opencv自带的非局部降噪算法:
CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float h = 3,
int templateWindowSize = 7, int searchWindowSize = 21);
h是过滤强度,templateWindowSize是分块大小,searchWindowSize是搜索区域大小。
应用实例
int main()
{
Mat I1 = imread("D:/im2.jpg",0);
Mat I2;
fastNlMeansDenoising(I1, I2, 21, 7, 21);
imshow("p1", I1);
imshow("p2", I2);
waitKey(0);
return 0;
}
运行效果:
简便写法的坑:
int main()
{
Mat I1 = imread("D:/im2.jpg",0);
printf("%p\n", I1.data);
imshow("p1", I1);
fastNlMeansDenoising(I1, I1, 21, 7, 21);
printf("%p\n", I1.data);
imshow("p2", I1);
waitKey(0);
return 0;
}
运行效果不变,但是I1会被更改(打印的2个I1.data的地址也相同),需要额外注意这一点。
在fastNlMeansDenoising函数中,首先把入参InputArray _src, OutputArray _dst都转换成Mat对象,代码如下:
Size src_size = _src.size();
Mat src = _src.getMat();
_dst.create(src_size, src.type());
Mat dst = _dst.getMat();
如果_src和_dst对应的实参是同一个Mat对象,那么src和dst也会是同一个地址。
因为create函数内部首先会进行判断,满足条件的就直接return了,不需要申请新空间。
if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
{
if( d == 2 && rows == _sizes[0] && cols == _sizes[1] )
return;
for( i = 0; i < d; i++ )
if( size[i] != _sizes[i] )
break;
if( i == d && (d > 1 || size[1] == 1))
return;
}