影醉阏轩窗

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

《图像处理实例》 之 疏密程度统计

 


 

疏密程度统计

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

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

 


 

说明:

   此方法是大佬给别的公司做的一个项目,本博文只对其进行方法说明!

目标:

   假设给定一个标准,圆与圆之间的密度为Value,当大于这个密度的时候就是不符合要求!

方法:

    1.填充每个圆形目标

    2.背景和前景做变换(把圆作为背景)

    3.对前景进行距离变换

    4.求局部最大值

    5.结合最大值位置和距离图对图像进行评估

 

运行步骤:

 

下面的红色圆代表物体之间的间隙,同时也代表疏密程度值!

 核心程序:

  1 //---fill black value
  2 int FillBlock(Mat src, Mat &mask, Point center)
  3 {
  4     uchar back = src.at<uchar>(center.y, center.x);
  5     vector<Point> fill_point;
  6     int count = 0, count_mount = 1;
  7     fill_point.push_back(center);
  8     while (count < count_mount)
  9     {
 10         vector<uchar*> img;
 11         vector<uchar*> msk;
 12         for (int i = -1; i < 2; i++)
 13         {
 14             img.push_back(src.ptr<uchar>(fill_point[count].y + i));
 15             msk.push_back(mask.ptr<uchar>(fill_point[count].y + i));
 16         }
 17         for (size_t i = 0; i < 3; i++)
 18         {
 19             for (int j = -1; j < 2; j++)
 20             {
 21                 if (img[i][fill_point[count].x + j] == back && !(j == 0 && i == 1) && msk[i][fill_point[count].x + j] == 255)
 22                 {
 23                     fill_point.push_back(Point(fill_point[count].x + j, fill_point[count].y + i - 1));
 24                     msk[i][fill_point[count].x + j] = 1;
 25                 }
 26             }
 27         }
 28         msk[1][fill_point[count].x] = 1;
 29         count_mount = fill_point.size() - 1;
 30         fill_point.erase(fill_point.begin());
 31     }
 32     return 0;
 33 }
 34 //---cal mask
 35 //---@_src        
 36 //---@mask        
 37 void MaskImage(InputArray _src, Mat &mask)
 38 {
 39     Mat src = _src.getMat(),mask_tmp = Mat::zeros(src.size(), CV_8UC1);
 40     mask_tmp.setTo(255);
 41     Mat rows = Mat::zeros(Size(src.cols, 1), CV_8UC1), cols = Mat::zeros(Size(1, src.rows), CV_8UC1);
 42     Mat src_rows_beg = mask_tmp.row(0);
 43     Mat src_rows_end = mask_tmp.row(src.rows - 1);
 44     Mat src_cols_beg = mask_tmp.col(0);
 45     Mat src_cols_end = mask_tmp.col(src.cols - 1);
 46     rows.copyTo(src_rows_beg); rows.copyTo(src_rows_end);
 47     cols.copyTo(src_cols_beg); cols.copyTo(src_cols_end);
 48     for (size_t i = 1; i < src.rows-1; i++)
 49     {
 50         uchar *img0 = src.ptr<uchar>(i - 1);
 51         uchar *img  = src.ptr<uchar>(i);
 52         uchar *img1 = src.ptr<uchar>(i + 1);
 53         uchar *msk  = mask_tmp.ptr<uchar>(i);    
 54         for (size_t j = 1; j < src.cols-1; j++)
 55         {
 56             bool flag = false;
 57             //msk[j] = img[j] == 0 ? 0 : msk[j];
 58             if (msk[j] != 255) continue;
 59             flag = (img[j] < img[j - 1] || img[j] < img[j + 1]
 60                 || img[j] < img0[j] || img[j] < img0[j - 1]
 61                 || img[j] < img0[j + 1] || img[j] < img1[j]
 62                 || img[j] < img1[j - 1] || img[j] < img1[j + 1])
 63                 ? true : false;
 64             int tmp = flag == true ? FillBlock(src, mask_tmp, Point(j, i)) : 0;
 65         }
 66     }
 67     mask = mask_tmp.clone();
 68 }
 69 //---filter parts max value
 70 //---@
 71 //---@
 72 //---@gap        
 73 //---@radius    
 74 
 75 vector<Point> Find_Max(InputArray _src, Mat&mask,int gap,int radius)
 76 {
 77     Mat src = _src.getMat();
 78     
 79     typedef struct MyStruct
 80     {
 81         Point position;
 82         float data;
 83     }MyStruct;
 84 
 85     MaskImage(src, mask);
 86     vector<MyStruct> max_point;
 87     for (size_t i = 0; i < src.rows; i++)
 88     {
 89         uchar *img = src.ptr<uchar>(i);
 90         uchar *msk = mask.ptr<uchar>(i);
 91         for (size_t j = 0; j < src.cols; j++)
 92         {
 93             if (msk[j] != 255) continue;
 94             MyStruct my_struct;
 95             my_struct.data = img[j];
 96             my_struct.position = Point(j, i);
 97             max_point.push_back(my_struct);
 98         }
 99     }
100     for (size_t i = 0; i < max_point.size(); i++)
101     {
102         for (size_t j = i; j < max_point.size(); j++)
103         {
104             MyStruct temp;
105             if (max_point[i].data <= max_point[j].data)
106             {
107                 if (max_point[j].data == 0) continue;
108                 temp = max_point[j];
109                 max_point[j] = max_point[i];
110                 max_point[i] = temp;
111             }
112         }
113     }
114     //---find max
115     for (size_t k = 0; k < max_point.size(); k++)//---
116     {
117         uchar back = src.at<uchar>(max_point[k].position.y, max_point[k].position.x);
118         vector<Point> fill_point;
119         int count = 0, count_mount = 1;
120         fill_point.push_back(max_point[k].position);
121         
122         while (count < count_mount &&  max_point[k].data != 1)
123         {
124             vector<uchar*> img;
125             vector<uchar*> msk;
126             for (int i = -1; i < 2; i++)
127             {
128                 img.push_back(src.ptr<uchar>(fill_point[count].y + i));
129                 msk.push_back(mask.ptr<uchar>(fill_point[count].y + i));
130             }
131             for (int i = 0; i < 3; i++)
132             {
133                 for (int j = -1; j < 2; j++)
134                 {
135                     //---
136                     uchar x = pow((max_point[k].position.x - fill_point[count].x + j), 2); //(max_point[k].position.x - img[i][fill_point[count].x + j])*(max_point[k].position.x - img[i][fill_point[count].x + j]);
137                     uchar y = pow((max_point[k].position.y - (fill_point[count].y + i - 1)) , 2); // (max_point[k].position.y - img[i][fill_point[count].y + j])*(max_point[k].position.y - img[i][fill_point[count].x + j]);
138                     uchar distance = sqrt(x + y);
139                     if (img[i][fill_point[count].x + j] <= img[1][fill_point[count].x] - gap 
140                         || msk[i][fill_point[count].x + j] == 3
141                         || msk[i][fill_point[count].x + j] == 0
142                         || (j == 0 && i == 1)
143                         || distance >= radius) continue;
144                     if (img[i][fill_point[count].x + j] == 2) max_point[k].data = 1;
145                     msk[i][fill_point[count].x + j] = 3;
146                     fill_point.push_back(Point(fill_point[count].x + j, fill_point[count].y + i - 1));
147                     count_mount++;
148                 }
149             }
150             count++;
151         }    
152         if (max_point[k].data == 1)
153         {
154             for (size_t i = 0; i < fill_point.size(); i++)
155             {
156                 mask.at<uchar>(fill_point[i]) = 1;
157             }
158         }
159         else
160         {
161             for (size_t i = 0; i < fill_point.size(); i++)
162             {
163                 mask.at<uchar>(fill_point[i]) = 2;
164             }
165             max_point[k].data = 255;
166             mask.at<uchar>(max_point[k].position) = 255;
167         }
168     }
169 }

 

posted on 2017-10-08 13:22  影醉阏轩窗  阅读(...)  评论(...编辑  收藏

导航

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