您的位置:首页 > 运维架构

opencv图像求差的绝对值cvAbsDiff和形态学开运算cvMorphologyEx

2015-07-03 10:24 495 查看
AbsDiff与cvMorphologyEx

我们先来学习图像求差的绝对值这个函数:AbsDiff,它的作用是:OpenCV 中计算两个数组差的绝对值的函数。

函数原型:

void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1:第一个原数组

src2:第二个原数组

dst:输出数组

原理是:dst(I)c = abs(src1(I)c - src2(I)c).

所有数组必须有相同的数据类型相同的大小(或ROI大小)

拓展一下:

AbsDiffS:计算数组元素与数量之间差的绝对值,注意与上面不同的是数量value。

void cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );

#define cvAbs(src, dst) cvAbsDiffS(src, dst, cvScalarAll(0))

src:原数组.

dst:输出数组

value:数量.

原理是:dst(I)c = abs(src(I)c - valuec).

所有数组必须有相同的数据类型相同的大小(或ROI大小)

然后,我们学习形态学转换开运算cvMorphologyEx这个函数。

void cvMorphologyEx(const CvArr* src, CvArr* dst, CvArr* tmp, IplConvKernel* element, int operation, int iterations = 1);

参数说明:

src:输入图像

dst:输出图像

tmp:临时图像,某些操作会用到。需要使用tmp时,它应与原图像有同样的大小

element:结构元素

operation:形态操作的类型,有以下几种可用的类型:

-CV_MOP_OPEN开运算不需要临时图像

-CV_MOP_CLOSE闭运算不需要临时图像

-CV_MOP_GRADIENT形态梯度需要临时图像

-CV_MOP_TOPHAT“礼帽”src = dst情况下需要

-CV_MOP_BLACKHAT”黑帽“src = dst情况下需要

开运算:是先腐蚀然后再膨胀:dst = open(src, element) = dilate(erode(src, element), element)。开运算通常可以用来统计二值图像中的区域属,如已将显微镜载玻片上观察到的细胞图像作了阈值化处理,可以使用开运算将相邻的细胞分离开来,然后再计算图像中的区域细胞数目。

闭运算:是先膨胀然后再腐蚀:dst
= close(src, element) = erode(dilate(src, element), element)。在大多数好的连通区域分析算法中,都会用到闭运算来除去噪声引起的区域。对于连通区域分析,通常采用腐蚀或闭运算来消除纯粹由噪声引起的部分,然后用开运算来连接邻近的区域。

形态学梯度:膨胀图像减去腐蚀图像:dst
= dilate(src, element) - erode(src, element)。形态学梯度操作能描述图像亮度变化的剧烈程度。当想突出亮度区域的外围时,通常可使用形态学梯度,这样可以把高亮的看成一个整体。因为从原区域的膨胀中减去了原区域的收缩,所以留下了完整的外围边缘。

礼帽操作:dst
= src - open(src, element)

黑帽操作:dst = close(src, element) - src

这两个操作分别用于分离比邻近的点亮或暗的一些斑块。

题目描述:

拍一张某场景的图片,然后相机不动,在此场景中心位置放一个杯子,再拍一张图片,将其载入电脑并转换为8位灰度图像

a、求其差的绝对值并显示结果,他应该是一个带有噪声的杯子的掩码,

b、对结果图像进行二值化操作,剔除噪声的同时并保留鼠标,超过阈值的像素应设为255

c、在图像上进行CV_MOP_OPEN操作,进一步清除噪声

代码:

#include <cv.h>

#include <highgui.h>

#include <iostream>

using namespace cv;

using namespace std;

//函数声明-->--->-->--->-->--->-->--->//

//<--<--<--<--<--<--<--<--<--函数声明//

int main()

{

const char * fileName1 = "D:\\VC98\\C++项目\\opencv\\cvMorphologyEx_1\\cvMorphologyEx_1\\cup.jpg";

const char * fileName2 = "D:\\VC98\\C++项目\\opencv\\cvMorphologyEx_1\\cvMorphologyEx_1\\cup1.jpg";

IplImage * src1 = cvLoadImage(fileName1, CV_LOAD_IMAGE_GRAYSCALE);

IplImage * src2 = cvLoadImage(fileName2, CV_LOAD_IMAGE_GRAYSCALE);

assert(src1);

assert(src2);

//IplImage * img = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1);

//assert(img);

//cvZero(img);

//cvSetReal2D(img, 49, 49, 255);

cvNamedWindow("原始图像1", 0);

cvNamedWindow("原始图像2", 0);

cvNamedWindow("题目_a", 0);

cvNamedWindow("题目_b", 0);

cvNamedWindow("题目_c", 0);

//cvNamedWindow("题目_d", 0);

/*char * imageName = "E:\\Testing\\Image\\ExerciseWindow.jpg";

cvSaveImage(imageName, img);*/

cvShowImage("原始图像1", src1);

cvShowImage("原始图像2", src2);

//---------------------------a:开始--------------------------------//

IplImage * diff12 = cvCloneImage(src1);

cvZero(diff12);

cvAbsDiff(src1, src2, diff12);

cvShowImage("题目_a", diff12);

cvSaveImage("result.jpg",diff12);

/*char * saveName = "E:\\Testing\\Image\\SavePath\\diff12.jpg";

cvSaveImage(saveName, diff12);*/

//---------------------------a:结束--------------------------------//

//---------------------------b:开始--------------------------------//

IplImage * cleandiff = cvCloneImage(diff12);

cvZero(cleandiff);

//针对有很强照明或反射梯度的图像,需要根据梯度进行阈值化时,自适应技术非常有用,看图5-24的处理结果对比很明显

cvThreshold(diff12, cleandiff, 64, 255, CV_THRESH_BINARY);

cvShowImage("题目_b", cleandiff);

cvSaveImage("result1.jpg",cleandiff);

/*saveName = "E:\\Testing\\Image\\SavePath\\image_open.jpg";

cvSaveImage(saveName, cleandiff);*/

//---------------------------b:结束--------------------------------//

//---------------------------c:开始--------------------------------//

IplImage * dirtydiff = cvCloneImage(cleandiff);

cvZero(dirtydiff);

IplConvKernel * kernel = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT);

cvMorphologyEx(cleandiff, dirtydiff, NULL, kernel, CV_MOP_OPEN,2);

cvShowImage("题目_c", dirtydiff);

cvSaveImage("result2.jpg",dirtydiff);

/*saveName = "E:\\Testing\\Image\\SavePath\\image_close.jpg";

cvSaveImage(saveName, dirtydiff);*/

//---------------------------c:结束--------------------------------//

cvWaitKey(0);

cvReleaseImage(&src1);

cvReleaseImage(&src2);

cvReleaseImage(&diff12);

cvReleaseImage(&cleandiff);

cvReleaseImage(&dirtydiff);

cvDestroyWindow("原始图像1");

cvDestroyWindow("原始图像2");

cvDestroyWindow("题目_a");

cvDestroyWindow("题目_b");

cvDestroyWindow("题目_c");

//cvDestroyWindow("题目_d");

return 0;

}

结果:

输入的两张图片:





题目_a:



题目_b:



题目_c:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: