节选自论文:高斯加权的二维灰度重心法提取光条中心
只能实现粗略的光条提取,后续借助初始提取的光条中心以及所求出的宽度,配合加权灰度重心法进行进一步的提取。
笔者水平有限,希望读者可以进行批评指正。
代码如下
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2\imgproc\types_c.h>
#include <vector>
#include <deque>
#include <algorithm>
using namespace cv;
using std::vector;
using namespace std;
//
void GNA(Mat src, int i) {
Mat srcimg;
srcimg = src;
Mat grayimg;
cvtColor(srcimg, grayimg, CV_BGR2GRAY);
float epsilon = 0.0;
//traverse each column
int x = 0;//用于计算行坐标
Mat a7 = (Mat_<float>(1, 7) << 1.0, 1.0, 2.0, 4.0, 2.0, 1.0, 1.0);
vector<int> width;//记录每一列的宽度
float width_jj=0;//记录上一列的宽度
for (int i = 0; i < grayimg.cols; i++) {
float sum_value = 0;
float sum_valuecoor = 0;
vector<float>current_coordinat;
vector<float> Aij0;
//创建一个矩阵,用于计算A(i,j)
cv::Mat temp = (Mat_<float>(7,1)<<0,0,0,0,0,0,0);
int num = 0;
deque<float> temp_d;
int width_j = 0;//记录某一列的宽度
for (int j = 0; j < grayimg.rows; j++) {
float current = grayimg.at<uchar>(j, i);
//temp = cv::Mat_<float>(7, 1) << current;
temp_d.push_back(current);
num++;
if (num == 7)
{
num = num-1;
for (int i = 0; i < 7; i++)
{
temp.at<float>(i,0) = temp_d.at(i);
}
if (temp_d.empty())
{
cout << "deque wrong!" << endl;
return;
}
//容器弹出第一个数
temp_d.pop_front();
Mat Aij = a7 * temp;
if (Aij.at<float>(0,0) >= epsilon)
{
Aij0.push_back(Aij.at<float>(0, 0));
width_jj = width_j;
width_j++;
current_coordinat.push_back(j);
}
}
}
//判断是否断裂
if (width_j == 0)
{
width_j = width_jj;
}
width.push_back(width_j);
//求Aij0的最大值
//auto max_Position = std::max_element(Aij0.begin(), Aij0.end());
if (!current_coordinat.empty())
{
float max_A = 0;
int P = 0;
for (int k = 0; k < Aij0.size(); k++)
{
if (Aij0[k] >= max_A)
{
max_A = Aij0[k];
P = k;
}
}
x = current_coordinat[P];
circle(srcimg, Point(i, x), 1, Scalar(0, 0, 255), -1, 8);
}
current_coordinat.clear();
Aij0.clear();
}
//namedWindow("gscog", 0);
//resizeWindow("gscog", 800, 600);
imshow("gscog", srcimg);
//string save_path = "E:\\Light_strip_treatment\\extraction\\gray_centroid\\" + to_string(i) + ".bmp";
//cout << save_path << endl;
//imwrite(save_path, srcimg);
waitKey(10);
}
int main() {
// 相对对路径
string path = "E:\\Light_strip_treatment\\threshold\\*.bmp";
cout << path << endl;
vector<Mat> images;
vector<String> fn;
glob(path, fn, false);
cout << fn.size() << endl;
size_t count = fn.size();
cout << count << endl;
for (int i = 0; i < count; i++) {
images.push_back(imread(fn[i]));
GNA(images[i], i);
/*imshow("pic", images[i]);
waitKey(10);*/
}
system("pause");
return 0;
}
效果如图: