c_cpp 摄像头物体跟踪定位(应用最小矩形)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 摄像头物体跟踪定位(应用最小矩形)相关的知识,希望对你有一定的参考价值。
#include<opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include<iostream>
#define BIN_DIV 120
using namespace std;
using namespace cv;
int main()
{
VideoCapture capture(0);
Mat srcImg;
while (1)
{
Mat frame;
capture >> frame;
frame.copyTo(srcImg);
Mat xianshi = srcImg.clone();
Mat redChannel;
namedWindow("【视频原画】", WINDOW_NORMAL);
imshow("【视频原画】", srcImg);
Mat grayImg;
vector<Mat> channels; //vector容器,用来存放split(需要进行分离的多通道数组,输出的数组或vector容器)
split(srcImg, channels); //分离色彩通道;进行通道分离的split函数。
//cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);
//-----------------------------------------------------------------
// 根据OpenCV的BGR色彩空间(blue,Green,Red,蓝绿红),
// 其中channels.at(0)就表示引用取出channels中的蓝色分量,
// channels.at(1)就表示引用取出channels中的绿色色分量,
// channels.at(2)就表示引用取出channels中的红色分量。
//-----------------------------------------------------------------
grayImg = channels.at(0);
redChannel = channels.at(2);
namedWindow("【视频灰度画面】", WINDOW_NORMAL);
imshow("【视频灰度画面】", grayImg);
//------------------------均值滤波---------------------------------
// 描述:灰度图经过中值滤波后可以得到去噪后的图片。
//-----------------------------------------------------------------
blur(grayImg, grayImg, Size(20, 20), Point(-1, -1));
namedWindow("【视频均值滤波后】", WINDOW_NORMAL);
imshow("【视频均值滤波后】", grayImg);
//----------------------------------------转化为二值图-----------------------------------------
// 描述:根据原图的蓝色通道和红色通道的大概取值范围,我们可得到比较满意的二值图。
// 在OpenCV中使用轮廓发现相关函数时候要求输入图像是二值图像,这样便于轮廓提取、边缘提取等操作。
//-------------------------------------------------------------------------------------------
Mat midImg1 = grayImg.clone();
int rowNumber = midImg1.rows;
int colNumber = midImg1.cols;
for (int i = 0; i < rowNumber; i++)
{
uchar* data = midImg1.ptr<uchar>(i); //取第i行的首地址
uchar* redData = redChannel.ptr<uchar>(i);
for (int j = 0; j < colNumber; j++)
{
if (data[j] > BIN_DIV && redData[j] < BIN_DIV / 2)
data[j] = 0;
else
data[j] = 255;
}
}
namedWindow("【视频二值画面】", WINDOW_NORMAL);
imshow("【视频二值画面】", midImg1);
//--------------------------------------开运算-----------------------------------------------
// 描述:目前使用的是开运算
// 为了去掉物体中少量的黑色部分,可以用闭运算。闭运算目前来看就是把MORPH_OPEN换成MORPH_CLOSE
//------------------------------------------------------------------------------------------
Mat midImg2 = midImg1.clone();
Mat element = getStructuringElement(MORPH_RECT, Size(20, 20));
morphologyEx(midImg1, midImg2, MORPH_OPEN, element);
namedWindow("【视频开运算后】", WINDOW_NORMAL);
imshow("【视频开运算后】", midImg2);
cout << "midImg1.channel=" << midImg1.channels() << endl;
cout << "mdiImg1.depth" << midImg1.depth() << endl;
//---------------------------------查找图像轮廓--------------------------------
Mat midImg3 = Mat::zeros(midImg2.rows, midImg2.cols, CV_8UC3);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(midImg2, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
int index = 0;
for (; index >= 0; index = hierarchy[index][0])
{
Scalar color(255, 255, 255);
drawContours(midImg3, contours, index, color, NULL, 8, hierarchy);
}
namedWindow("【视频轮廓画面】", WINDOW_NORMAL);
imshow("【视频轮廓画面】", midImg3);
Mat midImg4 = midImg3.clone();
//--------------------------创建包围轮廓的矩形边界--------------------------
// 描述:找到能包围轮廓的最小矩形。
//--------------------------------------------------------------------------
for (int i = 0; i < contours.size(); i++)
{
//每个轮廓
vector<Point> points = contours[i];
//对给定的2D点集,寻找最小面积的包围矩形
RotatedRect box = minAreaRect(Mat(points));
Point2f vertex[4];
box.points(vertex);
//绘制出最小面积的包围矩形
line(xianshi, vertex[0], vertex[1], Scalar(100, 200, 211), 6, LINE_AA);
line(xianshi, vertex[1], vertex[2], Scalar(100, 200, 211), 6, LINE_AA);
line(xianshi, vertex[2], vertex[3], Scalar(100, 200, 211), 6, LINE_AA);
line(xianshi, vertex[3], vertex[0], Scalar(100, 200, 211), 6, LINE_AA);
//绘制中心的光标
Point s1, l, r, u, d;
s1.x = (vertex[0].x + vertex[2].x) / 2.0;
s1.y = (vertex[0].y + vertex[2].y) / 2.0;
l.x = s1.x - 10;
l.y = s1.y;
r.x = s1.x + 10;
r.y = s1.y;
u.x = s1.x;
u.y = s1.y - 10;
d.x = s1.x;
d.y = s1.y + 10;
line(xianshi, l, r, Scalar(100, 200, 211), 2, LINE_AA);
line(xianshi, u, d, Scalar(100, 200, 211), 2, LINE_AA);
printf("\t 输出内容: 面积和轮廓长度\n");
//输出内容
for (unsigned int i = 0; i < contours.size(); i++)
{
printf("计算出的面积=%.2f , 长度: %.2f \n", contourArea(contours[i]), arcLength(contours[i], true));
}
}
namedWindow("【绘制的最小面积矩形】", WINDOW_AUTOSIZE);//输出视频自适应尺寸
imshow("【绘制的最小面积矩形】", xianshi);
waitKey(30);
}
return 0;
}
以上是关于c_cpp 摄像头物体跟踪定位(应用最小矩形)的主要内容,如果未能解决你的问题,请参考以下文章