原理见下图:
代码如下:
void Ctry::OnTryTyr1()
{
//TODO: 在此添加命令处理程序代码
IplImage *img = cvLoadImage("C:\\Users\\Administrator\\Desktop\\819.jpg",0);
if (img != 0)//imgSource为IplImage*
{
for (int j = 0; j < img->width; ++j)
{
for (int i = 0; i < img->height; ++i)
{
//获取(i, j)处的单道图像像素值
double dPixelVal = cvGetReal2D(img, i, j);
if ( dPixelVal <= 42)
{
//设定(i, j)处的单通道图像像素值
cvSetReal2D(img, i, j, 0);
}
else
{
cvSetReal2D(img, i, j, 255);
}
}
}
}
Thining(img);
cvReleaseImage(&img);
}
void Ctry::Thining(IplImage *img)
{
//四个条件
bool bCondition1;
bool bCondition2;
bool bCondition3;
bool bCondition4;
//5*5相邻区域像素值
unsigned char neighbour[5][5];
int i, j;
int m, n;
bool bModified = true;
while (bModified)
{
bModified = false;
IplImage *dst = cvCreateImage(cvGetSize(img), 8, 1);
//清空目标图像
for (int i = 0; i < dst->height; i++)
{
for (int j = 0; j < dst->width; j++)
{
cvSetReal2D(dst, i, j, 255);
}
}
for ( j = 2; j < img->height-2; j++)
{
for (i = 2; i < img->width-2; i++)
{
bool bCondition1 = false;
bool bCondition2 = false;
bool bCondition3 = false;
bool bCondition4 = false;
double pixel = cvGetReal2D(img, j, i);
if (pixel == 255)
continue;
//获得当前点相邻的5*5区域内像素值,白色用0代表,黑色用1代表
for ( m = 0; m < 5; m++)
{
for (n = 0; n < 5; n++)
{
neighbour[m][n] = (cvGetReal2D(img, j + n - 2, i + m - 2) == 0);
}
}
//逐个判断条件
//判断2<=NZ(P1)<=6
int 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)
{
cvSetReal2D(dst, j, i,255);
bModified = true;
}
else
{
cvSetReal2D(dst,j, i, 0);
}
}
}
cvSaveImage("C:\\Users\\Administrator\\Desktop\\I.jpg", dst);
}
}
由于运算量大,时间长,部分效果图: