文章目录

    • 概要
    • 环境配置
      • 1.vs2022社区版下载及opencv4.7下载
      • 2.在vs当中配置opencv的库
      • 3.验证是否配置成功
    • 第一章:对图像、视频、摄像头等资源导入
      • 1.图像导入
      • 2.视频导入
      • 3.摄像头导入
    • 第二章:对图像的预处理
    • 第三章:对图片尺寸调整
    • 第四章:创建图片和对基础图形绘制
    • 第五章:对图片进行扫描
    • 第六章:颜色识别
    • 第七章:形状识别
      • 1.对图片进行预处理
      • 2.提取轮廓
      • 3.提取点
      • 4.建立点与形状相对于的哈希表,判断类型
    • 小结

概要

本篇着重介绍基于c++的OpenCV的环境配置及其基本功能介绍。让大家可以快速入门OpenCV的相关的项目,如颜色识别,形状识别,视觉小车寻迹。

环境配置

1.vs2022社区版下载及opencv4.7下载

这些都是在官网上可以下载的,具体的下载可以参考vs2022下载以及opencv下载

2.在vs当中配置opencv的库

1.创建空项目,点开项目任务栏
步骤一
2.点击VC++找到包含目录,点击小三角形选择刚刚下载的OpenCV路径下的include文件。参考图片,这里d:\opencv是我定义的路径,后面的保持一致。
在这里插入图片描述
3.点击VC++找到库目录,点击小三角形选择刚刚下载的OpenCV路径下文件。参考图片,这里d:\opencv是我定义的路径,后面的保持一致。
在这里插入图片描述
4.找到链接器->输入->附加依赖项,点击小三角形点击编辑。找到刚刚下载的OpenCV路径下文件,参考图二并且将文件名复制粘贴到编辑处
在这里插入图片描述
注意:上图中最上方的配置处如果是debug版本则选择d.lib的文件,realease则选择lib文件
在这里插入图片描述
在这里插入图片描述

3.验证是否配置成功

#include <opencv2/opencv.hpp> 
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include <iostream>

将上述头文件在vs中写入,如果没有报错则说明配置成功。注意配置过程中不要选错了选项
特别提醒:这个只针对当前项目下有效,当重新建立新的项目则会需要重新配置。如果不想重复配置,则可采用将文件从项目中排除
在这里插入图片描述

第一章:对图像、视频、摄像头等资源导入

变量类型介绍:
Mat:OpenCV中的矩阵类,用于存储和操作图像数据。每一帧图像都保存在一个Mat对象中。
函数介绍:
imread:将本地资源的文件路径转化为Mat类型
imshow:输出图像
waitKey:

1.图像导入

技术细节:
waitKey(delay):等待键盘事件,单位为毫秒。delay=0 表示无限等待,直到用户按下任意键。imshpw必须和waitKey()组合使用否则将会立马关闭而不进行显示

//////////////////image//////////////////////
int main()
{
	string path = "D:/jichuang/opencv/test/1.jpg";
	Mat img;
	img = imread(path);
	if (img.empty())
	{
		cout << "请确认图像文件名是否正确" << endl;
		return 0;
	}
	imshow("souce",img);
	waitKey(0);
	return 0;
}

2.视频导入

技术细节:
VideoCapture:OpenCV中的类,用于打开、读取视频文件或摄像头流。可以用来一帧一帧地读取视频内容。可以看做是由很多个Mat组成。在下列代码中cap.read(img)可以体现这一理解。
read()、empty():为VideoCapture中的对象。
作用.read(img)从视频流中读取一帧,存入img(Mat对象)。如果读取成功返回true,否则返回false,
img.empty()检查Mat对象是否为空(即没有数据)。常用于判断是否成功读取到图像。

//////////////////video/////////////////////////////////////
int main()
{
	string path = "D:/jichuang/opencv/test/2.mp4";
	VideoCapture cap(path);
	Mat img;
	while (true)
	{
		if (!cap.isOpened())
		{
			cout << "请确认视频文件名是否正确" << endl;
			return 0;
		}
		cap.read(img);//存入img
		if (img.empty())
		{
			cout << "视频播放完毕" << endl;
			break;
		}
		imshow("souce", img);//显示img
		waitKey(15);//每一帧画面之间的间隔
	}
	return 0;
}

3.摄像头导入

技术细节:
与本地导入不同,在VideoCapture后面用0初始化,不再使用路径。0一般是自带摄像头,而1可能是外接入摄像头。

