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

相关文章

基于WinForm+Halcon实现图像缩放与交互功能

《基于WinForm+Halcon实现图像缩放与交互功能》本文主要讲述在WinForm中结合Halcon实现图像缩放、平移及实时显示灰度值等交互功能,包括初始化窗口的不同方式,以及通过特定事件添加相应... 目录前言初始化窗口添加图像缩放功能添加图像平移功能添加实时显示灰度值功能示例代码总结最后前言本文将

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

opencv实现像素统计的示例代码

《opencv实现像素统计的示例代码》本文介绍了OpenCV中统计图像像素信息的常用方法和函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 统计像素值的基本信息2. 统计像素值的直方图3. 统计像素值的总和4. 统计非零像素的数量

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

opencv 滚动条

参数介绍:createTrackbar( trackbarname , "hello" , &alpha_slider ,alpha_max ,  on_trackbar )  ;在标签中显示的文字(提示滑动条的用途) TrackbarName创建的滑动条要放置窗体的名字 “hello”滑动条的取值范围从 0 到 alpha_max (最小值只能为 zero).滑动后的值存放在

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存