您的位置:首页 > 编程语言 > MATLAB

搜索边缘链表算法之Matlab实现

2016-01-09 20:49 531 查看
概要:对于一幅二值图,需要提取图像的边缘点,并将其放入边缘链表中,其示意图如下:



方法是:

1:找到图像的起始位置,如最左上位置即为起始点,如下所示:



可以通过逐列扫描,然后再行扫描,即可找到。

2:旋转上次的查找方向,重新再搜索。如对于起始点A,它的上次搜索方向为向下,然后再逆时针旋转45∘。而对于上次搜索方向为45∘,135∘,225∘,315∘,则应该逆时针旋转90∘。如下图所示:



3:对于部分在图像的边缘部分的点,它的搜索会出现越界错误,因而可以考虑将图像放大2行和2列,然后再进行搜索,此时则不会出现越界现象。

4:当新加入的点和起始点一致时,搜索结束。

搜索边缘链表的MATLAB程序如下:

function edgeList = EdgeListCsdn(data)
% 本程序用来求取二值图的边缘链表
% data为二值图像,1为目标,0为背景
% edgeList 为data的边缘链表2*N,其首链表和末链表为同一边缘点

direction = [0 1; -1 1; -1 0; -1 -1; 0 -1; 1 -1; 1 0; 1 1];
direction = [direction; direction];

% 扩展数据,使其周边像素为0
im = zeros(size(data,1) + 2, size(data,2) + 2);
im(2:(end-1), 2:(end-1)) = data;

%查找起始点
[x, y] = find(im == 1);
xori = x(1); yori = y(1);

edgex = xori;
edgey = yori;

% 设置起始查找方向
i = 6;
while 1
if (1 == im(edgex(end) + direction(i, 1), edgey(end) + direction(i, 2)))
edgex = [edgex, edgex(end) + direction(i, 1)];
edgey = [edgey, edgey(end) + direction(i, 2)];

offset = 2 - mod(i, 2);
i = mod( (i - offset) - 1, 8) + 1 ;
if(edgex(1) == edgex(end) && edgey(1) == edgey(end))
break;
end
else
i = i+1;
end
end

edgeList = [edgex-1; edgey-1];


其C++程序如下:

int EdgeListCsdn(const unsigned char *data, const int row, const int col, int** inde, int* number)
{
if(NULL == data || NULL == inde)
return false;

//设置初始边缘链表长度
int indexLength = 20;
int* index = new int [indexLength];

//设置默认的查找方向
int direction[16][2] ={ {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1},
{0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}};

//查找data中第一个值的位置
for(int i = 0; i < row*col; i++)
{
if(1 == data[i])
{
index[0] = i/col;
index[1] = i%col;
break;
}
}

//设置初始值,并开始进行查找
int direInd = 5;
int length = 0;
while (true)
{
if (1 == data[(index[length] + direction[direInd][0]) * col + index[length + 1] + direction[direInd][1]])
{
if(length + 3 >= indexLength)
{
indexLength *= 2;
int* indexNew = new int [indexLength];
memcpy(indexNew, index, sizeof(int) * (indexLength >> 1));

delete [] index;
index = indexNew;

TraceArray(index, indexLength >> 1, 2); TRACE("\n");
}
index[length + 2] = index[length] + direction[direInd][0];
index[length + 3] = index[length + 1] + direction[direInd][1];

length += 2;

direInd = direInd - 1 - (direInd & 1);
direInd = direInd & 7;

//首像素和末像素重合,则退出
if(index[length] == index[0] && index[length + 1] == index[1])
{
break;
}

}
else
{
direInd++;
}
}

if(NULL != *inde)
{
delete[] *inde;
}

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