/////////////////////////webcam////////////////////
int main()
{
	VideoCapture cap(0);
	Mat img;
	while(true)
	{
		if (!cap.isOpened())
		{
			cout << "请确认摄像头是否正常" << endl;
			return 0;
		}
		cap.read(img);
		if (img.empty())
		{
			cout << "摄像头读取失败" << endl;
			break;
		}
		imshow("souce", img);
		waitKey(15);
	}
	return 0;
}


第二章:对图像的预处理

技术细节:
1.cvtColor:用于图像颜色空间转换的函数。第三个参数代表由BGR(蓝绿红)转化为灰度
2.GaussianBlur:用于对图像进行高斯模糊处理的函数。高斯模糊常用于去噪、平滑图像。注意第三个参数高斯核的大小必须为正奇数,第四、五个参数高斯核标准差sigmaX 和 sigmaY 控制模糊强度,通常只设置 sigmaX,sigmaY 设为 0。
3.Canny:用于边缘检测的函数,常用于提取图像中的轮廓和边界。常常是在图像经过模糊化处理后再进行边缘提取提高准确性。
4.dilate:膨胀操作函数,用于对图像中的白色区域(前景)进行扩展,常用于消除小黑洞、连接断裂的白色区域等。通常在边缘提取之后进行去除噪点、连接断裂边缘等
5.getStructuringElement是 OpenCV 中用于生成结构元素(卷积核/形态学操作核)的函数,常用于膨胀、腐蚀等形态学操作。第一个参数为元素形状,处理文本、直线:可用 MORPH_RECT 或 MORPH_CROSS。处理圆形、斑点:可用 MORPH_ELLIPSE。

int main()
{
	Mat img;
	string path = "D:/jichuang/opencv/test/1.jpg";
	img = imread(path);
	Mat imgGrey, imgBlur, imgCanny,imgDilate1, imgDilate2,imgErode;
	cvtColor(img, imgGrey, COLOR_BGR2GRAY);
	GaussianBlur(imgGrey, imgBlur, Size(3, 3), 3, 0);
	Canny(imgBlur, imgCanny, 50, 150);
	Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3));
	Mat kernel2 = getStructuringElement(MORPH_RECT, Size(5, 3));
	dilate(imgCanny, imgDilate1,kernel1);
	dilate(imgCanny, imgDilate2, kernel2);


	imshow("img", img);
	imshow("imgGrey", imgGrey);
	imshow("imgBlur", imgBlur);	
	imshow("imgCanny", imgCanny);
	imshow("imgDilate1", imgDilate1);
	imshow("imgDilate2", imgDilate2);
	waitKey(0);
	return 0;
}

第三章:对图片尺寸调整

技术细节:
1.Mat Mat::operator()(const Rect& roi) const:重载运算符(),对图片进行裁剪。
2.resize(img,dst imgSize(),fx,fy):第三个参数是缩放的尺寸,fx的缩放比例,fy的缩放比例。

int main()
{
	string path = "D:/jichuang/opencv/test/1.jpg";
	Mat img,imgResize,imgRec;
	img = imread(path);
	cout << img.size() << endl;
	resize(img, Reimg, Size(),0.5,0.5);

	Rect roi(450, 100, 200, 200);
	imgRec = img(roi);
	imshow("img", img);
	imshow("Reimg", imgResize);
	imshow("imRec",imgRec);
	waitKey(0);
	return 0;
}

第四章:创建图片和对基础图形绘制

技术细节:
Mat Mat::operator():第一、二个参数代表尺寸,第三参数CV_8UC3:CV_8表示每个像素是 8 位无符号整数(0~255),第四个参数代表颜色。

////////////////////draw shapes and text/////////////////////////////////////
int main()
{
	//创建一个空白图像
	Mat img(512,512,CV_8UC3,Scalar(255,255,255));// 创建一个512x512的白色空白图像()

	//绘制圆形
	circle(img, Point(256, 256), 100, Scalar(0, 0, 255), FILLED);
	rectangle(img, Point(156, 156), Point(200, 200), Scalar(255, 0, 0), 10);
	line(img,Point(200,300),Point(400,300),Scalar(0,255,0),2);

	imshow("img", img);
	waitKey(0);
	return 0;
}

第五章:对图片进行扫描

技术细节:
1.getPerspectiveTransform():计算透视变换矩阵的函数。通过原始图片的一部分的点和目标点得到变换矩阵。
2.warpPerspective(img,dimg,idex,Size(w,h)):用于对图像进行透视变换。将原始图像通过变换矩阵得到目标图像。Size()代表的是转化后的图像。

float w = 250, h = 350;
int main()
{
	Mat img=imread("D:/jichuang/opencv/test/2.jpg");
	Mat dimg;

	Point2f src[4] = { {1809,553},{2170,623},{1619,936},{2025,1029} };
	Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };

	Mat idex = getPerspectiveTransform(src, dst);
	warpPerspective(img,dimg,idex,Size(w,h));

	imshow("img", img);
	imshow("img2", dimg);
	waitKey(0);
	return 0;
}

