本文主要目的是检测激光点,并实时显示出激光点的质心坐标信息。
识别的流程为:
1.读取摄像头的数据
2.转化为HSV模型
3.修改识别颜色HSV的参数范围,进行识别。
4.计算激光点的质心位置
首先需要的opencv头文件
#include <opencv2\opencv.hpp>
#include<opencv2\imgproc.hpp>
#include<opencv2\imgcodecs.hpp>
#include<opencv2\highgui.hpp>
#include<iostream>
使用VideoCapture cap(1);读取摄像头数据(默认摄像头为0,插去USB为1)
定义HSV模型的6个参数,并设计调节窗口方便对后续参数进行调节
static int iLowH = 22; //色调
static int iHighH = 79;
static int iLowS = 0; //饱和度
static int iHighS = 7;
static int iLowV = 255; //亮度
static int iHighV = 255;
参数调节窗口
namedWindow("Threshould", WINDOW_AUTOSIZE);
createTrackbar("LowH", "Threshould", &iLowH, 179);
createTrackbar("HighH", "Threshould", &iHighH, 179);
createTrackbar("LowS", "Threshould", &iLowS, 255);
createTrackbar("HighS", "Threshould", &iHighS, 255);
createTrackbar("LowV", "Threshould", &iLowV, 255);
createTrackbar("HighV", "Threshould", &iHighV, 255);
效果图
将摄像头采集到的数据经过盒滤波进行显示
Mat frame;
cap >> frame;
Mat poisson;
boxFilter(frame, poisson, -1, Size(3, 3), Point(-1, -1));
将输入的图像变为HSV,方便inRange函数及逆行参数的赋值
cvtColor(srclmage, imgHSV, COLOR_BGR2HSV);
//输入图像变为HSV,方便inRange函数参数赋值
vector<Mat>hsvSplit;
split(imgHSV, hsvSplit);
equalizeHist(hsvSplit[2], hsvSplit[2]);
merge(hsvSplit, imgHSV);
图像二值化处理,通过开操作和闭操作去除噪点
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), buflmg);
//二值化
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
morphologyEx(buflmg, buflmg, MORPH_OPEN, element);//开操作 去除一些噪点
morphologyEx(buflmg, buflmg, MORPH_CLOSE, element);//闭操作 连接连通域
这是我们就能得到识别出的激光二值化的图像
因为激光二值化的图形为圆形,所以其中心位置坐标就是质心的坐标
int X = 0;
int Y = 0;
int PixCount = 0;
int ImgWidth = buflmg.cols;//目标结果图像的宽
int ImgHeight = buflmg.rows;//目标结果图像的长
int ImgChannels = buflmg.channels();//通道数
for (int y = 0; y < ImgHeight; y++)
{
for (int x = 0; x < ImgWidth; x++)
{
if (buflmg.data[y * ImgWidth + x] == 255)
{
X += x;
Y += y;
PixCount++;
}
}
}
if (PixCount > 0)
{
X /= PixCount;
Y /= PixCount;
printf("质心坐标(%d,%d)\n", X, Y);
Point line_begin = Point(X - 10, Y);
Point line_end = Point(X + 10, Y);
line(srclmage, line_begin, line_end, Scalar(255, 0, 0));
line_begin.x = X; line_begin.y = Y - 10;
line_end.x = X; line_end.y = Y + 10;
line(srclmage, line_begin, line_end, Scalar(255, 0, 0));
}
else
{
printf("未找到光点...\n");
}
这样我们就能找激光的位置坐标信息,并在原图的中心位置绘制出一个蓝色的十字