图像的修补技术由inpaint函数实现,它可以用来从扫描的照片中清除灰尘和划痕,或者从静态图像或视屏中去除不需要的物体。
函数原型C++:
void inpaint( InputArray src, InputArray inpaintMask, OutputArray dst,
double inpaintRadius, int flags )
1)InputArray类型的src,输入图像,填Mat类的对象即可,且需要8位单通道或者三通道图像;
2)InputArray类型的inpaintMask,修复掩膜,为8位的单通道图像。其中的非零像素表示需要修补的区域;
3)OutputArray类型的dst,函数调用后的运算结果存在这里,和源图片有一样的尺寸和类型;
4)double类型的inpaintRadius,需要修补的每个点的圆形领域,为修复算法的参考半径。
5)int类型的flags,修补方法的标识符,可以是:
INPAINT_NS: 基于Navier-Stokes方程的方法
INPATNT_TELEA: Alexandru Telea方法
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/photo/photo.hpp>
#include <iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "原始图"
#define WINDOW_NAME2 "修补后的效果图"
Mat srcImage1, inpaintMask;
Point previousPoint(-1, -1);
static void on_Mouse(int event, int x, int y, int flags, void*)
{
/*鼠标左键弹起消息*/
if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))
previousPoint = Point(-1, -1);
/*鼠标左键按下消息*/
else if (event == EVENT_LBUTTONDOWN)
previousPoint = Point(x, y);
/*鼠标按下并移动,进行绘制*/
else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
{
Point pt(x, y);
if (previousPoint.x < 0)
previousPoint = pt;
line(inpaintMask, previousPoint, pt, Scalar::all(255), 5, 8, 0);//画白线
line(srcImage1, previousPoint, pt, Scalar::all(255), 5, 8, 0);//画白线
previousPoint = pt;
imshow(WINDOW_NAME1, srcImage1);
}
}
int main()
{
Mat srcImage = imread("me.jpg", -1);
srcImage1 = srcImage.clone();
inpaintMask = Mat::zeros(srcImage1.size(), CV_8U);
imshow(WINDOW_NAME1, srcImage1);
/*设置鼠标回调消息*/
setMouseCallback( WINDOW_NAME1, on_Mouse, 0 );
while (1)
{
char c = (char)waitKey();
if (c == 27)
break;
/*恢复成原始图像*/
if (c == '2')
{
inpaintMask = Scalar::all(0); //0就是不需要修补的部分
srcImage.copyTo(srcImage1);
imshow(WINDOW_NAME1, srcImage1);
}
if (c == '1')
{
Mat inpaintedImage;
inpaint(srcImage1, inpaintMask, inpaintedImage, 3, INPAINT_TELEA);
imshow(WINDOW_NAME2, inpaintedImage);
}
}
return 0;
}
运行结果:
版权声明:本文为qq_27396861原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。