影醉阏轩窗

衣带渐宽终不悔,为伊消得人憔悴。
扩大
缩小

《图像处理实例》 之 二值图像分割

 


 

二值图像分割

以下的改进是http://www.imagepy.org/的作者原创,我只是对其理解之后改进和说明,欢迎大家使用这个小软件!

如有朋友需要源工程,请在评论处留邮箱!


 

 

原理:给定最大值处的种子点,然后进行涨水,各个种子点进行碰撞

 

  1 void Binary_Division(InputArray& _src, Mat& mask, vector<Point> Edge_Point)
  2 {
  3     Mat src = _src.getMat();// , mask = _mask.getMat();
  4                 
  5     mask = src.clone();
  6     distanceTransform(src, src, DIST_L2, DIST_MASK_3, 5);
  7     normalize(src, src, 0, 255, NORM_MINMAX);
  8     src.convertTo(src, CV_8UC1);
  9     
 10     vector<vector<Point>> Edge_Data;
 11     for (size_t i = 0; i < Edge_Point.size(); i++)
 12     {
 13         vector<Point> temp;
 14         temp.push_back(Edge_Point[i]);
 15         Edge_Data.push_back(temp);
 16         mask.at<uchar>(Edge_Point[i]) = i + 1;
 17     }
 18     
 19     const int histSize = 255;
 20     float range[] = { 0, 255 };
 21     const float* histRange = { range };
 22     Mat hist;
 23     calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false);
 24 
 25     
 26     hist = hist.reshape(1, 1);
 27     normalize(hist, hist, 0, 1000, NORM_MINMAX);
 28     hist.convertTo(hist, CV_32FC1);
 29     for (size_t level = 255; level > 0; level--)
 30     {
 31         if (!hist.at<float>(0, level)) continue;
 32         FindRidge(src, mask, Edge_Data, level);
 33     }
 34 }
 35 
 36 void FindRidge(InputArray& _src, Mat& mask, vector<vector<Point>>& Edge_Point,int level)
 37 {
 38     Mat src = _src.getMat();
 39     for (size_t i = 0; i < Edge_Point.size(); i++)
 40     {
 41         uchar pre_mark = i + 1;
 42         for (int j = 0; j < Edge_Point[i].size(); j++)
 43         {
 44             vector<Point> temp_vector;
 45             temp_vector.push_back(Point(Edge_Point[i][j].x, Edge_Point[i][j].y - 1));
 46             temp_vector.push_back(Point(Edge_Point[i][j].x, Edge_Point[i][j].y + 1));
 47             temp_vector.push_back(Point(Edge_Point[i][j].x - 1, Edge_Point[i][j].y));
 48             temp_vector.push_back(Point(Edge_Point[i][j].x + 1, Edge_Point[i][j].y));
 49             uchar* msk = mask.ptr(Edge_Point[i][j].y);
 50             uchar* img = src.ptr(Edge_Point[i][j].y);
 51             if (img[Edge_Point[i][j].x] < level)    continue;
 52             if (msk[j] == 254)
 53             {
 54                 Edge_Point[i].erase(Edge_Point[i].begin() + j);
 55                 j--;
 56                 continue;
 57             }
 58             bool Flag = true;
 59             for (size_t j = 0; j < temp_vector.size(); j++)
 60             {
 61                 uchar* pre_data = mask.ptr(temp_vector[j].y);
 62                 if (pre_data[temp_vector[j].x] != pre_mark && pre_data[temp_vector[j].x] != 0 
 63                     && pre_data[temp_vector[j].x] != 255 && pre_data[temp_vector[j].x] != (150+i+1)
 64                     && pre_data[temp_vector[j].x] != 254)
 65                 {
 66                     pre_data[temp_vector[j].x] = 254;
 67                     continue;
 68                 }
 69                 else if (pre_data[temp_vector[j].x] == 0 || pre_data[temp_vector[j].x] == pre_mark || pre_data[temp_vector[j].x] == 254) continue;            
 70                 else if (pre_data[temp_vector[j].x] == 255)
 71                 {
 72                     if (src.at<uchar>(temp_vector[j]) <= level)
 73                     {
 74                         pre_data[temp_vector[j].x] = pre_mark;
 75                         Edge_Point[i].push_back(temp_vector[j]);
 76                         //Edge_Point[i].insert(Edge_Point[i].begin() + j + 1, temp_vector[j]);
 77                     }
 78                     else
 79                     {
 80                         FillBlock(src, Edge_Point[i], mask, level, Edge_Point[i][j], i);
 81                         Flag = false;
 82                     }
 83                 }
 84             }
 85             if (Flag)
 86             {
 87                 mask.at<uchar>(Edge_Point[i][j]) = 150 + i + 1;
 88                 Edge_Point[i].erase(Edge_Point[i].begin() + j);
 89                 j--;
 90             }
 91             else
 92             {
 93                 mask.at<uchar>(Edge_Point[i][j]) = i + 1;
 94             }
 95         }
 96     }
 97 }
 98 
 99 void FillBlock(InputArray& _src, vector<Point>& Edge_Point, Mat& mask, int level, Point center,int seed_num)
100 {
101     Mat src = _src.getMat();
102     mask.at<uchar>(center) = seed_num + 151;
103     vector<Point> fill_point;
104     int count = 0, count_mount = 1;//count;
105     fill_point.push_back(center);
106     while (count < count_mount)
107     {
108         vector<uchar*> img;
109         vector<uchar*> msk;
110         for (int i = -1; i < 2; i++)
111         {
112             img.push_back(src.ptr<uchar>(fill_point[count].y + i));
113             msk.push_back(mask.ptr<uchar>(fill_point[count].y + i));
114         }
115         for (size_t i = 0; i < 3; i++)
116         {
117             for (int j = -1; j < 2; j++)
118             {
119                 if (img[i][fill_point[count].x + j] > level && !(j == 0 && i == 1) && msk[i][fill_point[count].x + j] == 255)
120                 {
121                     fill_point.push_back(Point(fill_point[count].x + j, fill_point[count].y + i - 1));
122                     msk[i][fill_point[count].x + j] = seed_num + 151;
123                 }
124                 else if (img[i][fill_point[count].x + j] <= level && msk[i][fill_point[count].x + j] == 255)
125                 {
126                     Edge_Point.push_back(Point(fill_point[count].x + j, fill_point[count].y + i - 1));
127                     msk[i][fill_point[count].x + j] = seed_num + 1;
128                 }
129             }
130         }
131         //msk[1][fill_point[count].x] = 2;
132         count_mount = fill_point.size() - 1;
133         fill_point.erase(fill_point.begin());
134     }
135 }

 

posted on 2017-10-14 05:39  影醉阏轩窗  阅读(3212)  评论(9编辑  收藏  举报

导航

/* 线条鼠标集合 */ /* 鼠标点击求赞文字特效 */ //带头像评论