OpenCV (bilibili教程代码)
Eva.Q Lv9

我是代码搬运机

github.com

Chapter 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Images
/// </summary>
//void main() {
// string path = "Resources/test.png";
// Mat img=imread(path);//matrix data type 由opencv引入来处理图像
// imshow("Image", img);
// waitKey(0);//增加延时,0表示无穷
//}


/// <summary>
/// Video
/// //视频是一系列图像,需要遍历所有图像或帧 一一捕获并显示,因此将使用while循环
/// </summary>
//void main() {
// string path = "Resources/test_video.mp4";
// VideoCapture cap(path);
// Mat img;
//
// while (true) {
// cap.read(img);
// imshow("Image", img);
// waitKey(20);//增加延时 20ms
// }
//
//}

/// <summary>
/// Webcam
/// 与导入视频不同的是,不需要视频路径,只需要给相机ID,id=0表示默认的摄像头
/// </summary>
//void main() {
// VideoCapture cap(0);//相机id=0
// Mat img;
//
//while (true) {
// cap.read(img);
// imshow("Image", img);
// waitKey(1);//增加延时 1ms,以免太慢
//}
//
//}

Chapter 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Basic Function
/// </summary>
//void main() {
// string path = "Resources/test.png";
// Mat img=imread(path);//matrix data type 由opencv引入来处理图像
// Mat imgGray,imgBlur,imgCanny,imgDil,imgErode;
//
// cvtColor(img, imgGray, COLOR_BGR2GRAY);//cvt是convert的缩写,将图像从一种颜色空间转换为另一种颜色空间。
// GaussianBlur(imgGray, imgBlur,Size(7,7),5,0);//使用高斯滤波器模糊图像。该函数将源图像与指定的高斯核进行卷积,Size(7,7)是核大小,数字越大越模糊
// Canny(imgBlur, imgCanny, 25, 75);//边缘检测,阈值1,2可调,目的:显示更多的边缘
//
// Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));//创建一个核,增加Size(只能是奇数)会扩张/侵蚀更多
// dilate(imgCanny, imgDil, kernel);//扩张边缘(增加边缘厚度)
// erode(imgDil, imgErode, kernel);//侵蚀边缘(减小边缘厚度)
// imshow("Image", img);
// imshow("Image Gray", imgGray);
// imshow("Image Blur", imgBlur);
// imshow("Image Canny", imgCanny);
// imshow("Image Dilation", imgDil);
// imshow("Image Erode", imgErode);
// waitKey(0);//增加延时,0表示无穷
//}

Chapter 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//学习如何调整大小以及裁剪图像

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

using namespace std;
using namespace cv;

/// <summary>
/// Resize and Crop
/// </summary>
//void main() {
// string path = "Resources/test.png";
// Mat img=imread(path);//matrix data type 由opencv引入来处理图像
// Mat imgResize,imgCrop;
// cout << img.size() << endl;//打印图像尺寸
// //resize(img, imgResize, Size(640, 480));//指定图片尺寸缩放
// resize(img, imgResize, Size(),0.5,0.5);//指定缩放比例,不指定图片尺寸
//
// //矩形数据类型
// Rect roi(200, 100, 300, 300);//以左上角为坐标原点,(200,100)为矩形的左上角坐标,300,300为矩形长宽
// imgCrop = img(roi);//裁剪图像,为了找到特定区域 添加更多处理 roi:region of interest
// imshow("Image", img);
// imshow("Image Resize", imgResize);
// imshow("Image Crop", imgCrop);
//
// waitKey(0);//增加延时,0表示无穷
//}

Chapter 4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//学习如何绘制形状(圆形、矩形、线段)和如何在图片上写字

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

using namespace std;
using namespace cv;

/// <summary>
/// Draw Shapes and Text
/// </summary>
//void main() {
// //创建空白图像
// //Scalar(255, 0, 255),(蓝色:255,0,0),(紫色:255,0,255),(黑色:0,0,0),(白色:255,255,255)
// Mat img(512, 512, CV_8UC3, Scalar(255, 255, 255));//(512,512)为图片大小,CV8UC3中8表示每个像素的值从0到255,3表示3个颜色通道BGR,Scalar(255, 0, 0)表示图像将具有的颜色
//
// circle(img, Point(256, 256), 155,Scalar(0,69,255),FILLED);//第一个参数:图片,第二个参数是圆心坐标,第三个参数是圆大小,第四个参数是颜色,第五个参数是厚度(可以不写),想要填充可以填FILLED
// rectangle(img, Point(130,226), Point(382,286),Scalar(255,255,255),FILLED);//第一个Point给矩形左上角坐标,第二个Point给矩形右下角坐标
// line(img, Point(130, 296), Point(382, 296), Scalar(255, 255, 255), 2);//第一个Point是起点坐标、第二个Point是终点坐标
// putText(img, "zhuhuijin", Point(137, 262), FONT_HERSHEY_DUPLEX, 0.75, Scalar(0, 69, 255), 2);
//
// imshow("Image", img);
// waitKey(0);//增加延时,0表示无穷
//}

