OpenCV中導向濾波介紹與應用
點擊上方“小白學視覺”,選擇加"星標"或“置頂”
重磅干貨,第一時間送達
導向濾波介紹
導向濾波是使用導向圖像作為濾波內(nèi)容圖像,在導向圖像上實現(xiàn)局部線性函數(shù)表達,實現(xiàn)各種不同的線性變換,輸出變形之后的導向濾波圖像。根據(jù)需要,導向圖像可以跟輸入圖像不同或者一致。假設(shè)I是導向圖像、p是輸入圖像、q是導向濾波輸出圖像,導向濾波是作為局部線性模型描述導向圖像I與輸出圖像q之間的關(guān)系。


導向濾波算法實現(xiàn)的一般步驟為:
讀取導向圖像I與輸入圖像P
輸入?yún)?shù) 與 其中 表示窗口半徑大小,單位是像素, 表示模糊程度
積分圖計算I的均值與方差、輸入圖像的均值以及I與P的乘積IP
計算線性相關(guān)因子a與b
a=(IP-meanImeanP)/(Var_I+ )
b=meanP-ameanI
計算a與b的均值
使用均值得到導向濾波結(jié)果Q=meana*I+meanb
導向濾波最常用四個功能是:
邊緣保留濾波
圖像去噪聲
圖像邊緣羽化
圖像增強(對比度)
OpenCV中導向濾波函數(shù)
由于導向濾波計算均值與方差可以通過積分圖查找快速得到,因此導向濾波的速度會很快,作為邊緣保留濾波它比雙線性濾波有明顯的速度優(yōu)勢,OpenCV中在擴展模塊ximgproc中實現(xiàn)了圖像的導向濾波函數(shù),相關(guān)API函數(shù)與參數(shù)解釋如下:
void cv::ximgproc::guidedFilter ? ?( ?
? ?InputArray guide,// 導向圖像
? ?InputArray src,// 輸入下
? ?OutputArray dst,//導向濾波輸出
? ?int radius,//窗口半徑大小
? ?double eps,// 模糊程度
? ?int dDepth = -1// 輸出圖像深度
)
eps值越大圖像模糊程度越大、半徑radius值越大圖像模糊程度越高。
代碼演示
通過代碼演示了導向濾波根據(jù)輸入的導向圖像不一樣分別實現(xiàn)了圖像濾波的邊緣保留、去噪聲、羽化、對比度提升功能。完整的演示代碼如下:
#include
#include
#include
using namespace cv;
using namespace cv::ximgproc;
using namespace std;
void guide_demo(Mat &guide, Mat &input, int r, double e);
void enhance_demo(Mat &guide, Mat &input, int r, double e);
int main(int argc, char** argv) {
? ?Mat src = imread("D:/vcprojects/images/guide.png");
? ?if (src.empty()) {
? ? ? ?printf("could not load image...\n");
? ? ? ?return -1;
? ?}
? ?namedWindow("input", CV_WINDOW_AUTOSIZE);
? ?imshow("input", src);
? ?namedWindow("output", CV_WINDOW_AUTOSIZE);
? ?int r = 2;
? ?double eps = 0.1;
? ?int type = 0;
? ?while (true) {
? ? ? ?char c = waitKey(50);
? ? ? ?printf("input digit : %d\n", c);
? ? ? ?if (c == 49) { // 邊緣保留
? ? ? ? ? ?type = 1;
? ? ? ?}
? ? ? ?else if (c == 50) {
? ? ? ? ? ?type = 2;
? ? ? ?}
? ? ? ?else if (c == 51) {
? ? ? ? ? ?type = 3;
? ? ? ?}
? ? ? ?else if (c == 52) { // 去噪
? ? ? ? ? ?type = 4;
? ? ? ?}
? ? ? ?else if (c == 53) { // 羽化
? ? ? ? ? ?type = 5;
? ? ? ?}
? ? ? ?else if (c == 54) { // 提升
? ? ? ? ? ?type = 6;
? ? ? ?}
? ? ? ?else if (c == 27) {
? ? ? ? ? ?break;
? ? ? ?}
? ? ? ?if (type == 0 || type == 1 || type == 2 || type == 3) {
? ? ? ? ? ?guide_demo(src, src, pow(r, type), eps*eps * pow(r, type));
? ? ? ?}
? ? ? ?else if(type == 4){
? ? ? ? ? ?Mat guide = imread("D:/vcprojects/images/gf_guide.png");
? ? ? ? ? ?Mat input = imread("D:/vcprojects/images/gf_noise.png");
? ? ? ? ? ?imshow("input", input);
? ? ? ? ? ?guide_demo(guide, input, 8, 0.02*0.02);
? ? ? ?}
? ? ? ?else if (type == 5) {
? ? ? ? ? ?Mat guide = imread("D:/vcprojects/images/twocat.png");
? ? ? ? ? ?Mat input = imread("D:/vcprojects/images/twocat_mask.png", IMREAD_GRAYSCALE);
? ? ? ? ? ?imshow("input", input);
? ? ? ? ? ?guide_demo(guide, input, 60, 10e-6);
? ? ? ?}
? ? ? ?else {
? ? ? ? ? ?Mat input = cv::imread("D:/vcprojects/images/demo.png");
? ? ? ? ? ?input.convertTo(input, CV_32F, 1.0 / 255.0);
? ? ? ? ? ?imshow("input", input);
? ? ? ? ? ?int r = 16;
? ? ? ? ? ?double eps = 0.1 * 0.1;
? ? ? ? ? ?enhance_demo(input, input, r, eps);
? ? ? ?}
? ?}
? ?waitKey(0);
? ?return 0;
}
void guide_demo(Mat &guide, Mat &input, int r, double e) {
? ?double eps = e * 255 * 255;
? ?Mat dst;
? ?guidedFilter(guide, input, dst, r, eps, -1);
? ?imshow("output", dst);
}
void enhance_demo(Mat &guide, Mat &input, int r, double e) {
? ?Mat dst;
? ?guidedFilter(guide, input, dst, r, e, -1);
? ?Mat result = (guide - dst) * 5 + dst;
? ?imshow("output", result);
}
運行截圖如下:
邊緣保留

去噪聲

邊緣羽化

對比度提升

交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學影像、GAN、算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

