Opencv处理图像--细化

秒速五厘米 2022-05-17 05:38 536阅读 0赞

Opencv处理图像—细化

细化的算法有很多种,但比较常用的算法是查表法

细化是从原来的图中去掉一些点,但仍要保持原来的形状。

实际上是保持原图的骨架。

代码如上:

  1. #include<iostream>
  2. #include<opencv2/core/core.hpp>
  3. #include<opencv2/highgui/highgui.hpp>
  4. IplImage* ColorSrc ,*ColorSrcCopy;
  5. //#define SHOW
  6. //#define LONG int
  7. //#define BYTE unsigned char
  8. /
  9. //基于索引表的细化细化算法
  10. //功能:对图象进行细化
  11. //参数:lpDIBBits:代表图象的一维数组
  12. // lWidth:图象高度
  13. // lHeight:图象宽度
  14. // 无返回值
  15. bool ThiningDIBSkeleton (unsigned char* lpDIBBits, int lWidth, int lHeight)
  16. {
  17. //循环变量
  18. long i;
  19. long j;
  20. long lLength;
  21. unsigned char deletemark[256] = {
  22. 0,0,0,0,0,0,0,1, 0,0,1,1,0,0,1,1,
  23. 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,1,
  24. 0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,
  25. 0,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,
  26. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  27. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  28. 0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,
  29. 1,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,
  30. 0,0,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,
  31. 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,1,1,
  32. 1,1,0,1,0,0,0,1, 0,0,0,0,0,0,0,0,
  33. 1,1,0,1,0,0,0,1, 1,1,0,0,1,0,0,0,
  34. 0,1,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,
  35. 0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,1,
  36. 1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0,
  37. 1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0
  38. };//索引表
  39. unsigned char p0, p1, p2, p3, p4, p5, p6, p7;
  40. unsigned char *pmid, *pmidtemp;
  41. unsigned char sum;
  42. int changed;
  43. bool bStart = true;
  44. lLength = lWidth * lHeight;
  45. unsigned char *pTemp = (unsigned char *)malloc(sizeof(unsigned char) * lWidth * lHeight);
  46. // P0 P1 P2
  47. // P7 P3
  48. // P6 P5 P4
  49. while(bStart)
  50. {
  51. bStart = false;
  52. changed = 0;
  53. //首先求边缘点(并行)
  54. pmid = (unsigned char *)lpDIBBits + lWidth + 1;
  55. memset(pTemp, 0, lLength);
  56. pmidtemp = (unsigned char *)pTemp + lWidth + 1;
  57. for(i = 1; i < lHeight -1; i++)
  58. {
  59. for(j = 1; j < lWidth - 1; j++)
  60. {
  61. if( *pmid == 0)
  62. {
  63. pmid++;
  64. pmidtemp++;
  65. continue;
  66. }
  67. p3 = *(pmid + 1);
  68. p2 = *(pmid + 1 - lWidth);
  69. p1 = *(pmid - lWidth);
  70. p0 = *(pmid - lWidth -1);
  71. p7 = *(pmid - 1);
  72. p6 = *(pmid + lWidth - 1);
  73. p5 = *(pmid + lWidth);
  74. p4 = *(pmid + lWidth + 1);
  75. sum = p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7;
  76. if(sum == 0)
  77. {
  78. *pmidtemp = 1;
  79. #ifdef SHOW
  80. cvSet2D(ColorSrc,i,j,cvScalar(0,0,255));
  81. #endif
  82. }
  83. pmid++;
  84. pmidtemp++;
  85. }
  86. pmid++;
  87. pmid++;
  88. pmidtemp++;
  89. pmidtemp++;
  90. }
  91. #ifdef SHOW
  92. cvNamedWindow("color");
  93. cvShowImage("color",ColorSrc);
  94. cvWaitKey(0);
  95. #endif
  96. //现在开始串行删除
  97. pmid = (unsigned char *)lpDIBBits + lWidth + 1;
  98. pmidtemp = (unsigned char *)pTemp + lWidth + 1;
  99. for(i = 1; i < lHeight -1; i++)
  100. {
  101. for(j = 1; j < lWidth - 1; j++)
  102. {
  103. if( *pmidtemp == 0)
  104. {
  105. pmid++;
  106. pmidtemp++;
  107. continue;
  108. }
  109. p3 = *(pmid + 1);
  110. p2 = *(pmid + 1 - lWidth);
  111. p1 = *(pmid - lWidth);
  112. p0 = *(pmid - lWidth -1);
  113. p7 = *(pmid - 1);
  114. p6 = *(pmid + lWidth - 1);
  115. p5 = *(pmid + lWidth);
  116. p4 = *(pmid + lWidth + 1);
  117. p1 *= 2;
  118. p2 *= 4;
  119. p3 *= 8;
  120. p4 *= 16;
  121. p5 *= 32;
  122. p6 *= 64;
  123. p7 *= 128;
  124. sum = p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7;
  125. // sum = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
  126. if(deletemark[sum] == 1)
  127. {
  128. *pmid = 0;
  129. bStart = true;
  130. #ifdef SHOW
  131. cvSet2D(ColorSrc,i,j,cvScalar(0,0,0));
  132. cvNamedWindow("delcolor");
  133. cvShowImage("delcolor",ColorSrc);
  134. cvWaitKey(2);
  135. #endif
  136. }
  137. pmid++;
  138. pmidtemp++;
  139. }
  140. pmid++;
  141. pmid++;
  142. pmidtemp++;
  143. pmidtemp++;
  144. }
  145. #ifdef SHOW
  146. printf("过了一圈\n");
  147. #endif
  148. }
  149. return true;
  150. }
  151. int main()
  152. {
  153. //#define WRITERESULT
  154. //#define WRITEIMAGE
  155. IplImage* src = cvLoadImage("char2.png",0); //加载图像并灰度化
  156. cvThreshold(src,src,100,255,CV_THRESH_BINARY); //二值化图像
  157. unsigned char* imagedata ;
  158. ColorSrc = cvLoadImage("char2.png",1);
  159. cvNamedWindow("s");
  160. cvShowImage("s" , src);
  161. FILE* fp ;
  162. #ifdef WRITEIMAGE
  163. fp = fopen("data255.txt","rt+");
  164. #endif
  165. imagedata = (unsigned char*)malloc(sizeof(char)*src->width*src->height); //动态分配内存
  166. int x , y;
  167. for(y=0;y<src->height;y++)
  168. {
  169. unsigned char* ptr = (unsigned char*)(src->imageData + y*src->widthStep);
  170. for(x=0;x<src->width;x++)
  171. {
  172. imagedata[y*src->width+x] = ptr[x] > 0 ? 1 : 0;
  173. #ifdef WRITEIMAGE
  174. if(ptr[x] > 0)
  175. fprintf(fp,"1");
  176. else
  177. {
  178. fprintf(fp,"0");
  179. }
  180. #endif
  181. }
  182. #ifdef WRITEIMAGE
  183. fprintf(fp,"\n");
  184. #endif
  185. }
  186. #ifdef WRITEIMAGE
  187. fclose(fp);
  188. #endif
  189. #ifdef WRITERESULT
  190. fp = fopen("result.txt","rt+");
  191. #endif
  192. ThiningDIBSkeleton(imagedata,src->width,src->height);//进行细化操作
  193. for(y=0;y<src->height;y++)
  194. {
  195. unsigned char* ptr = (unsigned char*)(src->imageData + y*src->widthStep);
  196. for(x=0;x<src->width;x++)
  197. {
  198. ptr[x] = imagedata[y*src->width + x]>0? 255 : 0;
  199. #ifdef WRITERESULT
  200. if(ptr[x] > 0)
  201. fprintf(fp,"1");
  202. else
  203. {
  204. fprintf(fp,"0");
  205. }
  206. #endif
  207. }
  208. #ifdef WRITERESULT
  209. fprintf(fp,"\n");
  210. #endif
  211. }
  212. #ifdef WRITERESULT
  213. fclose(fp);
  214. #endif
  215. cvNamedWindow("src");
  216. cvShowImage("src" , src);
  217. cvWaitKey(0);
  218. cvReleaseImage(&src);
  219. cvReleaseImage(&ColorSrc);
  220. free(imagedata);
  221. return 0;
  222. }

7070 1 细化前后对比

博客参考https://www.cnblogs.com/zhazhiqiang/p/4487950.html

发表评论

表情:
评论列表 (有 0 条评论,536人围观)

还没有评论,来说两句吧...

相关阅读

    相关 opencv实现图像细化效果

    在图像处理中,有时候我们会想要提取图像的骨架,这是就需要对图像进行细化,opencv中没有直接进行细化的算法,网上大部分的细化算法都是基于以前IplImage结构的,对于想要使

    相关 Opencv处理图像--细化

    Opencv处理图像--细化 细化的算法有很多种,但比较常用的算法是查表法 细化是从原来的图中去掉一些点,但仍要保持原来的形状。 实际上是保持原图的骨架。 代码如上