Chapter 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//学习如何扭曲图像,来扫描文档
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Warp Images
/// </summary>
//float w = 250, h = 350;//图片大小
//Mat matrix, imgWarp;
//void main() {
// //图片用画图打开,在屏幕左下角会显示点的坐标
// string path = "Resources/cards.jpg";
// Mat img=imread(path);//matrix data type 由opencv引入来处理图像
// Point2f src[4] = { {529,142},{771,190},{405,395},{674,457} };//Point2f表示浮点数
// Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };//Point2f表示浮点数
//
// matrix = getPerspectiveTransform(src, dst);
// warpPerspective(img, imgWarp, matrix, Point(w,h));
//
// //确定src坐标是否正确
// for (int i = 0; i < 4; i++) {
// circle(img, src[i], 10, Scalar(0, 0, 255), FILLED);
// }
//
// imshow("Image", img);
// imshow("Image Warp", imgWarp);
// waitKey(0);//增加延时,0表示无穷
//}

Chapter 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//学习检测图片中的颜色,来创建特定对象的对象检测器
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Color Detection
/// </summary>


//int hmin = 0, smin = 0, vmin = 0;
//int hmax = 179, smax = 255, vmax = 255;//如何确定这6个值,每次都更改所有这些再次运行很痛苦 -->创建跟踪栏(使我们可以实时更改这些值)
//void main() {
// string path = "Resources/shapes.png";
// Mat img=imread(path);
// Mat imgHSV,mask;
// cvtColor(img, imgHSV, COLOR_BGR2HSV);//转换图像到HSV空间,在其中查找颜色更加容易
// 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为输出图像
//
// Scalar lower(hmin, smin, vmin);
// Scalar upper(hmax, smax, vmax);
// inRange(imgHSV, lower, upper, mask);//定义颜色下限和上限,因为由于照明和不同的阴影,颜色的值将不完全相同,会是一个值的范围
// imshow("Image", img);
// imshow("Image HSV", imgHSV);
// imshow("Image mask", mask);
// waitKey(1);//增加延时
// }
//}

Chapter 7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//学习如何检测形状或图像中的轮廓
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Shapes
/// </summary>


//! 获取轮廓
void getContours(Mat imgDil,Mat img) {//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());
//过滤器:通过轮廓面积来过滤噪声
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]存储近似的结果,是输出。


boundRect[i]=boundingRect(conPoly[i]);//计算边界矩形

int objCor = (int)conPoly[i].size();//找近似多边形的角点,三角形有3个角点,矩形/正方形有4个角点,圆形>4个角点
cout << objCor << endl;
if (objCor == 3) {objectType = "Tri";}
else if (objCor == 4) {
float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height;//宽高比
if (aspRatio > 0.95 && aspRatio < 1.05) { objectType = "Square";}//矩形的宽高比不会正好等于1
else objectType = "Rect";
}
else if (objCor > 4) { objectType = "Circle";}

drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
rectangle/*绘制边界矩形*/(img, boundRect[i].tl()/*tl():topleft矩形左上角坐标*/, boundRect[i].br()/*br():bottom right矩形右下角坐标*/, Scalar(0, 255, 0), 5);
putText(img, objectType, {boundRect[i].x,boundRect[i].y-5}/*文字坐标*/, FONT_HERSHEY_PLAIN, 1, Scalar(0, 69, 255), 2);
}
}
}

//void main() {
// string path = "Resources/shapes.png";
// Mat img=imread(path);
//
// //在检测形状前,对图片预处理:转换为灰度、添加高斯模糊、使用Canny边缘检测器、扩张边缘
// Mat imgGray, imgBlur, imgCanny, imgDil, imgErode;
// cvtColor(img, imgGray, COLOR_BGR2GRAY);//cvt是convert的缩写,将图像从一种颜色空间转换为另一种颜色空间。
// GaussianBlur(imgGray, imgBlur,Size(3,3),3,0);//使用高斯滤波器模糊图像。该函数将源图像与指定的高斯核进行卷积,Size(7,7)是核大小,数字越大越模糊
// Canny(imgBlur, imgCanny, 25, 75);//边缘检测,阈值1,2可调,目的:显示更多的边缘
// Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));//创建一个核,增加Size(只能是奇数)会扩张/侵蚀更多
// dilate(imgCanny, imgDil, kernel);//扩张边缘(增加边缘厚度)
//
// getContours(imgDil,img);//img是在其上绘轮廓的图片
//
// imshow("Image", img);
// /*imshow("Image Gray", imgGray);
// imshow("Image Blur", imgBlur);
// imshow("Image Canny", imgCanny);
// imshow("Image Dil", imgDil);*/
// waitKey(0);//增加延时,0表示无穷
//}

