opencv学习笔记(十)-图像腐蚀与腐蚀

时间:2022-07-09 20:00:31

相关概念:

腐蚀:删除对象边界某些像素。

结构元素

设有两幅图象B,X。若X是被处理的对象,而B是用来处理X的,则称B为结构元素(structure element),又被形象地称做刷子。结构元素通常都是一些比较小的图象。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

腐蚀过程介绍:

对二值图腐蚀过程:

在图6.10中,左边是被处理的图象X(二值图象,我们针对的是黑点),中间是结构元素B,那个标有origin的点是中心点,即当前处理元素的位置。腐蚀的方法是,拿B的中心点和X上的点一个一个地对比,如果B上的所有点(指的是所有黑点)都在X的范围内(即X图上处理元素所在的位置以及它上,左两个点都是黑色),则该点保留,否则将该点去掉(变为白点);右边是腐蚀后的结果。可以看出,它仍在原来X的范围内,且比X包含的点要少,就像X被腐蚀掉了一层。
opencv学习笔记(十)-图像腐蚀与腐蚀

对灰度图像的腐蚀:

如下图,左边是要处理图像,中间是结构元素,右边是与对应每个像素的灰度值。

处理过程就是:与上面的B一样,中间是要处理的元素所在的位置,三个1所在的位置对应三个灰度值,然后将中间这个1对应的灰度值改成这三个最小的,如源图像第一个灰度值1,它上左都没有灰度值,所以最小就是它本身,所以输出也是1,再比如处理灰度值为22那个点的时候,上面是7左边是44,所以22应改为7。

opencv学习笔记(十)-图像腐蚀与腐蚀

腐蚀的作用

1,边缘检测。
2,噪声滤除。
3,形态骨架提取。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

腐蚀例程:

1:从灰度值层面介绍腐蚀


#include "cv.h"
#include "highgui.h"
#include "cxcore.h"

int main()
{
//创建源图像
IplImage* src = cvCreateImage(cvSize(11, 10), 8, 1);

//创建图像 用来保存输出后的图像
IplImage* dat = cvCreateImage(cvSize(11,10), 8, 1);

//图像清零
cvSetZero(dat);
cvSetZero(src);

//将源图像赋初值
int x, y;

//(1,6)-->(1,9)
//(2,6)-->(2,9)
//(3,6)-->(3,9)
for (y = 1; y < 4; y++)
{
for (x = 6; x < 10; x++)
{
cvSetReal2D(src, y, x, 255);
}
}

//(4,4)-->(4,7)
//(5,4)-->(4,7)
for (y = 4; y < 6; y++)
{
for (x = 4; x < 8; x++)
{
cvSetReal2D(src, y, x, 255);
}
}

//(6,1)-->(6,7)
for (x = 1; x < 8; x++)
{
cvSetReal2D(src, 6, x, 255);
}

//(7,1)-->(7,4)
//(8,1)-->(8,4)
for (y = 7; y < 9; y++)
{
for (x = 1; x < 5; x++)
{
cvSetReal2D(src, y, x, 255);
}
}

//输出源图像
printf("src is :\n");
for (y = 0; y < src->height; y++)
{
for (x = 0; x < src->width; x++)
{
float value = cvGetReal2D(src, y, x);

printf("%5d", (int)(value));
}
printf("\n");
}

//创建结构元素变量,并且对其取值
IplConvKernel* element = 0;

//结构元素的取值情况
int value[16] = {
0, 0, 0, 0,
0, 0, 1, 0,
0, 1, 1, 0,
0, 0, 0, 0
};

//声明结构元素的列数 行数 锚点坐标
int clos = 4, rows = 4, anchor_x = 2, anchor_y = 2;

element = cvCreateStructuringElementEx(clos, rows, anchor_x, anchor_y, CV_SHAPE_CUSTOM, value);

//使用自定义结构元素 对图像进行腐蚀
cvErode(src, dat, element, 1);

//输出腐蚀后的结果
printf("dat is: \n");
for (y = 0; y < dat->height; y++)
{
for (x = 0; x < dat->width; x++)
{
float value = cvGetReal2D(dat, y, x);
printf("%5d", (int)value);
}
printf("\n");
}

}

