安裝opencv時,在opencv的安裝路徑下,
sources\samples\cpp\ 路徑里面提供了好多經典的例子,很值得學習。
這次的例子是利用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 << "\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" "./inpaint [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 == 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>\n" << 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 算法修復效果圖