opencv快速上手教程(C++版)
文章目录
-
- 概要
- 环境配置
-
- 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++快速上手的一遍文章,之后会写一些实战项目。希望大家一起进步。
更多推荐


所有评论(0)