卷积法求解光斑质心(附源码,C++、opencv)

1、求解步骤

第一步,初始化一个高斯模板:

Mat GuassTemplate = (Mat_<uchar>(3, 3) << 1, 2, 1, 2, 4, 2, 1, 2, 1);	//高斯核

第二步,将高斯模板与图像进行卷积,并将卷积结果存储到另一个矩阵Mat中,这个过程类似于高斯滤波:

//进行卷积运算
	double value = 0;
	for (int i = 1; i < Img.rows + 1; i++)
	{
		for (int j = 1; j < Img.cols + 1; j++)
		{
			for (int m = 0; m < 3; m++)
			{
				for (int n = 0; n < 3; n++)
				{
					value += static_cast<double>(GuassTemplate.at<uchar>(m,n)) * Convolution_Img.at<uchar>(i + m - 1,j + n - 1 );
				}
			}
			Convolution_Result.at<double>(i - 1,j - 1) = value;	//将计算结果另存入矩阵中
			value = 0;
		}
	}

第三步,计算结果矩阵中最大值所在坐标,即为质心坐标。

//求矩阵中最大值坐标
	double minVal; double maxVal; Point minLoc; Point maxLoc;
	minMaxLoc(Convolution_Result, &minVal, &maxVal, &minLoc, &maxLoc);
	
	return maxLoc;

结果展示:

2、源码

// 质心检测.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include<opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Point Convolution_calculation_centroid(Mat Img);

int main()
{
	Point2d point1;
	Mat Img = imread("高斯光斑2.tif");
	point1 = Convolution_calculation_centroid(Img);
	circle(Img, point1, 1, Scalar(0, 255, 0), -1); //第五个参数设为-1,表明这是个实点。
	imshow("Img", Img);
	cout << "质心坐标:"<< point1 << endl;
	waitKey();
}

//卷积检测高斯光斑质心
Point Convolution_calculation_centroid(Mat Image)
{
	Mat Img;
	if (Image.channels() != 1)	//判断输入图像是否为灰度图,若不是转成灰度图
		cvtColor(Image, Img, COLOR_BGR2GRAY);

	Mat GuassTemplate = (Mat_<uchar>(3, 3) << 1, 2, 1, 2, 4, 2, 1, 2, 1);	//高斯核
	Mat Convolution_Img(Img.rows + 2, Img.cols + 2, CV_8UC1, Scalar::all(0));
	Mat Convolution_Result = Mat::zeros(Img.rows, Img.cols, CV_64F);

	// 构造卷积的图像区域
	for (int i = 1; i < Img.rows; i++)
	{
		for (int j = 1; j < Img.cols; j++)
		{
			Convolution_Img.at<uchar>(i + 1, j + 1) = Img.at<uchar>(i, j);
		}
	}

	//进行卷积运算
	double value = 0;
	for (int i = 1; i < Img.rows + 1; i++)
	{
		for (int j = 1; j < Img.cols + 1; j++)
		{
			for (int m = 0; m < 3; m++)
			{
				for (int n = 0; n < 3; n++)
				{
					value += static_cast<double>(GuassTemplate.at<uchar>(m,n)) * Convolution_Img.at<uchar>(i + m - 1,j + n - 1 );
				}
			}
			Convolution_Result.at<double>(i - 1,j - 1) = value;	//将计算结果另存入矩阵中
			value = 0;
		}
	}

	//求矩阵中最大值坐标
	double minVal; double maxVal; Point minLoc; Point maxLoc;
	minMaxLoc(Convolution_Result, &minVal, &maxVal, &minLoc, &maxLoc);
	
	return maxLoc;
}

3、注:该方法下检测结果的精度不是亚像素级别,转成亚像素级别可参考:https://blog.csdn.net/Mrweng1996/article/details/81474947

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值