opencv学习笔记七十一:图像修复

76 篇文章 525 订阅 ¥9.90 ¥99.00
本文介绍了如何利用OpenCV的inpaint()函数进行图像修复,通过分析图像边缘和结构信息,推断并填补损坏区域,以恢复图片原貌。修复过程中,调整修复半径和选择合适的修复算法至关重要,以减少修复后的细节差异。通过设置ROI区域,可以更精确地修复目标部分,提高修复质量。
摘要由CSDN通过智能技术生成

当我们的照片有划痕或遭到人为的涂鸦(比如马赛克)时, 如果我们想让这些遭到破坏的图片尽可能恢复到原样,Opencv能帮我们做到吗?答案是肯定的。

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

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

OpenCV中就是利用inpaint()这个函数来实现修复功能的。

void inpaint( InputArray src, InputArray inpaintMask,
                           OutputArray dst, double inpaintRadius, int flags );
  • 第一个参数src,输入的单通道或三通道图像;

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

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

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

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

#include<opencv2\opencv.hpp>
using namespace cv;
int main()
{
    imshow("原图", imageSource);
    Mat imageGray;

    //转换为灰度图
    cvtColor(imageSource, imageGray, CV_RGB2GRAY, 0);
    imshow("gray", imageGray);

    //通过阈值处理生成Mask
    Mat imageMask = Mat(imageSource.size(), CV_8UC1, Scalar::all(0));
    imshow("imageMask", imageMask);
    threshold(imageGray, imageMask, 240, 255, THRESH_BINARY);

    //对Mask膨胀处理,增加Mask面积
    Mat Kernel = getStructuringElement(MORPH_RECT, Size(3, 3));   
    dilate(imageMask, imageMask, Kernel);

    //图像修复
    inpaint(imageSource, imageMask, imageSource, 5, INPAINT_TELEA);
    imshow("Mask", imageMask);
    imshow("修复后", imageSource);
    waitKey();
}

下面是修复效果,效果看上去很不错,但仔细一看 ,还是有些细节跟原图发生了差异,比如刀和头上那个亮点,这是因为生成掩模的时候这些区域的亮度和白色的叉痕亮度相近,所以也成为了被修复的的对象。

想要消除这些瑕疵,可设置ROI区域,只对ROI区域的图像形成掩模和修复,其它区域不动。

//图像修复
#include<opencv2\opencv.hpp>
using namespace cv;
void callback(int event, int x, int y, int flags, void* userdata);
Point ptL, ptR;
Mat src, srcCopy,ROI,gray;
int main()
{
	src = imread("6.jpg");
	if (src.empty()) 
	{
		printf("could not load image!");
		return -1;
	}
	namedWindow("input");
	imshow("input", src);
	
	setMouseCallback("input", callback);
	waitKey();
}
void callback(int event, int x, int y, int flags, void* userdata)
{
	if (event == CV_EVENT_LBUTTONDOWN)
	{
		 ptL = Point(x, y);
		 ptR = Point(x, y);
	}
	if (flags == CV_EVENT_FLAG_LBUTTON)
	{
		ptR = Point(x, y);
		srcCopy = src.clone();
		rectangle(srcCopy, ptL, ptR, Scalar(255, 0, 0),2);
		imshow("srcCopy", srcCopy);
	}
	if (event == CV_EVENT_LBUTTONUP)
	{
		if (ptL!= ptR)
		{
			ROI = src(Rect(ptL, ptR));
			imshow("ROI", ROI);
		}
	}
	if (event == CV_EVENT_RBUTTONDOWN)
	{
                //灰度化
		cvtColor(ROI, gray, CV_BGR2GRAY);

                //通过阈值处理生成Mask
		Mat imageMask = Mat(ROI.size(), CV_8UC1, Scalar::all(0));
		threshold(gray, imageMask, 240, 255, THRESH_BINARY);

                //对Mask膨胀处理,增加Mask面积
		Mat Kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
		dilate(imageMask, imageMask, Kernel);
		imshow("Mask", imageMask);

		//图像修复
		inpaint(ROI, imageMask, ROI, 5, INPAINT_TELEA);
		imshow("修复后", src);
	}
}

下面是修复效果,效果比上面好很多:

 

 参考文献:https://www.cnblogs.com/skyfsm/p/6888213.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东城青年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值