您的位置:首页 > 其它

图像分割

2015-11-16 19:52 411 查看
1.图像分割:将一幅图像分解为若干个互不交叠的、有意义的、具有相同性质的区域。(灰度、纹理、区域边界、相邻区域)

2.间隔检测(点、线)

3.边缘检测(灰度和结构等信息发生改变,有方向和幅度两个特性,用微分算子检测出来)

4.梯度算子是一阶算子由图分析可得,它们都对图像进行了一个掩膜卷积处理,处理的复杂程度也越来越高,同时对边缘检测尤其是对噪声的抑制方面强

5.二阶导数:各种算子:

分别为四邻域八邻域上的掩膜模板

5.边缘连接和边缘检测

基本步骤:起始搜索点——边界判别准则和搜索准则——终止条件

6.hough变换在图像上给出n个点,我们希望找到这些点中位于直线上的点组成的子集。方法为先寻找所有由每对点确定的直线,然后找到所有接近特定直线的点组成的子集。

功能:将断了的线段连接起来,具有较强的抑制噪声的能力,能够提取出在噪声背景中的直线

7.门限处理(阈值分割):全局门限、自适应门限、最佳门限

8.区域分割:区域生长、区域分离合并

9.区域生长的步骤:选择合适的种子点

确定相似性准则(生长准则)

确定生长停止条件

10.区域分离:区域的某些特性差别比较大,不满足一致性准则,则区域应采用分离法,分离过程从图像的最大区域开始,一般情况下,从整幅图像开始;注意:确定分离准则(一致性准则)、确定分离方法,即如何分离区域,使得分离后的子区域尽可能满足一致性

11.区域分离算法:1形成初始区域

2对图像的每个区域,计算P,如果错误,则沿着某一合适的边界分离区域

3重复2,没有区域需要分离时,算法结束

13区域合并

14.迭代法:迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法,即一次性解决问题。迭代法又分为精确迭代和近似迭代。“二分法”和“牛顿迭代法”属于近似迭代法。迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值.

15.代码实现

a区域生长算法\\函数名称: * RegionGrow() * * \\输入参数: * CDib * pDib - 指向CDib类的指针,含有原始图象信息 * unsigned char * pUnRegion - 指向区域生长结果的指针 * * \\返回值: * 无 * * \\说明: * pUnRegion指针指向的数据区存储了区域生长的结果,其中1(逻辑)表示 * 对应象素为生长区域,0表示为非生长区域 * 区域生长一般包含三个比较重要的问题: * 1. 种子点的选取 * 2. 生长准则 * 3. 终止条件 * 可以认为,这三个问题需要具体分析,而且每个问题解决的好坏直接关系到 * 区域生长的结果。 * 本函数的种子点选取为图像的中心,生长准则是相邻象素的象素值小于 * nThreshold, 终止条件是一直进行到再没有满足生长准则需要的象素时为止 * ************************************************************************* */ void RegionGrow(CDib * pDib, unsigned char * pUnRegion, int nThreshold) { static int nDx[]={-1,0,1,0}; static int nDy[]={0,1,0,-1};

// 遍历图象的纵坐标 // int y;

// 遍历图象的横坐标 // int x;

// 图象的长宽大小 CSize sizeImage = pDib->GetDimensions(); int nWidth = sizeImage.cx int nHeight = sizeImage.cy

// 图像在计算机在存储中的实际大小 CSize sizeImageSave = pDib->GetDibSaveDim(); // 图像在内存中每一行象素占用的实际空间 int nSaveWidth = sizeImageSave.cx;

// 初始化 memset(pUnRegion,0,sizeof(unsigned char)*nWidth*nHeight);

// 种子点 int nSeedX, nSeedY;

// 设置种子点为图像的中心 nSeedX = nWidth /2 nSeedY = nHeight/2

// 定义堆栈,存储坐标 int * pnGrowQueX int * pnGrowQueY

// 分配空间 pnGrowQueX = new int [nWidth*nHeight]; pnGrowQueY = new int [nWidth*nHeight];

// 图像数据的指针 unsigned char * pUnchInput =(unsigned char * )pDib->m_lpImage; // 定义堆栈的起点和终点

// 当nStart=nEnd, 表示堆栈中只有一个点 int nStart int nEnd ; //初始化 nStart = 0 nEnd = 0

// 把种子点的坐标压入栈 pnGrowQueX[nEnd] = nSeedX; pnGrowQueY[nEnd] = nSeedY;

// 当前正在处理的象素 int nCurrX int nCurrY

// 循环控制变量 int k

// 图象的横纵坐标,用来对当前象素的4邻域进行遍历 int xx; int yy; while (nStart<=nEnd) {

// 当前种子点的坐标 nCurrX = pnGrowQueX[nStart]; nCurrYpnGrowQueY[nStart];

// 对当前点的4邻域进行遍历 for (k=0; k<4; k++) {

// 4邻域象素的坐标 xx = nCurrX+nDx[k]; yy = nCurrY+nDy[k];

// 判断象素(xx,yy) 是否在图像内部 // 判断象素(xx,yy) 是否已经处理过 // pUnRegion[yy*nWidth+xx]==0 表示还没有处理

// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值 if ( (xx < nWidth) && (xx>=0) && (yy<nHeight) && (yy>=0) && (pUnRegion[yy*nWidth+xx]==0) && abs(pUnchInput[yy*nSaveWidth+xx] - pUnchInput[nCurrY*nSaveWidth+nCurrX])<nThreshold ) { // 堆栈的尾部指针后移一位 nEnd++; // 象素(xx,yy) 压入栈 pnGrowQueX[nEnd] = xx; pnGrowQueY[nEnd] = yy; // 把象素(xx,yy)设置成逻辑1(255) // 同时也表明该象素处理过 pUnRegion[yy*nWidth+xx] = 255 } } nStart++; } // 释放内存 delete []pnGrowQueX; delete []pnGrowQueY; pnGrowQueX = NULL pnGrowQueY = NULL } 对于2D图象的组织增长,使用递归也是一种不错的选择,但需要注意栈空间需要设大一些。 而在3D数据场上,递归几乎是不可行的,栈空间经常会出现溢出的情况,因此不具备实用性。 2D组织增长伪代码如下 组织增长(Image* pImage, int i, ing j, byte* mask) { if 不满足增长条件(pImage, i,j, mask) return; 设置标记(mask, i, j); 组织增长(pImage, i-1, j, mask); 组织增长(pImage, i+1, j, mask);

16区域生长是通过matlab图像处理工具箱中的函数imreconstruct来完成的。调用函数outim=imreconstruct(markerim,maskim),markerim为标记图像,maskim为模板图像,outim为输出图像,imreconstruct函数的工作过程是一个迭代过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: