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

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

假设给定一个标准，圆与圆之间的密度为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));
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 }
35 //---@_src
38 {
39     Mat src = _src.getMat(),mask_tmp = Mat::zeros(src.size(), CV_8UC1);
41     Mat rows = Mat::zeros(Size(src.cols, 1), CV_8UC1), cols = Mat::zeros(Size(1, src.rows), CV_8UC1);
43     Mat src_rows_end = mask_tmp.row(src.rows - 1);
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);
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     }
68 }
69 //---filter parts max value
70 //---@
71 //---@
72 //---@gap
74
76 {
77     Mat src = _src.getMat();
78
79     typedef struct MyStruct
80     {
81         Point position;
82         float data;
83     }MyStruct;
84
86     vector<MyStruct> max_point;
87     for (size_t i = 0; i < src.rows; i++)
88     {
89         uchar *img = src.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));
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             {
157             }
158         }
159         else
160         {
161             for (size_t i = 0; i < fill_point.size(); i++)
162             {
164             }
165             max_point[k].data = 255;
169 }