效果:
腐蚀前:

opencv学习笔记(十)-图像腐蚀与腐蚀

腐蚀后:

opencv学习笔记(十)-图像腐蚀与腐蚀


2,从图像层面介绍腐蚀:

#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main()
{
Mat srcImage = imread("楪析.jpg");
imshow("【原图】腐蚀操作", srcImage);

Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));

Mat dstImage;

erode(srcImage, dstImage, element);

imshow("【效果图】腐蚀操作", dstImage);

waitKey(0);
return 0;
}

腐蚀前:
opencv学习笔记(十)-图像腐蚀与腐蚀

腐蚀后:
opencv学习笔记(十)-图像腐蚀与腐蚀

图像膨胀

图像的膨胀就是图像腐蚀的相反操作,例如: 对灰度图的处理过程就是:与上面的B一样,中间是要处理的元素所在的位置,三个1所在的位置对应三个灰度值,然后将中间这个1对应的灰度值改成这三个最的,如第一个灰度值1,它上左都没有灰度值,所以最大就是它本身,所以输出也是1,再比如处理灰度值为22那个点的时候,上面是7左边是44,所以22应改为44。

例程:

#include "cv.h"
#include "highgui.h"
#include "cxcore.h"

void main11()
{
/*创建两个单通道图像*/
IplImage *src, *dst;

src = cvCreateImage(cvSize(10, 10), 8, 1);
dst = cvCreateImage(cvGetSize(src), 8, 1);

/*图像的取值*/
unsigned char data[100] = {
1, 2, 5, 1, 78, 68, 7, 3, 5, 6,
5, 66, 7, 6, 3, 44, 22, 44, 0, 2,
9, 77, 3, 5, 6, 2, 4, 57, 9, 4,
54, 27, 59, 23, 58, 13, 36, 31, 38, 57,
35, 26, 24, 24, 31, 54, 22, 48, 48, 49,
27, 14, 26, 33, 68, 87, 57, 61, 19, 72,
46, 58, 46, 64, 54, 43, 97, 92, 20, 53,
84, 35, 35, 75, 12, 57, 37, 57, 4, 48,
57, 14, 67, 97, 56, 33, 37, 46, 58, 59,
36, 57, 89, 65, 47, 75, 11, 27, 41, 54
};

for (int y = 0; y < src->height; y++)
{
unsigned char* imageData = (unsigned char *)(src->imageData + y*src->widthStep);
for (int x = 0; x < src->width; x++)
{
imageData[x] = data[y*src->width + x];
}
}

printf("src is \n");
for (int y = 0; y < src->height; y++)
{
for (int x = 0; x < src->width; x++)
{
float value = cvGetReal2D(src, x, y);
printf("%3d ", (int)(value));
}
printf("\n");
}
/*声明结构元素变量*/
IplConvKernel* element = 0;
int values[16] = {
0,0,0,0,
0,0,1,0,
0,1,1,0,
0,0,0,0
};

/*结构体元素参数*/
int clos = 4, rows = 4, anchor_x = 2, anchor_y = 2;

/*创建结构元素*/
element = cvCreateStructuringElementEx(clos, rows, anchor_x, anchor_y, CV_SHAPE_CUSTOM, values);
/*膨胀后的结果*/
cvDilate(src, dst, element, 1);


printf("dst is \n");
for (int y = 0; y < src->height; y++)
{
for (int x = 0; x < src->width; x++)
{
float value = cvGetReal2D(dst, x, y);
printf("%3d ", (int)(value));
}
printf("\n");
}
/*释放图像内存*/
src = NULL;
dst = NULL;
system("pause");
}

效果如图:
opencv学习笔记(十)-图像腐蚀与腐蚀