在我们进行图像处理的时候,有可能需要对图像进行细化,提取出图像的骨架信息,进行更加有效的分析。
图像细化(Image Thinning),一般指二值图像的骨架化(Image Skeletonization) 的一种操作运算。
所谓的细化就是经过一层层的剥离,从原来的图中去掉一些点,但仍要保持原来的形状,直到得到图像的骨架。骨架,可以理解为图象的中轴。
好的细化算法一定要满足:
- 收敛性;
- 保证细化后细线的连通性;
- 保持原图的基本形状;
- 减少笔画相交处的畸变;
- 细化结果是原图像的中心线;
- 细化的快速性和迭代次数少;
--------------------- 本文来自 i_wooden 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qianchenglenger/article/details/19332011?utm_source=copy
1 void chao_thinimage(Mat &srcimage)//单通道、二值化后的图像 2 { 3 vector<Point> deletelist1; 4 int Zhangmude[9]; 5 int nl = srcimage.rows; 6 int nc = srcimage.cols; 7 while (true) 8 { 9 for (int j = 1; j < (nl - 1); j++) 10 { 11 uchar* data_last = srcimage.ptr<uchar>(j - 1); 12 uchar* data = srcimage.ptr<uchar>(j); 13 uchar* data_next = srcimage.ptr<uchar>(j + 1); 14 for (int i = 1; i < (nc - 1); i++) 15 { 16 if (data[i] == 255) 17 { 18 Zhangmude[0] = 1; 19 if (data_last[i] == 255) Zhangmude[1] = 1; 20 else Zhangmude[1] = 0; 21 if (data_last[i + 1] == 255) Zhangmude[2] = 1; 22 else Zhangmude[2] = 0; 23 if (data[i + 1] == 255) Zhangmude[3] = 1; 24 else Zhangmude[3] = 0; 25 if (data_next[i + 1] == 255) Zhangmude[4] = 1; 26 else Zhangmude[4] = 0; 27 if (data_next[i] == 255) Zhangmude[5] = 1; 28 else Zhangmude[5] = 0; 29 if (data_next[i - 1] == 255) Zhangmude[6] = 1; 30 else Zhangmude[6] = 0; 31 if (data[i - 1] == 255) Zhangmude[7] = 1; 32 else Zhangmude[7] = 0; 33 if (data_last[i - 1] == 255) Zhangmude[8] = 1; 34 else Zhangmude[8] = 0; 35 int whitepointtotal = 0; 36 for (int k = 1; k < 9; k++) 37 { 38 whitepointtotal = whitepointtotal + Zhangmude[k]; 39 } 40 if ((whitepointtotal >= 2) && (whitepointtotal <= 6)) 41 { 42 int ap = 0; 43 if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++; 44 if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++; 45 if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++; 46 if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++; 47 if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++; 48 if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++; 49 if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++; 50 if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++; 51 if (ap == 1) 52 { 53 if ((Zhangmude[1] * Zhangmude[7] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[5] * Zhangmude[7] == 0)) 54 { 55 deletelist1.push_back(Point(i, j)); 56 } 57 } 58 } 59 } 60 } 61 } 62 if (deletelist1.size() == 0) break; 63 for (size_t i = 0; i < deletelist1.size(); i++) 64 { 65 Point tem; 66 tem = deletelist1[i]; 67 uchar* data = srcimage.ptr<uchar>(tem.y); 68 data[tem.x] = 0; 69 } 70 deletelist1.clear(); 71 72 for (int j = 1; j < (nl - 1); j++) 73 { 74 uchar* data_last = srcimage.ptr<uchar>(j - 1); 75 uchar* data = srcimage.ptr<uchar>(j); 76 uchar* data_next = srcimage.ptr<uchar>(j + 1); 77 for (int i = 1; i < (nc - 1); i++) 78 { 79 if (data[i] == 255) 80 { 81 Zhangmude[0] = 1; 82 if (data_last[i] == 255) Zhangmude[1] = 1; 83 else Zhangmude[1] = 0; 84 if (data_last[i + 1] == 255) Zhangmude[2] = 1; 85 else Zhangmude[2] = 0; 86 if (data[i + 1] == 255) Zhangmude[3] = 1; 87 else Zhangmude[3] = 0; 88 if (data_next[i + 1] == 255) Zhangmude[4] = 1; 89 else Zhangmude[4] = 0; 90 if (data_next[i] == 255) Zhangmude[5] = 1; 91 else Zhangmude[5] = 0; 92 if (data_next[i - 1] == 255) Zhangmude[6] = 1; 93 else Zhangmude[6] = 0; 94 if (data[i - 1] == 255) Zhangmude[7] = 1; 95 else Zhangmude[7] = 0; 96 if (data_last[i - 1] == 255) Zhangmude[8] = 1; 97 else Zhangmude[8] = 0; 98 int whitepointtotal = 0; 99 for (int k = 1; k < 9; k++) 100 { 101 whitepointtotal = whitepointtotal + Zhangmude[k]; 102 } 103 if ((whitepointtotal >= 2) && (whitepointtotal <= 6)) 104 { 105 int ap = 0; 106 if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++; 107 if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++; 108 if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++; 109 if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++; 110 if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++; 111 if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++; 112 if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++; 113 if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++; 114 if (ap == 1) 115 { 116 if ((Zhangmude[1] * Zhangmude[3] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[1] * Zhangmude[7] == 0)) 117 { 118 deletelist1.push_back(Point(i, j)); 119 } 120 } 121 } 122 } 123 } 124 } 125 if (deletelist1.size() == 0) break; 126 for (size_t i = 0; i < deletelist1.size(); i++) 127 { 128 Point tem; 129 tem = deletelist1[i]; 130 uchar* data = srcimage.ptr<uchar>(tem.y); 131 data[tem.x] = 0; 132 } 133 deletelist1.clear(); 134 } 135 }