Chapter 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//学习检测图像中的面部
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/objdetect.hpp>//对象检测头文件
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Images
/// </summary>
//void main() {
// string path = "Resources/test.png";
// Mat img=imread(path);
// CascadeClassifier faceCascade;/*用于对象检测的级联分类器类*/
// faceCascade.load("Resources/haarcascade_frontalface_default.xml");//从文件加载分类器(已经训练好的模型)
//
// if (faceCascade.empty()) { cout << "XML file not loaded" << endl; }//检测文件是否加载成功
//
// vector<Rect> faces;
// faceCascade.detectMultiScale(img/*输入*/, faces/*输出*/, 1.1/*比例因子*/, 10/*最小邻居*/);//在输入图像中检测不同大小的对象。检测到的对象将以矩形列表的形式返回。
//
// for (int i = 0; i < faces.size(); i++) {
// rectangle(img, faces[i].tl(),faces[i].br(), Scalar(255, 0, 255), 3);//绘制矩形
// }
//
// imshow("Image", img);
// waitKey(0);//增加延时,0表示无穷
//}

Project 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;


/// <summary>
/// Project 1
/// 使用HSV空间检测颜色、找到轮廓所在位置、取轮廓的位置然后创建一个圆
/// </summary>

//Mat img;
//vector<vector<int>> newPoints;
//
//vector<vector<int>> myColors{ {98,109,54,127,255,255},//蓝色(hmin smin vmin hmax smax vmax)
// {35,0,0,77,245,255} };//绿色(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]存储近似的结果,是输出。
//
// boundRect[i] = boundingRect(conPoly[i]);//计算边界矩形
//
// myPoint.x = boundRect[i].x + boundRect[i].width / 2;
// myPoint.y = boundRect[i].y;
//
// 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);
// 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,以免太慢
// }
//
//}

Project 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

/// <summary>
/// Project 2 – Document Scanner
/// 图像预处理:转换为灰度、添加模糊、使用Canny边缘检测器找到边缘(知道纸张在哪里)、基于纸张的坐标提取四个角得到顶视图
/// </summary>

