【OpenCV归纳】5 图像处理


一、综述

本节我们将来探讨关于图像处理方面的诸多技术和应用。在学完了第一个常用的工具包之后,学习这一节将更加轻松。废话不多说,切入正题。

二、平滑处理和图像形态学

1、滤波器

"平滑处理“或者也称为”模糊处理“,英文名为blurring。对于平滑处理,我们先来介绍一个重要的函数,所有的操作都由这个函数来实现。

void cvSmooth

{

   const CvArr* src,

   CvArr* dst,

   intsmoothtype=CV_GAUSSIAN,

   int param1 = 3,

   int param2 = 0,

   double param3 = 0,

   double param4 = 0

};

如你所见,src和dst都是平滑处理的输入和输出图像。smoothtype共有5种类型,包括:CV_BLUR,CV_BLUR_NO_SCALE,CV_MEDIAN_CV_GAUSSIAN,CV_BILATERAL。下面我们挑几个介绍。

中值滤波器(CV_MEDIAN):它是一种非线性数字滤波器,经常用于去除图像或者其他信号中的杂讯。中值滤波是图像处理中的一个常用步骤,它对于斑点噪声(speckle noise)和椒盐噪音(salt-and-pepper
noise)来说尤其有用,以后我们将会介绍着两种噪声。

高斯滤波(CV_GAUSSIAN):用卷积核与输入图像的每个点进行卷积,将最终计算结果之和作为输出图像的像素值。对于高斯模糊,前2个参数代表滤波器窗口的宽度和高度可选择第三个参数来代表高斯卷积核的sigma值(其是最大宽度的四分之一)。高斯函数是单值函数,另外其宽度决定了平滑程度。

双边滤波(CV_BILATERAL):双边滤波的最大优点便是其可以做到边缘保存。进行高斯滤波的通常原因是真实图像在空间内的像素是缓慢变化的,因此临近点的像素变化不会很明显。但是随机的两个点就可能形成很大的像素差,这就是说空间上噪声点不是相互联系的。但是这种方法在接近边缘处就无效了。因此,高斯滤波会磨破边缘,而双边滤波器能够提供一种不会将边缘的平滑掉的方法,不过因此也需要更多的时间。至于应用上,这种滤波的效果大体上讲便是使画面更像一幅水彩画,也可以用于图像分割。

 

2、膨胀和腐蚀

膨胀是将一些图像,即为下列示例中的A部分和核B部分进行卷积。核可以是任意大小或形状,它拥有一个单独定义的参考点(anchor point)。而腐蚀是膨胀的反操作。在OpenCV中,我们用void
cvErode(IplImage* src, IplImage* dst, IplConvKernel* B = NULL,int iterations = 1);

和void cvDilate(IplImage* src, IplImage* dst, IplConvKernel* B = NULL,int iterations = 1);。

 

3、自定义核

通过cvCreateStrcturingElementEx函数我们可以创建自定义的IplConvKernel核。IplConvKernel的形状取值:CV_SHAPE_RECT,CV_SHAPE_CROSS,
CV_SHAPE_ELLIPSE, CV_SHAPE_CUSTOM。

 

4、形态学

下面我们再来介绍一个新的函数。

voidcvMorphologyEx(const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel*element, int operation, int iterations = 1)。该函数新加了2个参数,一个是temp数组一个是operation,后者用来指定形态学的操作方法。主要有:CV_MOP_OPEN,
CV_MOP_CLOSE, CV_MOP_GRADIENT, CV_MOP_TOPHAT,CV_MOP_BLASKHAT。

 

5、开运算和闭运算

在开运算的情况下,我们首先将其腐蚀然后膨胀。开运算通常可以用来统计二值图像中的区域数。在闭运算的情况下,我们首先将其膨胀然后腐蚀。闭运算消除了低于其邻近点的孤立点,而开运算则消除了高于其邻近点的孤立点。

 

6、形态学梯度

形态学梯度用来描述图像亮度变化的剧烈程度。以下是其的公式:gradient( src) = dilate (src )- erode (src)

 

7、礼帽和黑帽

TopHat (src) =src – open (src)

BlackHat (src) =close (src) – src

 

三、漫水填充

1.漫水填充的介绍

漫水填充的英文名是Flood Fill,它用来标记或者分离图像的一部分以便对其进行进一步的处理或分析。

 

