卷积法求解光斑质心(C++、opencv)
转载备用。原文链接
代码如下(示例):
#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("C:/Users/HZY/Desktop/3.jpg");
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;
}