zoukankan      html  css  js  c++  java
  • 《图像处理实例》 之 二值图像分割


    二值图像分割

    以下的改进是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 }
  • 相关阅读:
    4. Object
    3. string
    8. 滚动条美化
    7. 单位,移动布局
    2. js的异步
    2. 即时通讯
    让PHP更快的提供文件下载
    phpstorm+xdebug远程调试设置
    postman自动生成签名
    一位技术人员成长历程
  • 原文地址:https://www.cnblogs.com/wjy-lulu/p/7664941.html
Copyright © 2011-2022 走看看