//Mat imgOriginal, imgGray, imgBlur, imgCanny, imgDil, imgErode, imgThre, imgWarp, imgCrop;
//vector<Point> initialPoints,docPoints;
//float w = 420, h = 596;
//Mat preProcessing(Mat img) {
// cvtColor(img, imgGray, COLOR_BGR2GRAY);//cvt是convert的缩写,将图像从一种颜色空间转换为另一种颜色空间。
// GaussianBlur(imgGray, imgBlur,Size(7,7),5,0);//使用高斯滤波器模糊图像。该函数将源图像与指定的高斯核进行卷积,Size(7,7)是核大小,数字越大越模糊
// Canny(imgBlur, imgCanny, 25, 75);//边缘检测,阈值1,2可调,目的:显示更多的边缘
//
// Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));//创建一个核,增加Size(只能是奇数)会扩张/侵蚀更多
// dilate(imgCanny, imgDil, kernel);//扩张边缘(增加边缘厚度)
// //erode(imgDil, imgErode, kernel);//侵蚀边缘(减小边缘厚度)
// return imgDil;
//}
//
//vector<Point>/*返回纸张的4个角点*/ 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());
//
// vector<Point> biggest;
// int maxArea = 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]存储近似的结果,是输出。
//
// if (area > maxArea&&conPoly[i].size()==4) {
// biggest = { conPoly[i][0],conPoly[i][1],conPoly[i][2],conPoly[i][3] };
// maxArea = area;
// }
//
// //rectangle/*绘制边界矩形*/(imgOriginal, boundRect[i].tl()/*tl():topleft矩形左上角坐标*/, boundRect[i].br()/*br():bottom right矩形右下角坐标*/, Scalar(0, 255, 0), 5);
// //drawContours(imgOriginal, conPoly, i, Scalar(255, 0, 255), 2);
//
// }
// }
// return biggest;
//}
//
//void drawPoints(vector<Point> points, Scalar color) {
// for (int i = 0; i < points.size(); i++) {
// circle(imgOriginal, points[i], 10, color, FILLED);
// putText(imgOriginal, to_string(i), points[i], FONT_HERSHEY_PLAIN, 4, color, 4);
// }
//}
//
//vector<Point> reorder(vector<Point> points) {//标记点的顺序会变,要确定一个顺序 0 1
// // 2 3
// vector<Point> newPoints;
// vector<int> sumPoints, subPoints;
// for (int i = 0; i < 4; i++) {
// sumPoints.push_back(points[i].x + points[i].y);
// subPoints.push_back(points[i].x - points[i].y);
// }
//
// newPoints.push_back(points[min_element/* find smallest element*/(sumPoints.begin(), sumPoints.end())-sumPoints.begin()]);
// newPoints.push_back(points[max_element/* find largest element*/(subPoints.begin(), subPoints.end()) - subPoints.begin()]);
// newPoints.push_back(points[min_element/* find smallest element*/(subPoints.begin(), subPoints.end()) - subPoints.begin()]);
// newPoints.push_back(points[max_element/* find largest element*/(sumPoints.begin(), sumPoints.end()) - sumPoints.begin()]);
//
// return newPoints;
//}
//
//Mat getWarp(Mat img,vector<Point> points,float w,float h) {
// Point2f src[4] = { points[0],points[1],points[2],points[3] };//Point2f表示浮点数
// Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };//Point2f表示浮点数
//
// Mat matrix = getPerspectiveTransform(src, dst);
// warpPerspective(img, imgWarp, matrix, Point(w,h));
//
// return imgWarp;
//}
//
//void main() {
// string path = "Resources/paper.jpg";
// imgOriginal=imread(path);
//
// //resize(imgOriginal/*source*/, imgOriginal/*destination*/, Size()/*不定义尺寸*/, 0.5/*定义比例*/, 0.5/*定义比例*/);
//
// //预处理
// imgThre = preProcessing(imgOriginal);
// //获得轮廓--获得最大矩形
// initialPoints=getContours(imgThre);
// //drawPoints(initialPoints, Scalar(0, 0, 255));
// docPoints = reorder(initialPoints);
// //drawPoints(docPoints, Scalar(0, 255, 0));
// //扭曲
// imgWarp = getWarp(imgOriginal, docPoints, w, h);
// //裁剪多余的边--通过创建一个矩形
// int cropValue = 5;
// Rect roi(cropValue/*每条边要减去的像素*/, cropValue, w - 2 * cropValue/*宽度*/, h - 2 * cropValue/*高度*/);
// imgCrop = imgWarp(roi);
// imshow("Image", imgOriginal);
// imshow("Image Dilation", imgThre);
// imshow("Image Warp", imgWarp);
// imshow("Image Crop", imgCrop);
// waitKey(0);
//}

Project 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//学习如何检测车牌和如何裁剪并保存这些区域

#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/objdetect.hpp>//对象检测头文件
#include<iostream>

using namespace std;
using namespace cv;


/// <summary>
/// Project 3 – License Plate(车牌) Detector
/// </summary>


void main() {


VideoCapture cap(0);//相机id=0
Mat img;

//加载模型
CascadeClassifier plateCascade;/*用于对象检测的级联分类器类*/
plateCascade.load("Resources/haarcascade_russian_plate_number.xml");//从文件加载分类器(已经训练好的模型)
if (plateCascade.empty()) { cout << "XML file not loaded" << endl; }//检测文件是否加载成功

vector<Rect> plates;

while (true) {
cap.read(img);
//可以更改比例因子和最小邻居来调整检测成功率
plateCascade.detectMultiScale(img/*输入*/, plates/*输出*/, 1.1/*比例因子*/, 10/*最小邻居*/);//在输入图像中检测不同大小的对象。检测到的对象将以矩形列表的形式返回。



for (int i = 0; i < plates.size(); i++) {
Mat imgCrop = img(plates[i]);//plates是矩形列表,plates[i]是矩形
//imshow(to_string(i), imgCrop);
imwrite("Resources/Plates/" + to_string(i) + ".png", imgCrop);
rectangle(img, plates[i].tl(), plates[i].br(), Scalar(255, 0, 255), 3);//绘制矩形
}

imshow("Image", img);
waitKey(1);//增加延时,0表示无穷
}
}

Colorpicker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#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);//增加延时
// }
//}
  • Post title:OpenCV (bilibili教程代码)
  • Post author:Eva.Q
  • Create time:2021-07-26 14:21:54
  • Post link:https://qyy/2021/07/26/OPENCV/OPENCV1-1/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.