matlab函数imfilter和 opencv中filter2D函数的对应关系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/piaoxuezhong/article/details/80104697

在项目中遇到的matlab代码中的图像滤波函数,需要在opencv中去实现。关于怎么去转换,我主要参考的如下两篇 :

(1)https://blog.csdn.net/hust_sheng/article/details/79313503

(2)https://www.cnblogs.com/jsxyhelu/p/6597544.html

首先,关于matlab中imfilter函数的使用,主要涉及了两个概念:相关和卷积,实现方式有不同。下面简单附录一下:

函数名称:imfilter 
函数语法:g=imfilter(f,w,filtering_mode,boundary_options,size_optinos) 
函数功能:对任意类型数组或多维图像进行滤波 
参数介绍:f是输入图像,w为滤波模板,g为滤波结果;表1-1总结了其他参数的含义。 

这里写图片描述

opencv中对应的函数是filter2D,在第1篇参考里,讲述了关于一维情况下对应关系。

(一)一维情况下的滤波对应关系

因为我针对的是2维图像的滤波,所以暂时用不到一维,但是也附录一下,以备后用。

matlab:

kernel:[-1, 1, 0]
div_p_1 = imfilter(p(:, :, 1), [-1, 1, 0], 'corr', 0);
div_p_2 = imfilter(p(:, :, 2), [-1, 1, 0]', 'corr', 0)

Opencv:

float kernel_div[3] = {-1, 1, 0};
int   ddepth = -1;                  // 默认值,-1表示和原图像一样的深度
Point anchor_center(-1, -1);        // 十分关键!决定了滤波的边界处理形式!
Mat kerdiv_1 = Mat(1, 3, CV_32FC1, &kernel_div);    // 水平kernel
Mat kerdiv_2 = Mat(3, 1, CV_32FC1, &kernel_div);    // 垂直kernel
Mat div_p_1, div_p_2;
filter2D(p_channels.at(0), div_p_1, ddepth, kerdiv_1, anchor_center, 0, BORDER_CONSTANT);
filter2D(p_channels.at(1), div_p_2, ddepth, kerdiv_2, anchor_center, 0, BORDER_CONSTANT)

两者的结果一致,表明matlab的full或same模式对应于用opencv中的ancher调整。

matlab:

kernel:[-1, 1]

I_x = imfilter(I, [-1, 1], 'replicate');
I_y = imfilter(I, [-1, 1]', 'replicate')

Opencv:

int ddepth = -1;
Point anchor(0, 0);
float kernel_img[2] = {-1, 1};
Mat kerimg_1 = Mat(1, 2, CV_32FC1, &kernel_img);
Mat kerimg_2 = Mat(2, 1, CV_32FC1, &kernel_img);         
Mat I_x, I_y;
filter2D(images_graystyle_tmp[imgNo]+ktheta*div_p, I_x, ddepth, kerimg_1, anchor, 0, BORDER_REPLICATE);
filter2D(images_graystyle_tmp[imgNo]+ktheta*div_p, I_y, ddepth, kerimg_2, anchor, 0, BORDER_REPLICATE)

BORDER_REPLICATE 边缘扩充模式,filter2D和imfilter是一样的的,需要注意的是opencv的anchor是:Point anchor(0, 0)

(二)针对二维图像进行滤波操作

 首先,在matlab中进行测试,代码如下:

%测试比较matlab函数imfilter与opencv函数filter2D的区别
clc,clear all,close all;
img = im2double(imread('C:\image_fcq\C180806143231.jpg'));
kernel =[2.0,-1.0,3.0;2.0,-4.0,5.0];
rst = imfilter(img,kernel);

在opencv中正确的对应关系如下:

	string imgName="C://image_fcq//C180806143231.jpg"
        const int rows = 2, cols = 3;
	float RawData1[rows][cols] = { { 2.0,-1.0,3.0 },{ 2.0,-4.0,5.0 } };
	Mat RawDataMat1(2, 3, CV_32F, RawData1);
	Mat img = imread(imgName,0);
	img.convertTo(img, CV_32F);
	img = img / 255; //归一化处理
	Mat dst;
	filter2D(img, dst, img.depth(), RawDataMat1);
	WriteDataFloat("C://image//lv.txt", dst); //将滤波结果写到lv.txt中

结果:两者的滤波结果出了在边界有区别外,其他位置基本一致,能取得很好地对应关系,需要注意的是,在opencv中需要将图像进行归一化操作。

猜你喜欢

转载自blog.csdn.net/piaoxuezhong/article/details/80104697
今日推荐