第六章:颜色识别

技术细节:
namedWindows(“Trackbars”, (640, 200)):创建滑块界面
createtrackbars(“Hue Min”, “Trackbars”, &hmin, 179):"Hue Min"进度条名称,&hmin代表变量地址,179代表最大值。注意"trackbars"要和createWindows的名称保持一致。
cvtColor():和第二章保持一致。HSV也是一种颜色空间,Hue(色相)、Saturation(饱和度)、Value(明度)
inRange :用于图像像素值范围筛选的函数,即提取指定的颜色。操作对象为HSV图像。

Mat mask,imgHSV;
int hmin = 158, hmax = 179;
int vmin = 94, vmax = 165;
int smin = 250, smax = 64;

int main()
{
	Mat img = imread("D:/jichuang/opencv/test/3.jpg");
	cvtColor(img, imgHSV,COLOR_BGR2HSV);

	namedWindow("Trackbars", (640, 200));

	createTrackbar("Hue Min", "Trackbars", &hmin, 179);
	createTrackbar("Hue Max", "Trackbars", &hmax, 179);
	createTrackbar("Sue Min", "Trackbars", &smin, 255);
	createTrackbar("Sue Max", "Trackbars", &smax, 255);
	createTrackbar("Val Min", "Trackbars", &vmin, 255);
	createTrackbar("Val Max", "Trackbars", &vmax, 255);
	while (true)
	{
		Scalar lower(hmin, smin, vmin);
		Scalar upper(hmax, smax, vmax);
		inRange(imgHSV, lower, upper, mask);


		imshow("img", img);
		imshow("imgHSV", imgHSV);
		imshow("mask", mask);
		waitKey(1);
	}
	
	return 0;
}

在这里插入图片描述


第七章:形状识别

1.对图片进行预处理

技术要点:将图像处理为二值图像(采用Canny进行提取)详见第二章

2.提取轮廓

技术要点:
1.findContours():indContours 用于在二值图像中查找轮廓,并将结果存储在 contours (类型为 vector<vector>,用于存储检测到的每个轮廓的点集)和 hierarchy (类型为 vector,用于存储轮廓之间的层级关系中)
2.drawContours()绘制所有(-1)/第i个轮廓(i)检测到的轮廓。

void getCounters(Mat imgDilate, Mat img)
{
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(imgDilate, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	vector<vector<Point>> compoly(contours.size());
	vector<Rect> boundRect(contours.size()); 
	drawContours(img, contours, -1, Scalar(255, 0, 255), 2);
}

3.提取点

技术细节:
approxPolyDP:对输入的轮廓点集进行多边形拟合,简化轮廓形状
// 参数:contours[i] - 输入轮廓点集
// compoly - 输出拟合后的多边形点集
// 0.02 * peri - 近似精度,peri为轮廓周长
// true - 是否闭合轮廓

for (int i = 0;i < contours.size();i++)
{
	int area = contourArea(contours[i]);
	if (area > 5000)
	{
		float peri = arcLength(contours[i], true);
		approxPolyDP(contours[i], compoly[i], 0.01 * peri, true);
		ShapeDetect(compoly[i], img);
		cout << compoly[i].size() << endl;
	}
}

4.建立点与形状相对于的哈希表,判断类型

技术细节
putText():注意只要求一个点
boundingRect():计算最小外接矩形的函数。它的作用是:给定一组点(通常是轮廓点集),返回一个能包围所有这些点的最小矩形(Rect 类型)。即寻找边界值。

void ShapeDetect(vector<Point>& compoy, Mat img)
{
	Rect bounding = boundingRect(compoy);
	if (compoy.size() >=7)
	{
		putText(img, "Circle", { bounding.tl().x,bounding.tl().y-10  }, FONT_HERSHEY_PLAIN, 0.75, Scalar(0, 0, 255), 1);
		return;
	}
	vector<string> hash(10, " ");
	hash[1] = "dot";
	hash[2] = "Line";
	hash[3] = "Triangle";
	hash[4] = "Rectangle";
	hash[5] = "Pentagon";
	hash[6] = "Hexagon";
	putText(img, hash[compoy.size()], { bounding.tl().x,bounding.tl().y - 10 }, FONT_HERSHEY_PLAIN, 0.75, Scalar(0, 0, 255), 1);


}

在这里插入图片描述

小结

这是关于c++快速上手的一遍文章,之后会写一些实战项目。希望大家一起进步。

Logo

1331

更多推荐