opencv--c++项目(一)画笔
项目一、画笔:基于网络摄像头1、先是用上面所用的颜色检测测出你的笔的HSV三者的值#include<opencv2/imgcodecs.hpp>#include<opencv2/highgui.hpp>#include<opencv2/imgproc.hpp>#include<iostream>using namespace std;using na
·
项目一、画笔:基于网络摄像头
1、先是用上面所用的颜色检测测出你的笔的HSV三者的值
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int hmin = 0, smin = 0, vmin = 0;
int hmax = 179, smax = 255, vmax = 255;//如何确定这6个值,每次都更改所有这些再次运行很痛苦 -->创建跟踪栏(使我们可以实时更改这些值)
Mat img;
Mat imgHSV, mask, imgColor;
void main() {
VideoCapture cap(0);//相机id=0
namedWindow("Trackbars", (640, 200));//创建窗口,(640,200)是尺寸
//运行时,把3个min的都移到最小值,把3个max的都移到最大值,然后移动使其保持为白色
createTrackbar("Hue Min", "Trackbars", &hmin, 179);//对于hue色相饱和度最大180,对于另外两个色相饱和度最大255
createTrackbar("Hue Max", "Trackbars", &hmax, 179);
createTrackbar("Sat Min", "Trackbars", &smin, 255);
createTrackbar("Sat Max", "Trackbars", &smax, 255);
createTrackbar("Val Min", "Trackbars", &vmin, 255);
createTrackbar("Val Max", "Trackbars", &vmax, 255);
while (true) {
//检查数组元素是否位于其他两个数组的元素之间。
//imgHSV为输入图像,mask为输出图像
cap.read(img);
cvtColor(img, imgHSV, COLOR_BGR2HSV);//转换图像到HSV空间,在其中查找颜色更加容易
Scalar lower(hmin, smin, vmin);
Scalar upper(hmax, smax, vmax);
inRange(imgHSV, lower, upper, mask);//定义颜色下限和上限,因为由于照明和不同的阴影,颜色的值将不完全相同,会是一个值的范围
cout << hmin << "," << smin << "," << vmin << "," << hmax << "," << smax << "," << vmax << endl;
imshow("Image", img);
imshow("Image HSV", imgHSV);
imshow("Image mask", mask);
waitKey(1);//增加延时
}
}
2、主代码:
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat img;
vector<vector<int>> newPoints;
/////////////// 网络摄像头 //////////////////////
vector<vector<int>>myColors{//可以使用的颜色
{0,128,0,179,255,255},//红色(hmin smin vmin hmax smax vmax)
{0,0,3,179,255,51}//蓝色(hmin smin vmin hmax smax vmax)
};
vector<Scalar> mycolorvalues{{255,0,255},//红色
{0,255,0}//蓝色
};
Point getContours(Mat imgDil) {//imgDil是传入的扩张边缘的图像用来查找轮廓,img是要在其上绘制轮廓的图像
vector<vector<Point>> contours;//轮廓检测到的轮廓。每个轮廓线存储为一个点的向量
vector<Vec4i> hierarchy;//包含关于映像拓扑的信息 typedef Vec<int, 4> Vec4i;具有4个整数值
//在二值图像中查找轮廓。该函数利用该算法从二值图像中提取轮廓
findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//drawContours(img, contours, -1, Scalar(255, 0, 255), 2);//img:要绘制轮廓在什么图片上,contours:要绘制的轮廓,-1定义要绘制的轮廓号(-1表示所有轮廓),Saclar表示轮廓颜色,2表示厚度
vector<vector<Point>> conPoly(contours.size());//conploy的数量应小于contours
vector<Rect> boundRect(contours.size());
Point myPoint(0, 0);
//过滤器:通过轮廓面积来过滤噪声
for (int i = 0; i < contours.size(); i++) {//遍历检测到的轮廓
int area = contourArea(contours[i]);
//cout << area << endl;
string objectType;
if (area > 1000) {//轮廓面积>1000才绘制
//计算轮廓周长或凹坑长度。该函数计算了曲线长度和封闭的周长。
float peri = arcLength(contours[i], true);//计算封闭轮廓周长
approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);//以指定的精度近似多边形曲线。第二个参数conPloy[i]存储近似的结果,是输出。
cout << conPoly[i].size() << endl;
boundRect[i] = boundingRect(conPoly[i]);//计算边界矩形
myPoint.x = boundRect[i].x + boundRect[i].width / 2;
myPoint.y = boundRect[i].y;
cout << conPoly[i].size() << endl;
rectangle/*绘制边界矩形*/(img, boundRect[i].tl()/*tl():topleft矩形左上角坐标*/, boundRect[i].br()/*br():bottom right矩形右下角坐标*/, Scalar(0, 255, 0), 5);
drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
}
}
return myPoint;
}
vector<vector<int>> findColor(Mat img) {//找点
Mat imgHSV;
cvtColor(img, imgHSV, COLOR_BGR2HSV);//转换图像到HSV空间,在其中查找颜色更加容易
for (int i = 0; i < myColors.size(); i++)
{
Scalar lower(myColors[i][0], myColors[i][1], myColors[i][2]);
Scalar upper(myColors[i][3], myColors[i][4], myColors[i][5]);
Mat mask;
inRange(imgHSV, lower, upper, mask);//定义颜色下限和上限,因为由于照明和不同的阴影,颜色的值将不完全相同,会是一个值的范围
//imshow(to_string(i), mask);
//getContours(mask);
Point myPoint=getContours(mask);
if (myPoint.x != 0 && myPoint.y != 0) {//没检测到东西的时候就不加入新点
newPoints.push_back({ myPoint.x,myPoint.y,i });//i为颜色索引
}
}
return newPoints;
}
void drawOnCanvas(vector<vector<int>> newPoints, vector<Scalar> myColorValues) {//画点
for (int i = 0; i < newPoints.size(); i++) {
circle(img, Point(newPoints[i][0], newPoints[i][1]),6,myColorValues[newPoints[i][2]],FILLED);
}
}
void main() {
VideoCapture cap(0);//相机id=0
while (true) {
cap.read(img);
newPoints = findColor(img);
drawOnCanvas(newPoints, mycolorvalues);
imshow("Image", img);
waitKey(1);//增加延时 1ms,以免太慢
}
}
效果展示:
更多推荐
所有评论(0)