改进后的线条细化算法
原来每次遍历都是一整张图,现在每次都记录下需要操作的起始位置,下一次直接遍历起始位置就可以了。
原来的算法运行100次的时间为3.901秒
改进后的时间为0.148秒
代码如下:
1 //四周细化算法 2 void RefineNew(Mat& image, int num) 3 { 4 int p[8]; 5 int top = 1, down = 1, right = 1, left = 1; 6 vector<Point> del; 7 int grayvalue = 0; 8 bool state; 9 int height = image.rows; //获取图像高度 10 int width = image.cols; //获取图像宽度 11 vector<Point> run_up_down, run_lef_right; 12 Point next; //存放下一次的宽度或高度 13 //用于存放每一行需要处理图像的宽度 14 for (int i = 0; i < height; i++) 15 { 16 run_lef_right.push_back(Point(1, width - 1)); 17 } 18 //用于存放每一列需要处理图像的高度 19 for (int i = 0; i < width; i++) 20 { 21 run_up_down.push_back(Point(1, height - 1)); 22 } 23 24 Mat *im = reinterpret_cast<Mat*>((void*)&image); //获取像素点信息 25 for (int ite = 0; ite < num; ite++) 26 { 27 //上下收缩 28 for (int i = 1; i < width - 1; i++) 29 { 30 state = 1; 31 for (int j = run_up_down[i].x; j <run_up_down[i].y; j++) 32 { 33 grayvalue = Get_gray(im, i, j); //获取指定点灰度值 34 if (grayvalue != 0) //判断中心点是否为前景 35 { 36 if (state) 37 { 38 next.x = j; 39 next.y = j; 40 state = 0; 41 } 42 else 43 { 44 next.y = j; 45 } 46 p[0] = (Get_gray(im, i + 1, j) == 0) ? 0 : 1; 47 p[1] = (Get_gray(im, i + 1, j - 1) == 0) ? 0 : 1; 48 p[2] = (Get_gray(im, i, j - 1) == 0) ? 0 : 1; 49 p[3] = (Get_gray(im, i - 1, j - 1) == 0) ? 0 : 1; 50 p[4] = (Get_gray(im, i - 1, j) == 0) ? 0 : 1; 51 p[5] = (Get_gray(im, i - 1, j + 1) == 0) ? 0 : 1; 52 p[6] = (Get_gray(im, i, j + 1) == 0) ? 0 : 1; 53 p[7] = (Get_gray(im, i + 1, j + 1) == 0) ? 0 : 1; 54 if (j < height - 2) 55 down = (Get_gray(im, i, j + 2) == 0) ? 0 : 1; //判断下面第二格的状态 56 else 57 down = 1; 58 // 横向直线 59 if (p[6] && (p[5] || p[7] || p[0] || p[4]) && !(p[1] || p[3]) && p[2] == 0 && down) 60 { 61 del.push_back(Point(i, j)); 62 } 63 if (p[2] && (p[1] || p[3] || p[0] || p[4]) && !(p[5] || p[7]) && p[6] == 0) 64 { 65 del.push_back(Point(i, j)); 66 } 67 } 68 } 69 if (!state) 70 { 71 run_up_down[i].x = next.x; 72 run_up_down[i].y = next.y + 1; 73 } 74 else 75 { 76 run_up_down[i].x = 1; 77 run_up_down[i].y = 1; 78 } 79 } 80 81 for (int i = 1; i < height - 2; i++) 82 { 83 grayvalue = Get_gray(im, 0, i); 84 //最上边一行 85 if (grayvalue != 0) 86 { 87 if (Get_gray(im, 0, i - 1) && Get_gray(im, 1, i - 1) && Get_gray(im, 0, i + 1) == 0 && Get_gray(im, 1, i) == 0) //上2,上1,右上1,下1=0,右1=0 88 { 89 del.push_back(Point(0, i)); 90 } 91 if (Get_gray(im, 0, i - 1) == 0 && Get_gray(im, 1, i + 1) && Get_gray(im, 1, i) == 0 && Get_gray(im, 0, i + 2))//上1=0,下1,右下1,右1=0,下2 92 { 93 del.push_back(Point(0, i)); 94 } 95 } 96 //最下边一行 97 if (grayvalue != 0) 98 { 99 if (Get_gray(im, width - 1, i - 1) && Get_gray(im, width - 2, i - 1) && Get_gray(im, width - 1, i + 1) == 0 && Get_gray(im, width - 2, i) == 0) //上2,上1,左上1,下1=0,左1=0 100 { 101 del.push_back(Point(width - 1, i)); 102 } 103 if (Get_gray(im, width - 1, i - 1) == 0 && Get_gray(im, width - 2, i + 1) && Get_gray(im, width - 2, i) == 0 && Get_gray(im, width - 1, i + 2))//上1=0,下1,左下1,左1=0,下2 104 { 105 del.push_back(Point(width - 1, i)); 106 } 107 } 108 } 109 for (int i = 0; i < del.size(); i++) 110 { 111 uchar* data = image.ptr<uchar>(del[i].y); 112 data[del[i].x] = 0; 113 } 114 115 116 //左右收缩 117 for (int i = 1; i < height - 1; i++) 118 { 119 state = 1; 120 for (int j = run_lef_right[i].x; j <run_lef_right[i].y; j++) 121 { 122 grayvalue = Get_gray(im, j, i); //获取指定点灰度值 123 if (grayvalue != 0) //判断中心点是否为前景 124 { 125 if (state) 126 { 127 next.x = j; 128 next.y = j; 129 state = 0; 130 } 131 else 132 { 133 next.y = j; 134 } 135 p[0] = (Get_gray(im, j + 1, i) == 0) ? 0 : 1; 136 p[1] = (Get_gray(im, j + 1, i - 1) == 0) ? 0 : 1; 137 p[2] = (Get_gray(im, j, i - 1) == 0) ? 0 : 1; 138 p[3] = (Get_gray(im, j - 1, i - 1) == 0) ? 0 : 1; 139 p[4] = (Get_gray(im, j - 1, i) == 0) ? 0 : 1; 140 p[5] = (Get_gray(im, j - 1, i + 1) == 0) ? 0 : 1; 141 p[6] = (Get_gray(im, j, i + 1) == 0) ? 0 : 1; 142 p[7] = (Get_gray(im, j + 1, i + 1) == 0) ? 0 : 1; 143 if (j < width - 2) 144 right = (Get_gray(im, j + 2, i) == 0) ? 0 : 1; //判断右边第二格的状态 145 else 146 right = 1; 147 //竖直线 148 if (p[0] && (p[1] || p[7] || p[2] || p[6]) && !(p[3] || p[5]) && p[4] == 0 && right) 149 { 150 del.push_back(Point(j, i)); 151 } 152 if (p[4] && (p[3] || p[5] || p[2] || p[6]) && !(p[1] || p[7]) && p[0] == 0) 153 { 154 del.push_back(Point(j, i)); 155 } 156 157 } 158 } 159 if (!state) 160 { 161 run_lef_right[i].x = next.x; 162 run_lef_right[i].y = next.y + 1; 163 } 164 else 165 { 166 run_lef_right[i].x = 1; 167 run_lef_right[i].y = 1; 168 } 169 170 } 171 172 //最左边一列 173 for (int j = 1; j < width - 2; j++) 174 { 175 grayvalue = Get_gray(im, j, 0); 176 if (grayvalue != 0) 177 { 178 if (Get_gray(im, j - 1, 0) == 0 && Get_gray(im, j + 1, 0) && Get_gray(im, j + 2, 0) && Get_gray(im, j, 1) == 0 && Get_gray(im, j + 1, 1)) //左1=0,右1,右2,下1=0,右下1 179 { 180 del.push_back(Point(j, 0)); 181 } 182 if (Get_gray(im, j - 1, 0) && Get_gray(im, j + 1, 0) == 0 && Get_gray(im, j, 1) == 0 && Get_gray(im, j - 1, 1))//左1,右1=0,下1=0,左下1 183 { 184 del.push_back(Point(j, 0)); 185 } 186 } 187 } 188 //最右边一列 189 for (int j = 1; j < width - 2; j++) 190 { 191 grayvalue = Get_gray(im, j, height - 1); 192 if (grayvalue != 0) 193 { 194 if (Get_gray(im, j - 1, height - 1) == 0 && Get_gray(im, j + 1, height - 1) && Get_gray(im, j + 2, height - 1) && Get_gray(im, j, height - 2) == 0 && Get_gray(im, j + 1, height - 2)) //左1=0,右1,右2,下1=0,右下1 195 { 196 del.push_back(Point(j, height - 1)); 197 } 198 if (Get_gray(im, j - 1, height - 1) && Get_gray(im, j + 1, height - 1) == 0 && Get_gray(im, j, height - 2) == 0 && Get_gray(im, j - 1, height - 2))//左1,右1=0,下1=0,左下1 199 { 200 del.push_back(Point(j, height - 1)); 201 } 202 } 203 } 204 for (int i = 0; i < del.size(); i++) 205 { 206 uchar* data = image.ptr<uchar>(del[i].y); 207 data[del[i].x] = 0; 208 } 209 210 } 211 212 213 }