安装opencv时,在opencv的安装路径下,
sourcessamplescpp 路径里面提供了好多经典的例子,很值得学习。
这次的例子是利用inpaint函数进行图像修复。
CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask, OutputArray dst, double inpaintRadius, int flags );
其中
InputArray src 表示要修复的图像,
InputArray inpaintMask表示修复模板,
OutputArray dst 表示修复后的图像,
double inpaintRadius 表示修复的半径,
int flags 表示修复使用的算法 。 opencv提供了两种选择 CV_INPAINT_TELEA 和 CV_INPAINT_NS。
感觉两种算法修复效果都还不错,但是都需要事先准备修复模板mask,也就是inpaintMask 这个参数。
例子里面用鼠标在图片上划线,划线的同时也更新了mask,而真正应用的时候需要事先设计好这个mask。
文末有最终效果图。
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/photo/photo.hpp" #include <iostream> using namespace cv; using namespace std; static void help() { cout << " Cool inpainging demo. Inpainting repairs damage to images by floodfilling the damage " << "with surrounding image areas. " "Using OpenCV version %s " << CV_VERSION << " " "Usage: " "./inpaint [image_name -- Default fruits.jpg] " << endl; cout << "Hot keys: " " ESC - quit the program " " r - restore the original image " " i or SPACE - run inpainting algorithm " " (before running it, paint something on the image) " << endl; } Mat img, inpaintMask; Point prevPt(-1, -1); static void onMouse(int event, int x, int y, int flags, void*) { if (event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON)) prevPt = Point(-1, -1); else if (event == CV_EVENT_LBUTTONDOWN) prevPt = Point(x, y); else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON)) { Point pt(x, y); if (prevPt.x < 0) prevPt = pt; line(inpaintMask, prevPt, pt, Scalar::all(255), 5, 8, 0);//mask line(img, prevPt, pt, Scalar::all(255), 5, 8, 0); prevPt = pt; imshow("image", img); } } int main(int argc, char** argv) { char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg"; Mat img0 = imread(filename, -1); if (img0.empty()) { cout << "Couldn't open the image " << filename << ". Usage: inpaint <image_name> " << endl; return 0; } help(); namedWindow("image", 1); img = img0.clone(); inpaintMask = Mat::zeros(img.size(), CV_8U);//mask imshow("image", img); setMouseCallback("image", onMouse, 0); 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; //inpaint(img, inpaintMask, inpainted, 3, CV_INPAINT_TELEA);//CV_INPAINT_NS inpaint(img, inpaintMask, inpainted, 3, CV_INPAINT_TELEA); imshow("inpainted image", inpainted); } } return 0; }
图1 原图
图2 CV_INPAINT_NS 算法修复效果图
图3 CV_INPAINT_TELEA 算法修复效果图