c++opencv中线条细化算法

 要达到的效果就是将线条尽量细化成单像素,按照论文上的Hilditch算法试了一下,发现效果不好,于是自己尝试着写了一下细化的算法,基本原理就是从上下左右四个方向向内收缩。

1.先是根据图片中的原则确定了以下16种情况

2.调试过后发现,迭代次数多了之后,原来连接着的线条会断开,分析原因如下图

3.修改了一下判断条件

4.调试过后发现还是会出现断的地方,再次分析原因如下图

5.又加了判断条件,如下图

最终实现的效果如下

 

对比图

对规则曲线的效果比较好

但是圆的效果不太好,有待改进

 

附上代码,测试了一天,终于弄完了,啊哈哈哈!然而后面还有更艰苦的路要走。加油!!!

  1 //四周细化算法
  2 void Refine(Mat& image)
  3 {
  4     int p[8];
  5     int top=1, down=1, right=1, left=1;
  6     vector<Point> del;
  7     int grayvalue = 0;
  8     int height = image.rows;   //获取图像高度
  9     int width = image.cols;       //获取图像宽度
 10     Mat *im = reinterpret_cast<Mat*>((void*)&image);    //获取像素点信息
 11     //上下收缩
 12     for (int i = 1; i < height-1; i++)
 13     {
 14         for (int j = 1; j < width-1; j++)
 15         {
 16             grayvalue = Get_gray(im, j, i);  //获取指定点灰度值
 17             if (grayvalue != 0)   //判断中心点是否为前景
 18             {
 19                 p[0] = (Get_gray(im, j + 1, i) == 0) ? 0 : 1;
 20                 p[1] = (Get_gray(im, j + 1, i - 1) == 0) ? 0 : 1;
 21                 p[2] = (Get_gray(im, j, i - 1) == 0) ? 0 : 1;
 22                 p[3] = (Get_gray(im, j - 1, i - 1) == 0) ? 0 : 1;
 23                 p[4] = (Get_gray(im, j - 1, i) == 0) ? 0 : 1;
 24                 p[5] = (Get_gray(im, j - 1, i + 1) == 0) ? 0 : 1;
 25                 p[6] = (Get_gray(im, j, i + 1) == 0) ? 0 : 1;
 26                 p[7] = (Get_gray(im, j + 1, i + 1) == 0) ? 0 : 1;
 27                 if (i < height - 2)
 28                     down = (Get_gray(im, j, i + 2) == 0) ? 0 : 1;
 29                 else
 30                     down = 1;
 31                 //  横向直线
 32                 if (p[6] && (p[5] || p[7] || p[0] || p[4]) && !(p[1] || p[3]) && p[2] == 0 && down)
 33                 {
 34                     del.push_back(Point(j, i));
 35                 }
 36                 if (p[2] && (p[1] || p[3] || p[0] || p[4]) && !( p[5] || p[7]) && p[6] == 0)
 37                 {
 38                     del.push_back(Point(j, i));
 39                 }
 40             }
 41         }
 42     }
 43 
 44     for (int i = 1; i < height - 2; i++)
 45     {
 46         grayvalue = Get_gray(im, 0, i);
 47         if (grayvalue != 0)
 48         {
 49             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
 50             {
 51                 del.push_back(Point(0, i));
 52             }
 53             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
 54             {
 55                 del.push_back(Point(0, i));
 56             }
 57         }
 58         if (grayvalue != 0)
 59         {
 60             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
 61             {
 62                 del.push_back(Point(width - 1, i));
 63             }
 64             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
 65             {
 66                 del.push_back(Point(width - 1, i));
 67             }
 68         }
 69     }
 70     for (int i = 0; i < del.size();i++)
 71     {
 72         uchar* data = image.ptr<uchar>(del[i].y);
 73         data[del[i].x]=0;
 74     }
 75 
 76     //左右收缩
 77     for (int i = 1; i < height - 1; i++)
 78     {
 79         for (int j = 1; j < width - 1; j++)
 80         {
 81             grayvalue = Get_gray(im, j, i);  //获取指定点灰度值
 82             if (grayvalue != 0)   //判断中心点是否为前景
 83             {
 84                 p[0] = (Get_gray(im, j + 1, i) == 0) ? 0 : 1;
 85                 p[1] = (Get_gray(im, j + 1, i - 1) == 0) ? 0 : 1;
 86                 p[2] = (Get_gray(im, j, i - 1) == 0) ? 0 : 1;
 87                 p[3] = (Get_gray(im, j - 1, i - 1) == 0) ? 0 : 1;
 88                 p[4] = (Get_gray(im, j - 1, i) == 0) ? 0 : 1;
 89                 p[5] = (Get_gray(im, j - 1, i + 1) == 0) ? 0 : 1;
 90                 p[6] = (Get_gray(im, j, i + 1) == 0) ? 0 : 1;
 91                 p[7] = (Get_gray(im, j + 1, i + 1) == 0) ? 0 : 1;
 92                 if (j < width - 2)
 93                     right = (Get_gray(im, j + 2, i) == 0) ? 0 : 1;
 94                 else
 95                     right = 1;
 96 
 97                 
 98                 //竖直线
 99                 if (p[0] && (p[1] || p[7] || p[2] || p[6]) && !(p[3] || p[5]) && p[4] == 0 && right)
100                 {
101                     del.push_back(Point(j, i));
102                 }
103                 if (p[4] && (p[3] || p[5] || p[2] || p[6]) && !(p[1] || p[7]) && p[0] == 0)
104                 {
105                     del.push_back(Point(j, i));
106                 }
107 
108             }
109         }
110     }
111 
112     for (int j = 1; j < width - 2; j++)
113     {
114         grayvalue = Get_gray(im, j, 0);
115         if (grayvalue != 0)
116         {
117             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
118             {
119                 del.push_back(Point(j, 0));
120             }
121             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
122             {
123                 del.push_back(Point(j, 0));
124             }
125         }
126     }
127     for (int j = 1; j < width - 2; j++)
128     {
129         grayvalue = Get_gray(im, j, height-1);
130         if (grayvalue != 0)
131         {
132             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
133             {
134                 del.push_back(Point(j, height - 1));
135             }
136             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
137             {
138                 del.push_back(Point(j, height - 1));
139             }
140         }
141     }
142 
143     for (int i = 0; i < del.size(); i++)
144     {
145         uchar* data = image.ptr<uchar>(del[i].y);
146         data[del[i].x] = 0;
147     }
148 }

 

posted @ 2018-01-14 22:15  夏日已末  阅读(7131)  评论(6编辑  收藏  举报