谁有好的细化算法?为什么OPENCV里没有提供这个算法?
大家讨论下!呵呵!不过我知道这个板块的人很少,能来看的人少,能答的上问题的更是凤毛麟角!
为什么opencv不提供细化算法呢?所以我只能自己写细化算法!
想了想我还是想不出什么好办法(能力有限)
后来找了 Hilditch细化算法,很不幸,万方搜索的论文里对这个算法的解释众说纷纭。不知道大家是有意说不清,还是大家都是随便糊弄,还是根本就是笔糊涂账!
后来在GOOGLE图书里找到了本《数字图像处理与分析 By 龚声蓉, 刘纯平, 王强》
仔细看了之后还是这个里面的比较靠谱,但是按照里面的方法写出了后,效果不是很理想
后来还尝试了索引表法 索引表法会让图像断裂!
听说matlab里的Skeletonization确实效果很好 请问如何才能看到里面的源码?我进去看看!
[解决办法]
// 函数功能:细化
// lpDIBBits------------指向图像数据
// lWidth---------------图像像素宽度
// lHeight--------------图像像素高度
// widthStep------------图像内存宽度(为4的倍数)
int Thining(byte* lpDIBBits, int lWidth, int lHeight,int widthStep)
{
if(lpDIBBits==0)
{
return 0;
}
// 指向源图像的指针
byte*lpSrc;
// 指向缓存图像的指针
byte*lpDst;
// 指向缓存DIB图像的指针
byte*lpNewDIBBits;
//脏标记
BOOL bModified;
//循环变量
long i;
long j;
int n;
int m;
//四个条件
BOOL bCondition1;
BOOL bCondition2;
BOOL bCondition3;
BOOL bCondition4;
//计数器
int nCount=0;
//像素值
unsigned char pixel;
//5×5相邻区域像素值
unsigned char neighbour[5][5];
// 暂时分配内存,以保存新图像
lpNewDIBBits = new byte[widthStep*lHeight];
if (lpNewDIBBits == NULL)
{
// 分配内存失败
return 0;
}
// 初始化新分配的内存,设定初始值为0
lpDst = lpNewDIBBits;
memset(lpDst, (BYTE)0, widthStep * lHeight);
bModified=TRUE;
while(bModified)
{
bModified = FALSE;
// 初始化新分配的内存,设定初始值为255
lpDst = lpNewDIBBits;
memset(lpDst, (BYTE)0, widthStep * lHeight);
for(j = 2; j <lHeight-2; j++)
{
for(i = 2;i <lWidth-2; i++)
{
bCondition1 = FALSE;
bCondition2 = FALSE;
bCondition3 = FALSE;
bCondition4 = FALSE;
//由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = lpDIBBits + widthStep * j + i;
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = lpNewDIBBits + widthStep * j + i;
//取得当前指针处的像素值,注意要转换为unsigned char型
pixel = (unsigned char)*lpSrc;
//如果源图像中当前点为白色,则跳过
if(pixel == 0)
continue;
//获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
for (m = 0;m < 5;m++ )
{
for (n = 0;n < 5;n++)
{
if( (unsigned char)*(lpSrc + ((4 - m) - 2)*widthStep + n - 2 )>0 ){
neighbour[m][n] =1;
}
else{
neighbour[m][n] =0;
}
}
}
//neighbour[][]
//逐个判断条件。
//判断2<=NZ(P1)<=6
nCount = neighbour[1][1] + neighbour[1][2] + neighbour[1][3] \
+ neighbour[2][1] + neighbour[2][3] + \
+ neighbour[3][1] + neighbour[3][2] + neighbour[3][3];
if ( nCount >= 2 && nCount <=6)
bCondition1 = TRUE;
//判断Z0(P1)=1
nCount = 0;
if (neighbour[1][2] == 0 && neighbour[1][1] == 1)
nCount++;
if (neighbour[1][1] == 0 && neighbour[2][1] == 1)
nCount++;
if (neighbour[2][1] == 0 && neighbour[3][1] == 1)
nCount++;
if (neighbour[3][1] == 0 && neighbour[3][2] == 1)
nCount++;
if (neighbour[3][2] == 0 && neighbour[3][3] == 1)
nCount++;
if (neighbour[3][3] == 0 && neighbour[2][3] == 1)
nCount++;
if (neighbour[2][3] == 0 && neighbour[1][3] == 1)
nCount++;
if (neighbour[1][3] == 0 && neighbour[1][2] == 1)
nCount++;
if (nCount == 1)
bCondition2 = TRUE;
//判断P2*P4*P8=0 or Z0(p2)!=1
if (neighbour[1][2]*neighbour[2][1]*neighbour[2][3] == 0)
bCondition3 = TRUE;
else
{
nCount = 0;
if (neighbour[0][2] == 0 && neighbour[0][1] == 1)
nCount++;
if (neighbour[0][1] == 0 && neighbour[1][1] == 1)
nCount++;
if (neighbour[1][1] == 0 && neighbour[2][1] == 1)
nCount++;
if (neighbour[2][1] == 0 && neighbour[2][2] == 1)
nCount++;
if (neighbour[2][2] == 0 && neighbour[2][3] == 1)
nCount++;
if (neighbour[2][3] == 0 && neighbour[1][3] == 1)
nCount++;
if (neighbour[1][3] == 0 && neighbour[0][3] == 1)
nCount++;
if (neighbour[0][3] == 0 && neighbour[0][2] == 1)
nCount++;
if (nCount != 1)
bCondition3 = TRUE;
}
//判断P2*P4*P6=0 or Z0(p4)!=1
if (neighbour[1][2]*neighbour[2][1]*neighbour[3][2] == 0)
bCondition4 = TRUE;
else
{
nCount = 0;
if (neighbour[1][1] == 0 && neighbour[1][0] == 1)
nCount++;
if (neighbour[1][0] == 0 && neighbour[2][0] == 1)
nCount++;
if (neighbour[2][0] == 0 && neighbour[3][0] == 1)
nCount++;
if (neighbour[3][0] == 0 && neighbour[3][1] == 1)
nCount++;
if (neighbour[3][1] == 0 && neighbour[3][2] == 1)
nCount++;
if (neighbour[3][2] == 0 && neighbour[2][2] == 1)
nCount++;
if (neighbour[2][2] == 0 && neighbour[1][2] == 1)
nCount++;
if (neighbour[1][2] == 0 && neighbour[1][1] == 1)
nCount++;
if (nCount != 1)
bCondition4 = TRUE;
}
if(bCondition1 && bCondition2 && bCondition3 && bCondition4)
{
*lpDst = (unsigned char)0;
bModified = TRUE;
}
else
{
*lpDst = (unsigned char)255;
}
}
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, widthStep * lHeight);
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, widthStep * lHeight);
// 释放内存
delete[] lpNewDIBBits; lpNewDIBBits=NULL;
// 返回
return 1;
}