2017-04-13 11:12:26 doudouqbj 阅读数 6269

图像轮廓提取


1 基于区域的方法

分割+提取

基于灰度、颜色、纹理等来进行分割,

分割方法:区域生长(计算简单、均匀区域效果好,但是人为确定种子点、容易空洞、噪声敏感)

                  分水岭变换(容易过分割)

                  分裂合并(复杂、计算量大,分裂容易破坏边界)

                   图论


2 基于边缘的方法

分为:基于边缘检测和基于边缘分组

基于边缘检测:边缘检测算子+去除杂点、冗余边缘、修复边缘(噪声敏感)(基于梯度的方法可以归纳到这里)

基于边缘分组:线逼近算法去除噪声+边缘点逐步组合合并成(噪声敏感)


3 基于活动轮廓的方法

方法:snake模型法和水平集法

原理:都是设定一个初始轮廓,不断迭代,直到内部外部能量函数和最小

缺点:初始轮廓敏感


4 基于视觉特性的方法

原理:定义函数模拟人类的视觉特性,构建仿生模型进行特征提取


2017-04-19 19:54:00 The_star_is_at 阅读数 8502

实验三   图像轮廓提取与边缘检测


一、实验目的:

理解并掌握对二值图像进行轮廓提取的相关算法(比如,掏空内部点法),以及用于图像边缘检测和提取的典型微分算子(梯度算子和拉普拉斯算子)。

二、实验环境:

计算机、Windows XP操作系统,Matlab7.0

二、实验内容:

1、根据掏空内部点算法,运用Matlab编程实现二值图像的轮廓提取。

%以下适用于黑色背景白色前景的二值图像轮廓提取(以二值图像circles为例)

BW=imread('circles.png');     %二值图像circlesuint80黑,255

subplot(1,2,1);  imshow(BW);  title('二值图像');

[M, N]=size(BW);     %M行,N

BW_Buffer=BW;

for i=2: M-1

for j=2: N-1

if (BW(i, j)==255 & BW(i-1, j)==255 & BW(i+1, j)==255 & BW(i, j-1)==255 & BW(i, j+1)==255 & BW(i-1, j-1)==255 & BW(i-1, j+1)==255 & BW(i+1, j-1)==255 & BW(i+1, j+1)==255)    %说明BW(i, j)是前景中的一个内部点

       BW_Buffer(i, j)=0;    %掏空该内部点,即将该内部点置成与背景相同灰度

end

end

end

subplot(1,2,2);  imshow(BW_Buffer);  title('提取轮廓');


%以下适用于白色背景黑色前景的二值图像轮廓提取(以二值图像source为例)

BW=imread('source.bmp');      %二值图像sourceuint80黑,255

subplot(1,2,1);  imshow(BW);  title('二值图像');

[M, N]=size(BW);   %M行,N

BW_Buffer=BW;

for i=2: M-1

for j=2: N-1

if (BW(i, j)==0 & BW(i-1, j)==0 & BW(i+1, j)==0 & BW(i, j-1)==0 & BW(i, j+1)==0 & BW(i-1, j-1)==0 & BW(i-1, j+1)==0 & BW(i+1, j-1)==0 & BW(i+1, j+1)==0)      %说明BW(i, j)是前景中的一个内部点

       BW_Buffer(i, j)=255;   %掏空该内部点,即将该内部点置成与背景相同灰度

end

end

end

subplot(1,2,2);  imshow(BW_Buffer);  title('提取轮廓');

注意:使用掏空内部点的方法来提取二值图像的轮廓时,不能直接在原始二值图像矩阵上判断一个点掏空一个点,否则对前面像素的掏空操作会影响到对后面像素的判断结果。

解决方法:创建原始二值图像矩阵的副本(即图像矩阵BW_Buffer),在原始二值图像矩阵上执行判断操作,即依次判断每个像素点是否为前景中的内部点,如果是,则在图像矩阵BW_Buffer上执行掏空内部点的操作。

2、以灰度图像ricecameraman为例,利用Matlab图像处理工具箱中的edge函数,分别使用Roberts 算子、Sobel算子、Prewitt 算子对其进行边缘检测。

(1)函数格式: BW = edge(I, 'method', thresh)

(2)格式说明:edge函数输入灰度图像矩阵I,输出二值图像矩阵BW;参数'method'用于指定所使用的边缘检测算子,可以是'roberts''sobel''prewitt''log''canny';参数thresh用于指定梯度门限值(也称梯度阈值),图像中梯度值大于等于门限值thresh的像素用白色(1)表示,说明这些地方对应边缘,梯度值小于门限值thresh的像素用黑色(0)表示(edge function will ignore all edges that are not stronger than thresh)。若不指定参数thresh,则edge函数会自动选择阈值。所以edge函数最终将原始灰度图像中的边缘和背景用二值图像的形式展现出来,以突出边缘的位置,达到边缘检测的目的。

(3)程序如下:

I=imread('rice.png');

subplot(2,2,1);  imshow(I);  title('原始图像');

[BW1,thresh1]=edge(I,'roberts');  %进行Roberts算子边缘检测并返回门限值

[BW2,thresh2]=edge(I,'sobel');    %进行Sobel算子边缘检测并返回门限值

[BW3,thresh3]=edge(I,'prewitt');  %进行Prewitt算子边缘检测并返回门限值

subplot(2,2,2);  imshow(BW1);  title('Roberts算子边缘检测结果');

subplot(2,2,3);  imshow(BW2);  title('Sobel算子边缘检测结果');

subplot(2,2,4);  imshow(BW3);  title('Prewitt算子边缘检测结果');

