【第二部分 图像处理】第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

相关文章

修复已被利用的高危漏洞! macOS Sequoia 15.6.1发布

《修复已被利用的高危漏洞!macOSSequoia15.6.1发布》苹果公司于今日发布了macOSSequoia15.6.1更新,这是去年9月推出的macOSSequoia操作... MACOS Sequoia 15.6.1 正式发布!此次更新修复了一个已被黑客利用的严重安全漏洞,并解决了部分中文用户反馈的

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

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色彩空间详解