光条提取:灰度邻域属性法

节选自论文:高斯加权的二维灰度重心法提取光条中心

只能实现粗略的光条提取,后续借助初始提取的光条中心以及所求出的宽度,配合加权灰度重心法进行进一步的提取。

笔者水平有限,希望读者可以进行批评指正。

代码如下

#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;
}

 效果如图:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值