若向原始图像中加入随机噪声(比如高斯噪声),之后再对噪声图像分别运用Roberts 算子、Sobel算子、Prewitt 算子、Log算子(高斯-拉普拉斯算子)进行边缘检测,观察检测结果,试比较4种边缘检测算子的抗噪声干扰能力。

I=imread('rice.png');

subplot(2,3,1);  imshow(I);  title('原始图像');

G=imnoise(I, 'gaussian');  %向原始图像中加入高斯噪声

subplot(2,3,2);  imshow(G);  title('噪声图像');

BW1=edge(G, 'roberts');  %进行Roberts算子边缘检测

BW2=edge(G, 'sobel');    %进行Sobel算子边缘检测

BW3=edge(G, 'prewitt');  %进行Prewitt算子边缘检测

BW4=edge(G, 'log');      %进行Log算子边缘检测

subplot(2,3,3);  imshow(BW1);  title('Roberts算子边缘检测结果');

subplot(2,3,4);  imshow(BW2);  title('Sobel算子边缘检测结果');

subplot(2,3,5);  imshow(BW3);  title('Prewitt算子边缘检测结果');

subplot(2,3,6);  imshow(BW4);  title('Log算子边缘检测结果');

2014-12-03 10:32:45 u014568921 阅读数 1427

图像的轮廓提取在数字图像处理第三版(中文版 冈萨雷斯)第九章412页,讲得很清楚,在此就不赘述了。

将腐蚀和相减化作一步,上代码

BOOL CImageColorProcess::Contour(LPBYTE lpSrc, LPBYTE lpDst, LPBYTE lpDst_, int nSrcCount, int nW, int nH)
{
	this->OSTUThreshold(lpSrc, lpDst_, nSrcCount, nW, nH);//首先大律法二值化
	for (int i = 0; i < nH; i++)
	{
		for (int j = 0; j < nW; j++)
		{
			lpDst[i*nW + j] = 255;
		}
	}
	for (int i = 1; i < nH - 1; i++)
	{
		for (int j = 1; j < nW - 1; j++)
		{
			if (lpDst_[i*nW + j] == 0)
			{
				lpDst[i*nW + j] = 0;
				int nw = lpDst_[(i + 1)*nW + j - 1];
				int n = lpDst_[(i + 1)*nW + j];
				int ne = lpDst_[(i + 1)*nW + j + 1];
				int w = lpDst_[i*nW + j - 1];
				int e = lpDst_[i*nW + j + 1];
				int sw = lpDst_[(i - 1)*nW + j - 1];
				int s = lpDst_[(i - 1)*nW + j];
				int se = lpDst_[(i - 1)*nW + j + 1];
				if (nw + n + ne + e + sw + se + s + w == 0)
				{
					lpDst[i*nW + j] = 255;
				}
			}
		}
	}
	return true;
}

2017-10-02 18:09:34 cymy001 阅读数 542

本文内容参考《数字图像处理基础》Wilhelm Burger等著。
根据图像数组获得边缘检测信息,然后循着已检测到的边缘点找到轮廓线。

轮廓跟踪:从那些边缘强度较大的地方开始,沿着两个不同方向跟踪边缘点,直到这两条轨迹相遇并形成一条闭合的轮廓线。(灰度梯度弱——>边缘消失;交叉边缘——>歧义)

边缘图:通过“阈值运算”对一个“图像像素”是否属于边缘点做“二值判断”(这里需要被判断的“图像像素”是指由“各种边缘检测算子得到的边缘强度”,“阈值”可以是固定的,也可以说是自适应的),经过“阈值运算”的结果存为一张“二值的边缘图像”,即“边缘图”。
全局阈值化处理的后处理方法,如霍夫变换,能很好处理不完整的边缘图。

边缘锐化:

从原图像函数f(x)上减去其二阶导数f′′(x)的一部分,如下图:
这里写图片描述
二维函数f(x,y)的拉普拉斯算子

Δf(x,y)=2f2x(x,y)+2f2y(x,y)

由中心差分公式易得
HLx=2f2x(x,y)=(121),HLy=2f2y(x,y)=121

HL=HLx+HLy=010141010

接下来对原图像I,用HL算子滤波,然后再用I减去此滤波结果,即得锐化结果

I˘Iω(HLI)

拉普拉斯滤波器对噪声相当敏感,可以采用预平滑措施(如高斯平滑)减弱噪声的影响。

2014-06-06 14:42:32 C_Bright 阅读数 3256

OpenCV函数 cvFindContours提取轮廓

点击打开链接  点击打开链接 点击打开链接 点击打开链接

提取元素的轮廓及形状描述子

点击打开链接

提取轮廓的点坐标

轮廓提取后,它是用关键点组成的,下面提取出这些关键点。

1.先输出所有关键点的个数cout<<"elements"<<contour->total<<endl;

2.for(int i=0;i<contour->total;++i)

   {

          CvPoint* p = CV_GET_SEQ_ELEM(CvPoint,contour,i);
         cout<<p->x<<","<<p-y<<endl;


   }

求轮廓的面积和周长

for(contour;contour!=NULL;contour=contour->h_next)

{

       double s=cvContourArea(contour,CV_WHOLE_SEQ);

       double l=cvArcLength(contour,CV_WHOLE_SEQ,-1);//后面参数0表示轮廓不闭合,正数表示闭合;负数表示计算序列组成的面积;提取的角点以list形式时,用负数。

       cout<<"面积s:"<<s<<'    '<<"周长L:"<<L<<endl;

}



没有更多推荐了,返回首页