opencv-inpainting图像修复

图像修复技术的原理是什么呢?

简而言之,就是利用那些已经被破坏的区域的边缘, 即边缘的颜色和结构,根据这些图像留下的信息去推断被破坏的信息区的信息内容,然后对破坏区进行填补 ,以达到图像修补的目的

#include<opencv2/opencv.hpp>
#include<iostream>

int main(int argc, char** argv) {

    cv::Mat imageSource = cv::imread("D:/bb/tu/9.png");
    imshow("原图", imageSource);
    cv::Mat imageGray;
    cv::cvtColor(imageSource, imageGray, cv::COLOR_RGB2GRAY, 0);
    //注意:不能用cv::COLOR_BGR2BGRA 替换cv::COLOR_RGB2GRAY,否则inpaint报错,我也不知原因,知道的请告知 13116140007
   
    cv::Mat imageMask = cv::Mat(imageSource.size(), CV_8UC1, cv::Scalar::all(0));
    cv::threshold(imageGray, imageMask, 245, 255, cv::THRESH_BINARY);
    cv::Mat Kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    cv::dilate(imageMask, imageMask, Kernel);//对Mask膨胀处理,增加Mask面积

    cv::Mat dst;
    cv::inpaint(imageSource, imageMask, dst, 5, cv::INPAINT_TELEA);
    /*
   第一个参数src,输入的单通道或三通道图像
   第二个参数inpaintMask,图像的掩码,单通道图像,大小跟原图像一致,inpaintMask图像上除了需要修复的部分之外其他部分的像素值全部为0
   第三个参数dst,输出的经过修复的图像;
   第四个参数inpaintRadius,修复算法取的邻域半径,用于计算当前像素点的差值
   第五个参数flags,修复算法,有两种:INPAINT_NS 和INPAINT_TELEA
   */

    imshow("Mask", imageMask);
    imshow("修复后", dst);

    cv::waitKey(0);
    return 0;
}

上面就是修复效果,感觉很不错吧!不过仔细一看,感觉跟原图还是发生了一些差异,比如图中剑圣头上的那颗亮点,颜色发生了变化。这个就是修复后的副作用!毕竟作出了修复,付点代价还是要的。受损是由于图像全区域做阈值处理获得的掩码,图像上部分区域也被当做掩码对待,导致部分图像受损 

上面提到其他无辜的区域会受损,这个问题能解决一下吗?可以的,那就得自己定义一块需要修复的区域,不需要修复的区域我们不动它就是了【就是修改mask】

#include<opencv2/opencv.hpp>
#include<iostream>

cv::Point ptL, ptR; //鼠标画出矩形框的起点和终点
cv::Mat imageSource, imageSourceCopy;
cv::Mat ROI; //原图需要修复区域的ROI

void OnMouse(int event, int x, int y, int flag, void* param) {
    
    if (event == cv::EVENT_LBUTTONDOWN)
    {
        ptL = cv::Point(x, y);
        ptR = cv::Point(x, y);
    }
    if (flag == cv::EVENT_FLAG_LBUTTON)
    {
        ptR = cv::Point(x, y);
        imageSourceCopy = imageSource.clone();
        cv::rectangle(imageSourceCopy, ptL, ptR, cv::Scalar(255, 0, 0));
        imshow("原图", imageSourceCopy);
    }
    if (event == cv::EVENT_LBUTTONUP)
    {
        if (ptL != ptR)
        {
            ROI = imageSource(cv::Rect(ptL, ptR));
            imshow("ROI", ROI);
            
        }
    }
    //单击鼠标右键开始图像修复
    if (event == cv::EVENT_RBUTTONDOWN)
    {
        imageSourceCopy = ROI.clone();
        cv::Mat Gray;
        cvtColor(ROI, Gray, cv::COLOR_RGB2GRAY); //转换为灰度图
        cv::Mat imageMask = cv::Mat(ROI.size(), CV_8UC1, cv::Scalar::all(0));
        
        //通过阈值处理生成Mask
        threshold(Gray, imageMask, 245, 255, cv::THRESH_BINARY);
        cv::Mat Kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
        dilate(imageMask, imageMask, Kernel);  //对Mask膨胀处理
        inpaint(ROI, imageMask, ROI, 9, cv::INPAINT_TELEA);  //图像修复

                
        imshow("修复后", imageSource);
    }

}


int main(int argc, char** argv) {

    imageSource = cv::imread("D:/bb/tu/9.png");
    imshow("原图", imageSource);
    cv::setMouseCallback("原图", OnMouse);
    
    
    cv::waitKey(0);
    return 0;
}

 

  

 

 

posted @ 2021-12-13 07:19  天子骄龙  阅读(235)  评论(0编辑  收藏  举报