如何细化二值化后的图象 最近,我在做指纹预处理时,得到二值化后的图象,有很多的细化方法,线跟踪法,谢尔曼细化法,还有模板细化算法.但好象都不大好应用,不知道各位大虾有没有什么好的算法,比如对一个m*n像素矩阵,元素值为0,1.采用什么样的方法能细化使一些元素由1变0?谢谢了! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www-scf.usc.edu/~flv/ipbook/你看看这个,不知道对你有没有帮助 BOOL WINAPI ThiningDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight){ // 指向源图像的指针 LPSTR lpSrc; // 指向缓存图像的指针 LPSTR lpDst; // 指向缓存DIB图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; LONG lLineBytes=WIDTHBYTES(lWidth * 8); //脏标记 BOOL bModified; //循环变量 long i; long j; int n; int m; //四个条件 BOOL bCondition1; BOOL bCondition2; BOOL bCondition3; BOOL bCondition4; bool bNotCondition5; //计数器 unsigned char nCount; //像素值 unsigned char pixel; //5×5相邻区域像素值 unsigned char neighbour[5][5]; // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的内存,设定初始值为255 lpDst = (char *)lpNewDIBBits; memset(lpDst, (BYTE)255,lLineBytes * lHeight); bModified=TRUE; while(bModified) { bModified = FALSE; // 初始化新分配的内存,设定初始值为255 lpDst = (char *)lpNewDIBBits; memset(lpDst, (BYTE)255, lLineBytes* lHeight); for(j = 2; j <lHeight-2; j++) { for(i = 2;i <lWidth-2; i++) { bCondition1 = FALSE; bCondition2 = FALSE; bCondition3 = FALSE; bCondition4 = FALSE; bNotCondition5=true; //由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素 // 指向源图像倒数第j行,第i个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * j + i; // 指向目标图像倒数第j行,第i个象素的指针 lpDst = (char *)lpNewDIBBits + lLineBytes * j + i; //取得当前指针处的像素值,注意要转换为unsigned char型 pixel = (unsigned char)*lpSrc; //目标图像中含有0和255外的其它灰度值 if(pixel != 255 && *lpSrc != 0) //return FALSE; continue; //如果源图像中当前点为白色,则跳过 else if(pixel == 255) continue; //获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表 for (m = 0;m < 5;m++ ) { for (n = 0;n < 5;n++) { neighbour[m][n] =(255 - (unsigned char)*(lpSrc + ((4 - m) - 2)*lLineBytes + n - 2 )) / 255; } }// 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; if(neighbour[1][2]+neighbour[1][1]+neighbour[2][1]+ neighbour[3][1]+neighbour[3][2]+neighbour[3][3]+ neighbour[2][3]+neighbour[1][3]==1) bNotCondition5=false; //判断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&&bNotCondition5) { *lpDst = (unsigned char)255; bModified = TRUE; } else { *lpDst = (unsigned char)0; } } } // 复制腐蚀后的图像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); } // 复制腐蚀后的图像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE;} 问一下【svchost.exe应用程序错误】的原因 关于编写播放器的问题 opengl写漫游用了glulookat,然后用billboard绘树,树的位置老改变 关于同一程序运行在单核主机与双核主机下的内存占用量不同的疑问? 文件与文件间如何共享数据? 紧急求助:高分求助VC画板程序! 各位大虾,紧急求助 奇怪的问题 请教:控件上文字的字体如何设定。 DLL高手请看! 不知道有没有“模拟”打印机的软件? 多列显示的listctrl,首列为checkbox,怎么确定被选中"√"的索引号?
{
// 指向源图像的指针
LPSTR lpSrc;
// 指向缓存图像的指针
LPSTR lpDst;
// 指向缓存DIB图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
LONG lLineBytes=WIDTHBYTES(lWidth * 8);
//脏标记
BOOL bModified; //循环变量
long i;
long j;
int n;
int m; //四个条件
BOOL bCondition1;
BOOL bCondition2;
BOOL bCondition3;
BOOL bCondition4;
bool bNotCondition5; //计数器
unsigned char nCount;
//像素值
unsigned char pixel; //5×5相邻区域像素值
unsigned char neighbour[5][5]; // 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255,lLineBytes * lHeight); bModified=TRUE; while(bModified)
{ bModified = FALSE;
// 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes* lHeight); for(j = 2; j <lHeight-2; j++)
{
for(i = 2;i <lWidth-2; i++)
{ bCondition1 = FALSE;
bCondition2 = FALSE;
bCondition3 = FALSE;
bCondition4 = FALSE;
bNotCondition5=true; //由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素 // 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i; // 指向目标图像倒数第j行,第i个象素的指针
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i; //取得当前指针处的像素值,注意要转换为unsigned char型
pixel = (unsigned char)*lpSrc; //目标图像中含有0和255外的其它灰度值
if(pixel != 255 && *lpSrc != 0)
//return FALSE;
continue;
//如果源图像中当前点为白色,则跳过
else if(pixel == 255)
continue; //获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
for (m = 0;m < 5;m++ )
{
for (n = 0;n < 5;n++)
{
neighbour[m][n] =(255 - (unsigned char)*(lpSrc + ((4 - m) - 2)*lLineBytes + n - 2 )) / 255;
}
}
// 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;
if(neighbour[1][2]+neighbour[1][1]+neighbour[2][1]+
neighbour[3][1]+neighbour[3][2]+neighbour[3][3]+
neighbour[2][3]+neighbour[1][3]==1)
bNotCondition5=false;
//判断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&&bNotCondition5)
{
*lpDst = (unsigned char)255;
bModified = TRUE;
}
else
{
*lpDst = (unsigned char)0;
}
}
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits); // 返回
return TRUE;
}