Opencv处理图像--细化
Opencv处理图像—细化
细化的算法有很多种,但比较常用的算法是查表法
细化是从原来的图中去掉一些点,但仍要保持原来的形状。
实际上是保持原图的骨架。
代码如上:
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
IplImage* ColorSrc ,*ColorSrcCopy;
//#define SHOW
//#define LONG int
//#define BYTE unsigned char
/
//基于索引表的细化细化算法
//功能:对图象进行细化
//参数:lpDIBBits:代表图象的一维数组
// lWidth:图象高度
// lHeight:图象宽度
// 无返回值
bool ThiningDIBSkeleton (unsigned char* lpDIBBits, int lWidth, int lHeight)
{
//循环变量
long i;
long j;
long lLength;
unsigned char deletemark[256] = {
0,0,0,0,0,0,0,1, 0,0,1,1,0,0,1,1,
0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,1,
0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,
0,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,
1,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,
0,0,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,
0,0,0,0,0,0,0,0, 0,0,0,1,0,0,1,1,
1,1,0,1,0,0,0,1, 0,0,0,0,0,0,0,0,
1,1,0,1,0,0,0,1, 1,1,0,0,1,0,0,0,
0,1,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,
0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,1,
1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0,
1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0
};//索引表
unsigned char p0, p1, p2, p3, p4, p5, p6, p7;
unsigned char *pmid, *pmidtemp;
unsigned char sum;
int changed;
bool bStart = true;
lLength = lWidth * lHeight;
unsigned char *pTemp = (unsigned char *)malloc(sizeof(unsigned char) * lWidth * lHeight);
// P0 P1 P2
// P7 P3
// P6 P5 P4
while(bStart)
{
bStart = false;
changed = 0;
//首先求边缘点(并行)
pmid = (unsigned char *)lpDIBBits + lWidth + 1;
memset(pTemp, 0, lLength);
pmidtemp = (unsigned char *)pTemp + lWidth + 1;
for(i = 1; i < lHeight -1; i++)
{
for(j = 1; j < lWidth - 1; j++)
{
if( *pmid == 0)
{
pmid++;
pmidtemp++;
continue;
}
p3 = *(pmid + 1);
p2 = *(pmid + 1 - lWidth);
p1 = *(pmid - lWidth);
p0 = *(pmid - lWidth -1);
p7 = *(pmid - 1);
p6 = *(pmid + lWidth - 1);
p5 = *(pmid + lWidth);
p4 = *(pmid + lWidth + 1);
sum = p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7;
if(sum == 0)
{
*pmidtemp = 1;
#ifdef SHOW
cvSet2D(ColorSrc,i,j,cvScalar(0,0,255));
#endif
}
pmid++;
pmidtemp++;
}
pmid++;
pmid++;
pmidtemp++;
pmidtemp++;
}
#ifdef SHOW
cvNamedWindow("color");
cvShowImage("color",ColorSrc);
cvWaitKey(0);
#endif
//现在开始串行删除
pmid = (unsigned char *)lpDIBBits + lWidth + 1;
pmidtemp = (unsigned char *)pTemp + lWidth + 1;
for(i = 1; i < lHeight -1; i++)
{
for(j = 1; j < lWidth - 1; j++)
{
if( *pmidtemp == 0)
{
pmid++;
pmidtemp++;
continue;
}
p3 = *(pmid + 1);
p2 = *(pmid + 1 - lWidth);
p1 = *(pmid - lWidth);
p0 = *(pmid - lWidth -1);
p7 = *(pmid - 1);
p6 = *(pmid + lWidth - 1);
p5 = *(pmid + lWidth);
p4 = *(pmid + lWidth + 1);
p1 *= 2;
p2 *= 4;
p3 *= 8;
p4 *= 16;
p5 *= 32;
p6 *= 64;
p7 *= 128;
sum = p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7;
// sum = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
if(deletemark[sum] == 1)
{
*pmid = 0;
bStart = true;
#ifdef SHOW
cvSet2D(ColorSrc,i,j,cvScalar(0,0,0));
cvNamedWindow("delcolor");
cvShowImage("delcolor",ColorSrc);
cvWaitKey(2);
#endif
}
pmid++;
pmidtemp++;
}
pmid++;
pmid++;
pmidtemp++;
pmidtemp++;
}
#ifdef SHOW
printf("过了一圈\n");
#endif
}
return true;
}
int main()
{
//#define WRITERESULT
//#define WRITEIMAGE
IplImage* src = cvLoadImage("char2.png",0); //加载图像并灰度化
cvThreshold(src,src,100,255,CV_THRESH_BINARY); //二值化图像
unsigned char* imagedata ;
ColorSrc = cvLoadImage("char2.png",1);
cvNamedWindow("s");
cvShowImage("s" , src);
FILE* fp ;
#ifdef WRITEIMAGE
fp = fopen("data255.txt","rt+");
#endif
imagedata = (unsigned char*)malloc(sizeof(char)*src->width*src->height); //动态分配内存
int x , y;
for(y=0;y<src->height;y++)
{
unsigned char* ptr = (unsigned char*)(src->imageData + y*src->widthStep);
for(x=0;x<src->width;x++)
{
imagedata[y*src->width+x] = ptr[x] > 0 ? 1 : 0;
#ifdef WRITEIMAGE
if(ptr[x] > 0)
fprintf(fp,"1");
else
{
fprintf(fp,"0");
}
#endif
}
#ifdef WRITEIMAGE
fprintf(fp,"\n");
#endif
}
#ifdef WRITEIMAGE
fclose(fp);
#endif
#ifdef WRITERESULT
fp = fopen("result.txt","rt+");
#endif
ThiningDIBSkeleton(imagedata,src->width,src->height);//进行细化操作
for(y=0;y<src->height;y++)
{
unsigned char* ptr = (unsigned char*)(src->imageData + y*src->widthStep);
for(x=0;x<src->width;x++)
{
ptr[x] = imagedata[y*src->width + x]>0? 255 : 0;
#ifdef WRITERESULT
if(ptr[x] > 0)
fprintf(fp,"1");
else
{
fprintf(fp,"0");
}
#endif
}
#ifdef WRITERESULT
fprintf(fp,"\n");
#endif
}
#ifdef WRITERESULT
fclose(fp);
#endif
cvNamedWindow("src");
cvShowImage("src" , src);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&ColorSrc);
free(imagedata);
return 0;
}
细化前后对比
博客参考https://www.cnblogs.com/zhazhiqiang/p/4487950.html
还没有评论,来说两句吧...