2.函数分析

voidcvFloodFill(IplImage* img, CvPoint seedPoint, CvScalar newVal, CvScalar loDiff= cvScalarAll(0), CvScalar upDiff = cvScalarAll(0),CvConnectedComp*
comp =NULL, int flaags = 4, CvArr* mask = NULL); newVal是像素点被染色的值,如果一个像素点的值不低于被染色的相邻点减去loDiff且不高于其加上upDiff,那么这个像素点就会被染色。如果flags参数包含CV_FLOODFILL_FIXED_RANGE,这时每个像素点都将与种子点而不是相邻点比较。mask参数所代表的掩码既可以作为cvFloodFill()函数的输入值,也可以作为输出值。如果其非空,那么它必须是一个单通道、8位、像素宽度和高度均比原图像大两个像素的图像。

 

四、尺寸及图像金字塔

1.尺寸的调整

我们常用cvResize()函数来放大或缩小图像。该函数可以将原图像精确转换为目标图像的尺寸。cvResize()中有3种插值方式:CV_INTER_NN,
CV_INTER_LINEAR,CV_INTER_AREA,CV_INTER_CUBIC。

 

2.图像金字塔

图像金字塔是一个图像集合,集合中的所有图像都源于同一个原始图像,而且是通过对原始图像连续采样获得,直到达到某个终止条件才停止采样。我们常用的有高斯金字塔和拉普拉斯金字塔,分别为向下采样图像和从底层向上采样重建一个图像。

 

最常用的用途便是用金字塔来进行图像分割,先建立一个图像金字塔,然后建立起父与子的关系,通过这种方式,快速初始分割可以先在金字塔高层的低分辨率图像上完成,然后逐层对分割加以优化。OpenCV中用一下函数来进行此算法。

voidcvPyrSegmentation( IplImage* src, IplImage* dst, CvMemStorage* storage, CvSeq**comp, int level, double threshold1, double threshold2);关于src和dst,特别需要注意的一点是,由于图像金字塔各层的长和宽都必须是整数,所以要求起始图像的长和宽都能被2整除,并且能被2整除的次数不能少于金字塔的总层数。例如,对于5曾的金字塔,长度为48是满足要求的,因为48=2*2*2*2*3。

 

CvMemStorage*storage = cvCreateMemStorage()可以用来分配存储区域。

 

五、阈值化

1.介绍

阈值化的基本思想是将给定的一个数组,根据数组中的每个元素的值是否低于或高于阈值而进行的相关处理。

 

2、具体函数

doublecvThreshold(CvArr* src, CvArr* dst, double threshold, double max_value, intthreshold_type);其中的阈值的类型为:CV_THRESH_BINARY,
CV_THRESH_BINARY_INV, CV_THRESH_TRUNC,CV_THRESH_TOZERO_INV, CV_THRESH_TOZERO。

 

3.阈值化

最好不要对8位数组进行加法运算,因为在较高的位可能会溢出。不过可以使用加权加法算法(cvAddWeighted())对三个通道求和。cvThreshold()函数只能处理8位或浮点灰度图像。目标图像必须与源图像的类型是一致,或者为8位图像。事实上,cvThreshold()还允许源图像和目标图像是同一图像。

 

4.自适应阈值

针对有很强照明或反射梯度的图像,需要根据梯度进行阈值化时,自适应阈值技术非常有用。这种方法由以下函数实现:

void cvAdaptiveThreshold(CvArr* src, CvArr* dst, double max_val, intadaptive_method = CV_ADAPTIVE_THRESH_MEAN_C, int threshold_type
=CV_THRESH_BINARY, int block_size =3, double param1 = 5);

时间: 2025-01-26 16:22:36

【OpenCV归纳】5 图像处理的相关文章

【OpenCV归纳】3 在实例中学习简单函数以及数据读写

 实例一 int main() {  IplImage*  img = cvLoadImage("6085.jpg", 1);  IplImage* red = cvCreateImage(cvGetSize(img), img->depth, 1);  IplImage* green = cvCreateImage(cvGetSize(img), img->depth, 1);  IplImage* blue = cvCreateImage(cvGetSize(img

【OpenCV归纳】4 关于HighGUI

 通过HighGUI(high-level graphical user interface)可以实现打开窗口.显示图像.读出和写入图像文件,处理鼠标.光标.键盘事件.而HighGUI主要分成"视频输入/输出"."图像输入/输出"和"GUI工具",分别在cacap*.grfmt*和window*源文件中实现. int cvNamedWindow  ( const char* name,    int flags=CV_WINDOW_AUTOS

【OpenCV归纳】2 读写视频

 除了读入图片之外,读写视频也足够简单易学,下面来看看如何读写视频吧. 播放硬盘中的视频: #include "highgui.h" int main(int argc,char** argv) { cvNamedWindow("Test2",CV_WINDOW_AUTOSIZE); CvCapture* capture=cvCreateFileCapture(argv[1]); IplImage* frame; while(1) { frame=cvQuery

【OpenCV归纳】1 体验OpenCV

#include "highgui.h" int main(int argc,char** argv) { IplImage* img=cvLoadImage(argv[1]); cvNamedWindow("Test1",CV_WINDOW_AUTOSIZE); cvShowImage("Test1",img); cvWaitKey(0); cvReleaseImage(&img); cvDestoryWindow("Test

《OpenCV图像处理》——导读

前言 OpenCV,可以说是使用最广泛的计算机视觉库,它包括几百个易用的图像成像和视觉函数,既可用于学术研究,也可用于工业领域.随着摄像机越来越便宜和对影像学特征需求的增长,无论是对于台式机还是移动平台,OpenCV的应用范围都有了显著增长. 本书结合示例讲述OpenCV的主要图像处理算法.OpenCV方面的其他书籍试图说明其基础理论,或提供接近完整的大型应用程序示例,而本书则针对这样的读者而编写:他们想要尽量快速地得到一个易于理解的工作示例,并可能在此基础上开发一些附加功能. 本书以一个介绍性

OpenCV Mat —— 基本的图像容器

OpenCV Mat -- 基本的图像容器 目标 现实中我们有很多种方法来获取数字图像:数字摄像头.扫描仪.计算机断层扫描以及核磁共振生成图像等等.对我们人类来说这些设备生成的结果我们称之为图像.而我们从这些设备获取的图像最终是以组成点阵的数值来表示的. 就好像是一张车的图片中就是包含了点阵强度值的矩阵.我们可以根据需要来获取或者存储点阵,但最终所有计算机中的图片就剩下点阵以及描述点阵的信息.OpenCV 是一个计算机视觉库,主要用来处理和操作这类图像信息.因此你首先需要熟悉的是 OpenCV

java-previewcallback方法中的byte[]数据怎么转成opencv里的IplImage型?

问题描述 previewcallback方法中的byte[]数据怎么转成opencv里的IplImage型? previewcallback方法中的byte[]数据怎么转成opencv里的IplImage型?转成Mat类型也可以.从C++转Java,目前用ndk编程,想用C++和opencv做一些图像处理的东西,但是数据不知道该怎么转换,希望有高手指点. 解决方案 http://blog.sina.com.cn/s/blog_4a8e595e0100z2wt.html

<font color="red">[置顶]</font>

Profile Introduction to Blog 您能看到这篇博客导读是我的荣幸,本博客会持续更新,感谢您的支持,欢迎您的关注与留言.博客有多个专栏,分别是关于 Windows App开发 . UWP(通用Windows平台)开发 . SICP习题解 和 Scheme语言学习 . 算法解析 与 LeetCode等题解 . Android应用开发 ,而最近会添加的文章将主要是算法和Android,不过其它内容也会继续完善. About the Author 独立 Windows App 和

图像处理-用opencv, 帧差法进行室内人数识别,遇到光照问题,以及人多时无法分开识别 人

问题描述 用opencv, 帧差法进行室内人数识别,遇到光照问题,以及人多时无法分开识别 人 a) 光照问题:当人从靠近墙一侧走进出教室时,人影会影响图像处理的结果,从而导致所找到的连通域面积变大,包含了人和人影两部分,使质心向墙一侧偏移.通过观察,算法将此种情况视为不同的质心,导致结果有误差: b) 人走得近时算法无法分开识别:当教室内有大部分人集中走出教室的时候,由于同方向人一同走出,彼此之间空隙很小甚至彼此接触.在经过图像处理后的结果显示出,几个人的连通域是一个,而不是一个人一个连通域