【第二部分 图像处理】第4章 Opencv图像处理高阶【3图像修复】

2024-08-30 13:32

本文主要是介绍【第二部分 图像处理】第4章 Opencv图像处理高阶【3图像修复】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.1图像修复概述

在实际应用中,我们的图像常常会被噪声腐蚀,这些噪声或是镜头上的灰尘或水滴,或是旧照片的划痕,或者是图像遭到人为的涂画(比如马赛克)或者图像的部分本身已经损坏。如果我们想让这些受到破坏的额图片尽可能恢复到原样,Opencv能帮我们做到吗?
OpenCV真的有这个妙手回春的功能!别以为图像修补的工作只能用PS或者美图秀秀那些软件去做,其实由程序员自己写代码去做更加高效!
图像修复技术的原理是什么呢?简而言之,就是利用那些已经被破坏的区域的边缘, 即边缘的颜色和结构,根据这些图像留下的信息去推断被破坏的信息区的信息内容,然后对破坏区进行填补 ,以达到图像修补的目的。

3.2图像修复API:inpaint()函数

 inpaint()函数讲解

c++: void inpaint(InputArray src, InputArray inpaintMask, OutputArray dst, double inpaintRadius, int flags)

【参数】
第一个参数,src,输入的单通道或三通道图像;
第二个参数,inpaintMask,图像的掩码,单通道图像,大小跟原图像一致,inpaintMask图像上除了需要修复的部分之外其他部分的像素值全部为0;
第三个参数,dst,输出的经过修复的图像;
第四个参数,inpaintRadius,修复算法取的邻域半径,用于计算当前像素点的差值;
第五个参数,flags ,修复算法,有两种:INPAINT_NS 和I NPAINT_TELEA;
 INPAINT_NS Navier-Stokes based method.
 INPAINT_TELEA Method by Alexandru Telea [Telea04].
 inpaint()函数源代码

