网站后台树形菜单样式,郑州福千欣隆网站建设有限公司,网站建设免费软件,wordpress页眉页脚的底色图像细化针对的是二值图像 或者用阀值处理的二值图像。基于索引表的细化算法大致是遍历被二值化图像的边缘#xff0c;根据边缘点的八连通域情况查找索引表以确定该边缘点是否能够被删除。根据一些细化规则我们可以建立索引表#xff0c;因此我们的主要工作就是不断地遍历边…图像细化针对的是二值图像 或者用阀值处理的二值图像。基于索引表的细化算法大致是遍历被二值化图像的边缘根据边缘点的八连通域情况查找索引表以确定该边缘点是否能够被删除。根据一些细化规则我们可以建立索引表因此我们的主要工作就是不断地遍历边缘进行是否删除判断直至边缘的每一个点都不能再被细化删除。
(1)例子 左边为输入图像 右边为细化的效果图 (2)思想 公式: y p0*2^0 p1*2^1 p2*2^2 p3*2^3 p4*2^4 p5*2^5 p6*2^6 p7*2^7
这八个点的取值范围为{0,1} (1表示255)
对于这八个点的不同取值情况按如下顺序表示的二进制的值也将有不同的取值 P7 P6 P5 P4 P3 P2 P1 P0 Sum Delete Enable
其中Sum的取值从0~255Delete Enable为1表示可以删除为0表示不能删除这样我们就建立了一个索引表deletemark[256] 前辈们对此作出了总结得出每个点周围8领域的256种情况放在一个char data[256]的数组中不可以删除用0来表示能被删除的用1来表示。然后对图像进行处理得到二值图像0和1扫描图像根据公式得出y依次用data[y]判断该点是否可以被删除直到所有的点都不可以被删除为止。
(3)算法步骤 (4)代码
#include stdlib.h
#include string.h#include cv.h
#include highgui.h
#include cxcore.h//基于索引表的细化细化算法
//功能对图象进行细化
//参数lpDIBBits代表图象的一维数组
// lWidth图象高度
// lHeight图象宽度
// 无返回值
bool ThiningDIBSkeleton (unsigned char* lpDIBBits, int lWidth, int lHeight)
{ //循环变量long i;long j;long lLength;unsigned char deletemark[256] { // 这个即为前人据8领域总结的是否可以被删除的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; // pmid 用来指向二值图像 pmidtemp用来指向存放是否为边缘unsigned char sum;bool bStart true;lLength lWidth * lHeight;unsigned char *pTemp new uchar[sizeof(unsigned char) * lWidth * lHeight](); //动态创建数组 并且初始化// P0 P1 P2// P7 P3// P6 P5 P4while(bStart){bStart false;//首先求边缘点pmid (unsigned char *)lpDIBBits lWidth 1;memset(pTemp, 0, lLength);pmidtemp (unsigned char *)pTemp lWidth 1; // 如果是边缘点 则将其设为1for(i 1; i lHeight -1; i) {for(j 1; j lWidth - 1; j){if( *pmid 0) //是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; // 这样周围8个都是1的时候 pmidtemp1 表明是边缘 }pmid;pmidtemp;}pmid;pmid;pmidtemp;pmidtemp;}//现在开始删除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) //1表明是边缘 0--周围8个都是1 即为中间点暂不予考虑{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; // 表明本次扫描进行了细化}pmid;pmidtemp;}pmid;pmid;pmidtemp;pmidtemp;}}delete []pTemp;return true;
}int main(int argc, char* argv[])
{IplImage* src cvLoadImage(E:\\study_opencv_video\\testthin\\char2.png,0);cvThreshold(src,src,100,255,CV_THRESH_BINARY);unsigned char* imagedata ;cvNamedWindow(s,0);cvShowImage(s , src);imagedata new uchar[sizeof(char)*src-width*src-height]();int x , y;for(y0;ysrc-height;y){unsigned char* ptr (unsigned char*)(src-imageData y*src-widthStep);for(x0;xsrc-width;x){imagedata[y*src-widthx] ptr[x] 0 ? 1 : 0;}}ThiningDIBSkeleton(imagedata,src-width,src-height);for(y0;ysrc-height;y){unsigned char* ptr (unsigned char*)(src-imageData y*src-widthStep);for(x0;xsrc-width;x){ptr[x] imagedata[y*src-width x]0? 255 : 0;}}cvNamedWindow(src,0);cvShowImage(src , src);cvWaitKey(0);delete []imagedata;return 0;
}// 转载https://blog.csdn.net/lu597203933/article/details/14397605