二值图像轮廓提取的问题

shuke2000 2008-05-09 09:19:00

我要将一幅二值图像的轮廓提取出来,在网上找了一种查找黑点周围八个点的方法,如果一个黑点周围八个点都是黑点,那么将该黑点删除。

用该代码完成后发现不能达到目的,程序只能将图像黑色区域变成一道黑一道白的样子,并不能完全将黑色区域内部完全掏空。


我是新手,请大家帮我看看代码。谢谢!!!


int num;//相邻八个点灰度值之和
int nw,n,ne,w,e,sw,s,se;//相邻八个点的灰度值

long i;
long j;//循环变量

unsigned char pixel;//当前点灰度值

for (i = 1;i <m_Height-1;i++)
{
for(j = 1;j < m_Width-1;j++)
{
pixel = (unsigned char)*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3);
//m_lpDibbitsChg是指向源图像的指针,m_Height是图像高度,m_Width是图像宽度,m_bytePerLine是图像每行字节数

if(pixel==(unsigned char)0)//如果当前点为黑点,求其相邻八点的灰度值
{
nw=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i-1)-1)*m_bytePerLine+(j-1)*3);

n=(unsigned char)*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+(j-1)*3);

ne=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i+1)-1)*m_bytePerLine+(j-1)*3);

w=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i-1)-1)*m_bytePerLine+j*3);

e=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i+1)-1)*m_bytePerLine+j*3);

sw=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i-1)-1)*m_bytePerLine+(j+1)*3);

s=(unsigned char)*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+(j+1)*3);

ne=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i+1)-1)*m_bytePerLine+(j+1)*3);

num=nw+n+ne+w+e+sw+s+se;

if(num==0) //说明都是黑点

{
*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3) = (unsigned char)255;

*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3+1) = (unsigned char)255;

*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3+2) = (unsigned char)255; //删除该黑点
}
}
}
}




...全文
569 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
gcm3070341084 2011-05-30
  • 打赏
  • 举报
回复
说得有道理,我也犯这个错误
大麦ordheart 2010-05-27
  • 打赏
  • 举报
回复
看看啊
shuke2000 2008-05-10
  • 打赏
  • 举报
回复
谢谢楼上几位尤其是快乐鹦鹉的帮助。分已经给了,可惜laoma_hbu 来晚了,已经结贴了。只能口头感谢了。
laoma_hbu 2008-05-10
  • 打赏
  • 举报
回复
如1楼所说的,你前面像素的操作影响了后面像素的结果,
解决方法是借助缓冲区(可新建一个与原始图像数据区一般大小的空缓冲区),
根据当前图像的像素判断是否为轮廓,如果是则修改缓冲区中的值,置为黑点
最后把缓冲区再重新赋给原始图像
wqvbjhc 2008-05-10
  • 打赏
  • 举报
回复
http://blog.csdn.net/wqvbjhc/archive/2008/04/17/2299066.aspx
shuke2000 2008-05-10
  • 打赏
  • 举报
回复
谢谢你了,我看了网上的很多东西都说是这样判断的,我也仔细想过,与被删除黑点相邻的内部点是不会被删除。可我不知道怎么解决。原来是判断完了所有点才删除。
快乐鹦鹉 2008-05-10
  • 打赏
  • 举报
回复
比如,定义一个CPoint动态数组
#include <afxtempl.h>
typedef CArray<CPoint,CPoint&> CPointArray;
CPointArray arBlackPt;
int num;//相邻八个点灰度值之和
int nw,n,ne,w,e,sw,s,se;//相邻八个点的灰度值

long i;
long j;//循环变量

unsigned char pixel;//当前点灰度值

for (i = 1;i <m_Height-1;i++)
{
for(j = 1;j < m_Width-1;j++)
{
pixel = (unsigned char)*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3);
//m_lpDibbitsChg是指向源图像的指针,m_Height是图像高度,m_Width是图像宽度,m_bytePerLine是图像每行字节数

if(pixel==(unsigned char)0)//如果当前点为黑点,求其相邻八点的灰度值
{
nw=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i-1)-1)*m_bytePerLine+(j-1)*3);

n=(unsigned char)*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+(j-1)*3);

ne=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i+1)-1)*m_bytePerLine+(j-1)*3);

w=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i-1)-1)*m_bytePerLine+j*3);

e=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i+1)-1)*m_bytePerLine+j*3);

sw=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i-1)-1)*m_bytePerLine+(j+1)*3);

s=(unsigned char)*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+(j+1)*3);

ne=(unsigned char)*(m_lpDibbitsChg+(m_Height-(i+1)-1)*m_bytePerLine+(j+1)*3);

num=nw+n+ne+w+e+sw+s+se;

if(num==0) //说明都是黑点

{
CPoint pt;
pt.x = i;
pt.y = j;
arBlackPt.Add(pt);
}
}
}
}
int nSize = arBlackPt.GetSize();
for(int i=0; i<nSize; i++)
{
CPoint pt = arBlackPt.GetAt(i);
*(m_lpDibbitsChg+(m_Height-pt.x-1)*m_bytePerLine+pt.y*3) = (unsigned char)255;

*(m_lpDibbitsChg+(m_Height-pt.x-1)*m_bytePerLine+pt.y*3+1) = (unsigned char)255;

*(m_lpDibbitsChg+(m_Height-pt.x-1)*m_bytePerLine+pt.y*3+2) = (unsigned char)255; //删除该黑点
}
快乐鹦鹉 2008-05-10
  • 打赏
  • 举报
回复
显然你的这个逻辑有问题阿。如果一个黑点周围是八个黑点,那么你把这个黑点变成白色了。那么,在判断其它点时,如果你变成白色的这个点是其周围点,那么这个其它点肯定不会被变为白色了,但其实它原来周围的点都是黑色的,只是由于你把其中一个点修改成白色了,导致无法判断正确。
因此,你在
if(num==0) //说明都是黑点

{
*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3) = (unsigned char)255;

*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3+1) = (unsigned char)255;

*(m_lpDibbitsChg+(m_Height-i-1)*m_bytePerLine+j*3+2) = (unsigned char)255; //删除该黑点
}
时,不能立即修改该点的颜色,否则会影响到其它点的判断。你应该将该点的位置先记录下来,等所有点判断完成后,再将所有记录的点的颜色全部改成白色才可以。

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