/*【inpaint()源代码】***************************************************************** @Version:OpenCV 3.0.0(Opnencv2和Opnencv3差别不大,Linux和PC的对应版本源码完全一样,均在对应的安装目录下)  * @源码路径:…\opencv\sources\modules\photo\src\inpaint.cpp* @起始行数:810行   
********************************************************************************/
void cv::inpaint( InputArray _src, InputArray _mask, OutputArray _dst,
                  double inpaintRange, int flags )
{
    Mat src = _src.getMat(), mask = _mask.getMat();
    _dst.create( src.size(), src.type() );
    CvMat c_src = src, c_mask = mask, c_dst = _dst.getMat();
    cvInpaint( &c_src, &c_mask, &c_dst, inpaintRange, flags );
}
可以看出inpaint源码中调用的是cvInpaint()函数,其源代码如下。
/*【inpaint()源代码】***************************************************************** @Version:OpenCV 3.0.0(Opnencv2和Opnencv3差别不大,Linux和PC的对应版本源码完全一样,均在对应的安装目录下)  * @源码路径:…\opencv\sources\modules\photo\src\inpaint.cpp* @起始行数:727行   
********************************************************************************/
Void cvInpaint( const CvArr* _input_img, const CvArr* _inpaint_mask, CvArr* _output_img,double inpaintRange, int flags )
{cv::Ptr<CvMat> mask, band, f, t, out;cv::Ptr<CvPriorityQueueFloat> Heap, Out;cv::Ptr<IplConvKernel> el_cross, el_range;CvMat input_hdr, mask_hdr, output_hdr;CvMat* input_img, *inpaint_mask, *output_img;int range=cvRound(inpaintRange);int erows, ecols;input_img = cvGetMat( _input_img, &input_hdr );inpaint_mask = cvGetMat( _inpaint_mask, &mask_hdr );output_img = cvGetMat( _output_img, &output_hdr );if( !CV_ARE_SIZES_EQ(input_img,output_img) || !CV_ARE_SIZES_EQ(input_img,inpaint_mask))CV_Error( CV_StsUnmatchedSizes, "All the input and output images must have the same size" );if( (CV_MAT_TYPE(input_img->type) != CV_8UC1 &&CV_MAT_TYPE(input_img->type) != CV_8UC3) ||!CV_ARE_TYPES_EQ(input_img,output_img) )CV_Error( CV_StsUnsupportedFormat,"Only 8-bit 1-channel and 3-channel input/output images are supported" );if( CV_MAT_TYPE(inpaint_mask->type) != CV_8UC1 )CV_Error( CV_StsUnsupportedFormat, "The mask must be 8-bit 1-channel image" );range = MAX(range,1);range = MIN(range,100);ecols = input_img->cols + 2;erows = input_img->rows + 2;f.reset(cvCreateMat(erows, ecols, CV_8UC1));t.reset(cvCreateMat(erows, ecols, CV_32FC1));band.reset(cvCreateMat(erows, ecols, CV_8UC1));mask.reset(cvCreateMat(erows, ecols, CV_8UC1));el_cross.reset(cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_CROSS,NULL));cvCopy( input_img, output_img );cvSet(mask,cvScalar(KNOWN,0,0,0));COPY_MASK_BORDER1_C1(inpaint_mask,mask,uchar);SET_BORDER1_C1(mask,uchar,0);cvSet(f,cvScalar(KNOWN,0,0,0));cvSet(t,cvScalar(1.0e6f,0,0,0));cvDilate(mask,band,el_cross,1);   // image with narrow bandHeap=cv::makePtr<CvPriorityQueueFloat>();if (!Heap->Init(band))return;cvSub(band,mask,band,NULL);SET_BORDER1_C1(band,uchar,0);if (!Heap->Add(band))return;cvSet(f,cvScalar(BAND,0,0,0),band);cvSet(f,cvScalar(INSIDE,0,0,0),mask);cvSet(t,cvScalar(0,0,0,0),band);if( flags == cv::INPAINT_TELEA ){out.reset(cvCreateMat(erows, ecols, CV_8UC1));el_range.reset(cvCreateStructuringElementEx(2*range+1,2*range+1,range,range,CV_SHAPE_RECT,NULL));cvDilate(mask,out,el_range,1);cvSub(out,mask,out,NULL);Out=cv::makePtr<CvPriorityQueueFloat>();if (!Out->Init(out))return;if (!Out->Add(band))return;cvSub(out,band,out,NULL);SET_BORDER1_C1(out,uchar,0);icvCalcFMM(out,t,Out,true);icvTeleaInpaintFMM(mask,t,output_img,range,Heap);}else if (flags == cv::INPAINT_NS) {icvNSInpaintFMM(mask,t,output_img,range,Heap);} else {CV_Error( cv::Error::StsBadArg, "The flags argument must be one of CV_INPAINT_TELEA or CV_INPAINT_NS" );}
}

3.3图像修复实例

 全区域阈值处理+Mask膨胀处理
代码参看附件【demo1】。

这里写图片描述

图1

由于是图像全区域做阈值处理获得的掩码,图像上部分区域也被当做掩码对待,导致部分图像受损。
 鼠标框选区域+阈值处理+Mask膨胀处理
代码参看附件【demo2】。
这里写图片描述

图2

可以看到,选定区域之外的图像不受修复影响,没有额外的损伤。
 鼠标划定整个区域作为修复对象
这个方法选定一个矩形区域,把整个矩形区域作为要修复的对象,该方法适用于图像结构比较简单,特别是纯色图像,并且选定区域面积占比不大的情况,效果较好。
代码参看附件【demo3】。
这里写图片描述

图3

 图像修复综合实例
代码参看附件【demo4】。
这里写图片描述

图4

本章参考附件

点击进入

这篇关于【第二部分 图像处理】第4章 Opencv图像处理高阶【3图像修复】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120958

相关文章

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

qt5cored.dll报错怎么解决? 电脑qt5cored.dll文件丢失修复技巧

《qt5cored.dll报错怎么解决?电脑qt5cored.dll文件丢失修复技巧》在进行软件安装或运行程序时,有时会遇到由于找不到qt5core.dll,无法继续执行代码,这个问题可能是由于该文... 遇到qt5cored.dll文件错误时,可能会导致基于 Qt 开发的应用程序无法正常运行或启动。这种错

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性