OpenCV学习2-----使用inpaint函数进行图像修复

安装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 算法修复效果图

时间: 2024-10-10 20:08:12

OpenCV学习2-----使用inpaint函数进行图像修复的相关文章

opencv学习笔记(03)——遍历图像(迭代器法)

1 #include <opencv2\highgui\highgui.hpp> 2 #include <opencv2\imgproc\imgproc.hpp> 3 #include <opencv2\core\core.hpp> 4 5 void colorReduce(cv::Mat& img, int div=64); 6 7 8 int main() 9 { 10 cv::Mat img_orginal = cv::imread("F:\\i

opencv学习笔记(02)——遍历图像(指针法)

#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <iostream> void colorReduce(cv::Mat& image, int div=64) { int nr = image.rows; int nc = image.cols * image.

opencv学习笔记(01)——操作图像的像素

1 #include <opencv2\core\core.hpp> 2 #include <opencv2\highgui\highgui.hpp> 3 #include <opencv2\imgproc\imgproc.hpp> 4 #include <iostream> 5 6 7 void salt(cv::Mat& image, int n) 8 { 9 10 for(int k=0; k<n; k++) 11 { 12 13 int

opencv学习笔记之cvSobel 函数解析

首先,我们来开一下计算机是如何检测边缘的.以灰度图像为例,它的理论基础是这样的,如果出现一个边缘,那么图像的灰度就会有一定的变化,为了方便假设由黑渐变为白代表一个边界,那么对其灰度分析,在边缘的灰度函数就是一个一次函数y=kx,对其求一阶导数就是其斜率k,就是说边缘的一阶导数是一个常数,而由于非边缘的一阶导数为零,这样通过求一阶导数就能初步判断图像的边缘了.通常是X方向和Y方向的导数,也就是梯度.理论上计算机就是通过这种方式来获得图像的边缘. 但是,具体应用到图像中你会发现这个导数是求不了的,因

OPENCV学习笔记11_编写高效的图像扫描循环

When you write an image-processing function, efficiency is often a concern(涉及). When you design your function, you will frequently need to check the computational efficiency of your code in order to detect(发现) any bottleneck(瓶颈) in your processing th

【opencv学习笔记1】5种图像滤波辨析:方框、均值、高斯、中值、双边

图像滤波 什么是图像滤波 图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性. 图像滤波的目的 a.消除图像中混入的噪声 b.为图像识别抽取出图像特征 图像滤波的要求 a.不能损坏图像轮廓及边缘 b.图像视觉效果应当更好 滤波器的定义 滤波器,顾名思义,是对波进行过滤的器件.(摘自网络) 以上的定义是针对物理器件的,但对于图像滤波而言显然也是适用的. 大家都用过放大镜,这里就以此举一个例

OpenCV(C++接口)学习笔记2-像素级的图像操作

1.通过成员函数at(int y, int x)访问 这种方法需要知道像素保存的格式. (1) 这是为模板类型的函数,因为一个函数的返回类型只有在运行时才会知道. (2)这个函数返回的是一个向量即Vector,故有下标的操作. image.at<uchar>(j,i)= 255; 在单通道图像中,采用以上语句可以获取图像(i,j)处的灰度值(注:先行后列,一般用j表示行(rows),i表示列(cols)).如果是灰度图像的话,只需要更改一个数据就可以了.如果是rgb图像的话,就要用"

opencv2函数学习之erode、dilate:图像腐蚀和膨胀

图像腐蚀和图像膨胀是图像中两种最基本形态学操作. void erode( const Mat& src, Mat& dst, const Mat& element,Point anchor=Point(-1,-1), int iterations=1,int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() ); void dilate( const Ma

OpenCV学习之六: 使用方向梯度直方图估计图像旋转角度

在备份ltedecoder程序时,需要把此目录拷由到bak目录下,但decoder目录下有个大文件,不需要备份,还有日志问题,也不需要备份,如何实现呢?? 方法: cd /source-dir find . -name .snapshot -prune -o -print0 | cpio -pmd0 /dest-dir 解释: This command copies the contents of /source-dir to /dest-dir, but omits files and dir