基于区域生长的二值化图像连通域标记
2011-08-02 11:26
393 查看
最近在做一个图像识别方面的项目
以下是自己写的一个关于二值化图像连通域标记的代码
算法效率较高
编程容易
贴出来和大家分享一下!!
void ConnDomainMark (BYTE *p, int *pConnDomainMark, int *pMaxMarkValue, BYTE obj,
int width, int height, BYTE bitcount)
{
LONG LineBytes = (width + 3)/4*4;
CList <CPoint, CPoint> *pMarkSeedList;
pMarkSeedList = new CList <CPoint, CPoint>;
int i, j, temp;
int markvalue = 1000;
for (i=0; i<height; i++)
{
temp = i*LineBytes;
for (j=0; j<width; j++)
{
if ((obj == *(p + temp + j)) && (0 == *(pConnDomainMark + temp + j)))
{
markvalue++;
*(pConnDomainMark + temp + j) = markvalue;
CPoint pt(i, j);
pMarkSeedList->AddTail(pt);
}
while(!pMarkSeedList->IsEmpty())
{
int m, n;
m = ((CPoint)pMarkSeedList->GetHead()).x;
n = ((CPoint)pMarkSeedList->GetHead()).y;
//左
if ((n > 0) && (obj == *(p + m*LineBytes + n - 1)) && (0 == *(pConnDomainMark + m*LineBytes + n - 1)))
{
*(pConnDomainMark + m*LineBytes + n - 1) = markvalue;
CPoint pt(m, n-1);
pMarkSeedList->AddTail(pt);
}
//左上
if ((m > 0) && (n > 0) && (obj == *(p + (m-1)*LineBytes + n - 1)) && (0 == *(pConnDomainMark + (m-1)*LineBytes + n - 1)))
{
*(pConnDomainMark + (m-1)*LineBytes + n - 1) = markvalue;
CPoint pt(m-1, n-1);
pMarkSeedList->AddTail(pt);
}
//上
if ((m > 0) && (obj == *(p + (m-1)*LineBytes + n)) && (0 == *(pConnDomainMark + (m-1)*LineBytes + n)))
{
*(pConnDomainMark + (m-1)*LineBytes + n) = markvalue;
CPoint pt(m-1, n);
pMarkSeedList->AddTail(pt);
}
//右上
if ((m > 0) && (n < (width-1)) && (obj == *(p + (m-1)*LineBytes + n + 1)) && (0 == *(pConnDomainMark + (m-1)*LineBytes + n + 1)))
{
*(pConnDomainMark + (m-1)*LineBytes + n + 1) = markvalue;
CPoint pt(m-1, n+1);
pMarkSeedList->AddTail(pt);
}
//右
if ((n < (width-1)) && (obj == *(p + m*LineBytes + n + 1)) && (0 == *(pConnDomainMark + m*LineBytes + n + 1)))
{
*(pConnDomainMark + m*LineBytes + n + 1) = markvalue;
CPoint pt(m, n+1);
pMarkSeedList->AddTail(pt);
}
//右下
if ((m < (height-1)) && (n < (width-1)) && (obj == *(p + (m+1)*LineBytes + n + 1)) && (0 == *(pConnDomainMark + (m+1)*LineBytes + n + 1)))
{
*(pConnDomainMark + (m+1)*LineBytes + n + 1) = markvalue;
CPoint pt(m+1, n+1);
pMarkSeedList->AddTail(pt);
}
//下
if ((m < (height-1)) && (obj == *(p + (m+1)*LineBytes + n)) && (0 == *(pConnDomainMark + (m+1)*LineBytes + n)))
{
*(pConnDomainMark + (m+1)*LineBytes + n) = markvalue;
CPoint pt(m+1, n);
pMarkSeedList->AddTail(pt);
}
//左下
if ((m < (height-1)) && (n > 0) && (obj == *(p + (m+1)*LineBytes + n - 1)) && (0 == *(pConnDomainMark + (m+1)*LineBytes + n - 1)))
{
*(pConnDomainMark + (m+1)*LineBytes + n - 1) = markvalue;
CPoint pt(m+1, n-1);
pMarkSeedList->AddTail(pt);
}
pMarkSeedList->RemoveHead();
}
}
}
*pMaxMarkValue = markvalue;
return TRUE;
}
以下是自己写的一个关于二值化图像连通域标记的代码
算法效率较高
编程容易
贴出来和大家分享一下!!
void ConnDomainMark (BYTE *p, int *pConnDomainMark, int *pMaxMarkValue, BYTE obj,
int width, int height, BYTE bitcount)
{
LONG LineBytes = (width + 3)/4*4;
CList <CPoint, CPoint> *pMarkSeedList;
pMarkSeedList = new CList <CPoint, CPoint>;
int i, j, temp;
int markvalue = 1000;
for (i=0; i<height; i++)
{
temp = i*LineBytes;
for (j=0; j<width; j++)
{
if ((obj == *(p + temp + j)) && (0 == *(pConnDomainMark + temp + j)))
{
markvalue++;
*(pConnDomainMark + temp + j) = markvalue;
CPoint pt(i, j);
pMarkSeedList->AddTail(pt);
}
while(!pMarkSeedList->IsEmpty())
{
int m, n;
m = ((CPoint)pMarkSeedList->GetHead()).x;
n = ((CPoint)pMarkSeedList->GetHead()).y;
//左
if ((n > 0) && (obj == *(p + m*LineBytes + n - 1)) && (0 == *(pConnDomainMark + m*LineBytes + n - 1)))
{
*(pConnDomainMark + m*LineBytes + n - 1) = markvalue;
CPoint pt(m, n-1);
pMarkSeedList->AddTail(pt);
}
//左上
if ((m > 0) && (n > 0) && (obj == *(p + (m-1)*LineBytes + n - 1)) && (0 == *(pConnDomainMark + (m-1)*LineBytes + n - 1)))
{
*(pConnDomainMark + (m-1)*LineBytes + n - 1) = markvalue;
CPoint pt(m-1, n-1);
pMarkSeedList->AddTail(pt);
}
//上
if ((m > 0) && (obj == *(p + (m-1)*LineBytes + n)) && (0 == *(pConnDomainMark + (m-1)*LineBytes + n)))
{
*(pConnDomainMark + (m-1)*LineBytes + n) = markvalue;
CPoint pt(m-1, n);
pMarkSeedList->AddTail(pt);
}
//右上
if ((m > 0) && (n < (width-1)) && (obj == *(p + (m-1)*LineBytes + n + 1)) && (0 == *(pConnDomainMark + (m-1)*LineBytes + n + 1)))
{
*(pConnDomainMark + (m-1)*LineBytes + n + 1) = markvalue;
CPoint pt(m-1, n+1);
pMarkSeedList->AddTail(pt);
}
//右
if ((n < (width-1)) && (obj == *(p + m*LineBytes + n + 1)) && (0 == *(pConnDomainMark + m*LineBytes + n + 1)))
{
*(pConnDomainMark + m*LineBytes + n + 1) = markvalue;
CPoint pt(m, n+1);
pMarkSeedList->AddTail(pt);
}
//右下
if ((m < (height-1)) && (n < (width-1)) && (obj == *(p + (m+1)*LineBytes + n + 1)) && (0 == *(pConnDomainMark + (m+1)*LineBytes + n + 1)))
{
*(pConnDomainMark + (m+1)*LineBytes + n + 1) = markvalue;
CPoint pt(m+1, n+1);
pMarkSeedList->AddTail(pt);
}
//下
if ((m < (height-1)) && (obj == *(p + (m+1)*LineBytes + n)) && (0 == *(pConnDomainMark + (m+1)*LineBytes + n)))
{
*(pConnDomainMark + (m+1)*LineBytes + n) = markvalue;
CPoint pt(m+1, n);
pMarkSeedList->AddTail(pt);
}
//左下
if ((m < (height-1)) && (n > 0) && (obj == *(p + (m+1)*LineBytes + n - 1)) && (0 == *(pConnDomainMark + (m+1)*LineBytes + n - 1)))
{
*(pConnDomainMark + (m+1)*LineBytes + n - 1) = markvalue;
CPoint pt(m+1, n-1);
pMarkSeedList->AddTail(pt);
}
pMarkSeedList->RemoveHead();
}
}
}
*pMaxMarkValue = markvalue;
return TRUE;
}
相关文章推荐
- 实现二值图像连通区标记之区域生长法
- 实现二值图像连通区标记之区域生长法
- 实现二值图像连通区标记之区域生长法
- 实现二值图像连通区标记之区域生长法
- 基于区域的图像分割-----------区域生长
- 二值图像连通区域标记(OpenCV版)
- 连通区域标记:c++版的bwlabel实现(基于opencv)
- 【转】基于区域的图像分割-----------区域生长
- Matlab形态学图像处理:二值图像分割 标记连通区域和重心位置 删除连通区域
- 【图像处理】二值图像连通域标记-基于行程的标记方法-计算目标中心位置方法1
- C++ 二值图像连通区域标记
- 数字图像处理—图像分割—并行区域—连通区域标记(像素标记)(4-连通情况)
- 基于区域生长的二值图像标记,去掉区域的细小直线段并选择
- 一种二值图像连通区域标记的新方法
- bwlabel(BW,n) matlab中标记二值图像中白色(1)的连通区域
- OpenCV:二值图像连通区域分析与标记算法实现
- OpenCV 基于轮廓提取的二值图像分析与连通区域标记算法
- 采用递归实现二值化图像连通区域的区域生长算法
- 基于区域的图像分割-----------区域生长
- OpenCV:二值图像连通区域分析与标记算法实现