zoukankan      html  css  js  c++  java
  • opencvinpainting图像修复

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

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

    #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;
    }

      

  • 相关阅读:
    1016: 写出来吧
    从硬件工程师转到纯软件开发,回顾那些岁月
    用大白话聊聊JavaSE -- 自定义注解入门
    数组中的一些常用方法总结
    js中的隐式转换
    开源OSS.Social微信项目进阶介绍
    .Net开源oss项目进度更新(含小程序接口)
    windows下部署免费ssl证书(letsencrypt)
    完成OSS.Http底层HttpClient重构封装 支持标准库
    谈javascript变量声明
  • 原文地址:https://www.cnblogs.com/liming19680104/p/15681465.html
Copyright © 2011-2022 走看看