左侧为修复后的 右侧为源图像
源码:
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/photo.hpp"
#include <iostream>
using namespace cv;
using namespace std;
static void help(char** argv)
{
cout << "\nCool inpainging demo. Inpainting repairs damage to images by floodfilling the damage \n"
<< "with surrounding image areas.\n"
"Using OpenCV version %s\n" << CV_VERSION << "\n"
"Usage:\n" << argv[0] << " [image_name -- Default fruits.jpg]\n" << endl;
cout << "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\ti or SPACE - run inpainting algorithm\n"
"\t\t(before running it, paint something on the image)\n" << endl;
}
Mat img, inpaintMask;
Point prevPt(-1, -1);
static void onMouse(int event, int x, int y, int flags, void*)
{
if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))//非左键按下 左键抬起
prevPt = Point(-1, -1);//重置上一点
else if (event == EVENT_LBUTTONDOWN) //左键第一次按下
prevPt = Point(x, y);//上一点
else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))//左键按下 鼠标移动
{
Point pt(x, y);//当前点
if (prevPt.x < 0)
prevPt = pt;//上一点
line(inpaintMask, prevPt, pt, Scalar::all(255), 5, 8, 0);//绘制修复区域,非零像素
line(img, prevPt, pt, Scalar::all(255), 5, 8, 0);//在原图上绘制
prevPt = pt;//更新上一点
imshow("image", img);
}
}
int main(int argc, char** argv)
{
cv::CommandLineParser parser(argc, argv, "{@image|fruits.jpg|}");
help(argv);
//加载图像
string filename = samples::findFile(parser.get<string>("@image"));
Mat img0 = imread(filename, IMREAD_COLOR);
if (img0.empty())
{
cout << "Couldn't open the image " << filename << ". Usage: inpaint <image_name>\n" << endl;
return 0;
}
namedWindow("image", WINDOW_AUTOSIZE);
img = img0.clone();
inpaintMask = Mat::zeros(img.size(), CV_8U);//修复蒙版
imshow("image", img);
setMouseCallback("image", onMouse, NULL);//鼠标回调
for (;;)
{
char c = (char)waitKey();
if (c == 27)
break;
if (c == 'r')
{
inpaintMask = Scalar::all(0);
img0.copyTo(img);
imshow("image", img);
}
if (c == 'i' || c == ' ')
{
Mat inpainted;
/** @brief 使用区域邻域恢复图像中的选定区域。
@param src 输入 8 位、16 位无符号或 32 位浮点 1 通道或 8 位 3 通道图像。
@param inpaintMask 修复蒙版,8 位 1 通道图像。非零像素表示需要修复的区域。
@param dst 输出与 src 大小和类型相同的图像。
@param inpaintRadius 算法考虑的每个修复点的圆形邻域的半径。
@param 标记可能是 cv::INPAINT_NS 或 cv::INPAINT_TELEA 的修复方法
该函数从区域边界附近的像素重建所选图像区域。该功能可用于去除扫描照片上的灰尘和划痕,或去除静止图像或视频中不需要的物体。有关详细信息,请参阅 <http://en.wikipedia.org/wiki/Inpainting>。
@笔记
- 使用修复技术的示例可以在 opencv_source_code/samples/cpp/inpaint.cpp 找到
- (Python) 使用修复技术的示例可以在 opencv_source_code/samples/python/inpaint.py 找到
*/
inpaint(img, inpaintMask, inpainted, 3, INPAINT_TELEA);
imshow("inpainted image", inpainted);
}
}
return 0;
}