opencv 浅谈图像修复

一、话说图像修复

在实际应用中,我们的图像常常会被噪声腐蚀,这些噪声或是镜头上的灰尘或水滴,或是旧照片的划痕,或者是图像遭到人为的涂画(比如马赛克)或者图像的部分本身已经损坏。如果我们想让这些受到破坏的额图片尽可能恢复到原样,Opencv能帮我们做到吗?

OpenCV真的有这个妙手回春的功能!别以为图像修补的工作只能用PS或者美图秀秀那些软件去做,其实由程序员自己写代码去做更加高效!

图像修复技术的原理是什么呢?

简而言之,就是利用那些已经被破坏的区域的边缘, 即边缘的颜色和结构,根据这些图像留下的信息去推断被破坏的信息区的信息内容,然后对破坏区进行填补 ,以达到图像修补的目的。

OpenCV中实现的图像修复算法有两种。

  • 基于Navier-Stokes的修复方法

  • 基于图像梯度的快速匹配方法又称(Telea法)

对应的两个枚举类型分别如下:

  • CV_INPAINT_NS

  • CV_INPAINT_TELEA


二、API

void inpaint( InputArray src, InputArray inpaintMask, OutputArray dst, double inpaintRadius, int flags );

  • 第一个参数src,输入的单通道或三通道图像;

  • 第二个参数inpaintMask,图像的掩码,单通道图像,大小跟原图像一致,inpaintMask图像上除了需要修复的部分之外其他部分的像素值全部为0;

  • 第三个参数dst,输出的经过修复的图像;

  • 第四个参数inpaintRadius,修复算法取的邻域半径,用于计算当前像素点的差值;

  • 第五个参数flags,修复算法,有两种:INPAINT_NS 和I NPAINT_TELEA;

函数实现关键是图像掩码的确定,可以通过阈值筛选或者手工选定。

三、实验

废话不多说,直接上代码

int main()
{
	Mat src, dst,mask,temp;
	src = imread("D:\\cv_study\\Exercise\\inpaint\\g.jpg");
	temp = src.clone();
	rectangle(temp, Rect(500, 500, 100, 100), Scalar(0, 0, 255), 3, 8);
	inRange(temp, Scalar(0, 0, 250), Scalar(0, 0, 255), mask);
	inpaint(temp, mask, dst,3, CV_INPAINT_TELEA);		
 	waitKey();
    return 0;
}

opencv 浅谈图像修复_第1张图片opencv 浅谈图像修复_第2张图片opencv 浅谈图像修复_第3张图片opencv 浅谈图像修复_第4张图片

现在原图上画一个矩形,然后找到需要修复位置的掩膜,进而进行图像修复。可以看到,对于简单的图像损坏,修复的还是挺不错的。上面的图是网上随便下载的,可以看到左下角有图库网的logo,那么怎么将这个logo去掉呢?

int main()
{
	Mat src, dst,mask,temp;
	src = imread("D:\\cv_study\\Exercise\\inpaint\\g.jpg");
	inRange(src, Scalar(235, 235, 235), Scalar(255, 255, 255), mask);
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
	morphologyEx(mask, mask, MORPH_DILATE,element, Point(-1, -1), 3);
	inpaint(src, mask, dst, 5, CV_INPAINT_NS);
 	waitKey();
    return 0;
}

opencv 浅谈图像修复_第5张图片opencv 浅谈图像修复_第6张图片

opencv 浅谈图像修复_第7张图片

上面提取mask的方式和第一个有点不同,原因是logo周边的区域,所以这里对mask做形态学处理,使周边的区域也包含进来,从结果中看到,最终效果还不错。今天讲的比较简单,但是希望大家和我一样都有所收获


你可能感兴趣的:(opencv)