C++ opencv (一):基础代码入门

本文介绍了使用OpenCV进行C++编程的基础知识,包括读取图片和视频、图像转换、模糊处理、边缘检测、缩放裁剪、形状绘制、透视变换、颜色检测以及轮廓分析。

opencv学习资料声明

对于C++ 不熟悉的伙伴,强推这版学习资源!
B站学习资源:4h上手C++版Opencv
安装opencv包以及添加包含目录、库目录和附加依赖项看视频即可
以下是我的学习B站视频和知乎大神笔记整理与自己所在领域——医学图像处理相关的实践和学习笔记!

1.基础知识

1.1 Read Images Videos and Webcams

示例:

#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>//输入输出流

using namespace cv;
using namespace std;


/////////////////  Images  //////////////////////

void main() {

	string path = "Resources/test.png";
	//1.读取:imread读取到Mat类型的 img中
	Mat img = imread(path);  
	//检测image有无数据,无数据 img.empty()返回真
	if (img.empty())  
	{
		cout << "Could not open or find the image" << endl;
		return -1;
	}
	cout << "图像的行数为: " << image1.rows << endl;  //获取图像的高度,行数;
	cout << "图像的列数为: " << image1.cols << endl;  //获取图像的宽度,列数;
	cout << "图像的通道数为: " << image1.channels() << endl;  //获取图像的通道数,彩色图=3,灰度图=1;
	cout << "图像的尺寸为: " << image1.size << endl;  //获取图像的尺寸,行*列;
	//2.保存:imwrite保存图像为png格式
	imwrite("Resources/test_save.png", img); 
	//3.显示:imshow窗口显示图像
	imshow("Image", img);   
	waitKey(0);

}

///////////////  Video  //////////////////////

//void main() {
//
//	string path = "Resources/test_video.mp4";
//	VideoCapture cap(path);
//	Mat img;
//
//	while (true) {
//
//		cap.read(img);
//		imshow("Image", img);
//		waitKey(20);
//	}
//}

/////////////////  Webcam  //////////////////////

//void main() {
//
//	VideoCapture cap(0);
//	Mat img;
//
//	while (true) {
//
//		cap.read(img);
//		imshow("Image", img);
//		waitKey(1);
//	}
//}

imread读取图像的方式有三种:
① 彩色:

imread(path, IMREAD_COLOR);
or
imread(path, 1);

②灰度:

imread(path,  IMREAD_GRAYSCALE);
or
imread(path, 0);

③alpha通道:

为实现图形的透明效果,采取在图形文件的处理与存储中附加上另一个8位信息的方法,这个附加的代表图形中各个素点透明度的通道信息就被叫做Alpha通道。Alpha通道使用8位二进制数,就可以表示256级灰度,即256级的透明度。

imread(path,  IMREAD_UNCHANGED);
or
imread(path, -1);

1.2 Basic Functions

基本的图像处理操作(依次增加操作):
图像转换(cvtColor)
图像模糊(GaussianBlur)
图像边缘检测(Canny)
图像边缘扩大(dilate)
图像边缘侵蚀(erode)\

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

using namespace cv;
using namespace std;

///////////////  Basic Functions  //////////////////////

void main() {

	string path = "Resources/test.png";
	Mat img = imread(path);
	Mat imgGray, imgBlur, imgCanny, imgDil, imgErode;

	cvtColor(img, imgGray, COLOR_BGR2GRAY); //BGR——GRAY
	GaussianBlur(imgGray, imgBlur, Size(7, 7), 5, 0); // 高斯模糊 Size(7, 7), 5, 控制模糊程度
	Canny(imgBlur, imgCanny, 25,75); // 边缘检测,使用前常进行模糊处理 ,75 控制边缘数(越大边缘越少)
    //Q:边缘检测后部分边缘没有被完全填充
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); //创建膨胀内核
	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);
}

imshow图像展示:
请添加图片描述
请添加图片描述

1.3 Resize and Crop

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

using namespace cv;
using namespace std;


///////////////  Resize and Crop //////////////////////

void main() {

	string path = "Resources/test.png";
	Mat img = imread(path);
	Mat imgResize, imgCrop;

	//cout << img.size() << endl; //在终端打印图像宽高
	resize(img, imgResize, Size(),0.5,0.5); //可按比例resize,也可以给实际的数字

	Rect roi(200, 100, 300, 300); //矩形数据类型 rectangle,定位左上角的点,并给出矩形size
	imgCrop = img(roi);

	imshow("Image", img);
	imshow("Image Resize", imgResize);
	imshow("Image Crop", imgCrop);
	waitKey(0);
}

1.4 Draw Shapes and Text

圆(circle)
框(rectangle)
线(line)
显示内容(putText)\

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

using namespace cv;
using namespace std;

//////////////  Draw Shapes and Text //////////////////////

void main() {

	// Blank Image 
	Mat img(512, 512, CV_8UC3, Scalar(255, 255, 255));

	circle(img, Point(256, 256), 155, Scalar(0, 69, 255),FILLED); //Point表示圆心;155表示圆的半径; FILLED填满,数字表示线的粗细
	rectangle(img, Point(130, 226), Point(382, 286), Scalar(255, 255, 255), FILLED); //定义左上角和右下角
	line(img, Point(130, 296), Point(382, 296), Scalar(255, 255, 255), 2);
	
	putText(img, "Murtaza's Workshop", Point(137, 262), FONT_HERSHEY_DUPLEX, 0.75, Scalar(0, 69, 255),2);//0.75字体大小,2字体粗细

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

1.5 Warp Images

透视转换

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

using namespace cv;
using namespace std;

///////////////  Warp Images  //////////////////////

void main() {

	string path = "Resources/cards.jpg";
	Mat img = imread(path);
	Mat matrix, imgWarp;
	float w = 250, h = 350; // 目标转换大小
	
	Point2f src[4] = { {529,142},{771,190},{405,395},{674,457} }; //定位目标点
	Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} }; //定义目标点顺序

	matrix = getPerspectiveTransform(src, dst);
	warpPerspective(img, imgWarp, matrix, Point(w, h));

	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);

}

请添加图片描述

1.6 Color Detection

图像转换为HSV空间,更容易查找颜色
创建色调可调节滑动窗口

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

using namespace cv;
using namespace std;

///////////////  Color Detection  //////////////////////

void main() {

	string path = "Resources/lambo.png";
	Mat img = imread(path);
	Mat imgHSV, mask;
	int hmin = 0, smin = 110, vmin = 153;
	int hmax = 19, smax = 240, vmax = 255;

	cvtColor(img, imgHSV, COLOR_BGR2HSV);

	namedWindow("Trackbars", (640, 200));
	createTrackbar("Hue Min", "Trackbars", &hmin, 179);
	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) {

		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);
	}
}

请添加图片描述

1.7 Shape/Contour Detection

使用颜色进行对象检测和跟踪
存在问题:图像在放大后像素间存在间隙(为什么在1.2小节中进行膨胀的原因)

请添加图片描述

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

using namespace cv;
using namespace std;

///////////////  Color Detection  //////////////////////

void getContours(Mat imgDil, Mat img) {

	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;

	findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	//drawContours(img, contours, -1, Scalar(255, 0, 255), 2);
    //扩张,轮廓,层次,方法  
	vector<vector<Point>> conPoly(contours.size());
	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) 
		{
			float peri = arcLength(contours[i], true);
			approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);
			cout << conPoly[i].size() << endl;
			boundRect[i] = boundingRect(conPoly[i]);
		
			int objCor = (int)conPoly[i].size();

			if (objCor == 3) { objectType = "Tri"; }
			else if (objCor == 4)
			{ 
				float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height;
				cout << aspRatio << endl;
				if (aspRatio> 0.95 && aspRatio< 1.05){ objectType = "Square"; }
				else { objectType = "Rect";}
			}
			else if (objCor > 4) { objectType = "Circle"; }

			drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
			rectangle(img, boundRect[i].tl(), boundRect[i].br(), 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);
	Mat imgGray, imgBlur, imgCanny, imgDil, imgErode;

	// Preprocessing
	cvtColor(img, imgGray, COLOR_BGR2GRAY);
	GaussianBlur(imgGray, imgBlur, Size(3, 3), 3, 0);
	Canny(imgBlur, imgCanny, 25, 75);
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
	dilate(imgCanny, imgDil, kernel);

	getContours(imgDil,img);

	imshow("Image", img);
	//imshow("Image Gray", imgGray);
	//imshow("Image Blur", imgBlur);
	//imshow("Image Canny", imgCanny);
	//imshow("Image Dil", imgDil);

	waitKey(0);

}

课程目的:OpenCV是应用非常广泛的开源视觉处理库,在图像处理、计算机视觉和自动驾驶中有着非常重要的作用。课程设计特色:(课程当前为第期)1、C++与Python双语教学Python语言是在计算机视觉中应用最多的语言,在工作中,深度学习模型的训练基本上都是使用Python语言编写的训练代码OpenCV在这个过程中用于图像的预处理(例如图像读取、数据增强)和后处理,还可以用于显示处理的结果,功能强大,使用方便。但是在功能的部署的时候,不管是部署在服务端还是PC端,开发语言基本上用的是C++,所以如何有效的使用OpenCV进行模型或者功能的部署尤为重要。C++语言应用的好坏,在面试中可以看出个面试者的工程实践能力的强弱,两种语言开发掌握好了可以使工作如虎添翼。2、全模块讲解我出版了本图书《学习OpenCV4:基于Python的算法实战》,虽然这本书是写的基于Python的算法实战,但是实际上这本书有详细的介绍算法的C++接口,还有C++方向的案例,是以Python为主。图书出版的时候就想双语写作,只是限于篇幅没有成行。本课程不仅采用双语教学,更是对C++的每个模块都做讲解,我们知道,很多的书其实只讲imgproc,如果你翻开本书图像的形态学运算和图像滤波都是作为独立章节讲解的,那么这本书基本上就可以确定是只是讲解了imgproc模块,但是其他的模块在工作中也有很重要的作用。例如:core模块定义了C++的基本数据结构和基本运算(如四则运算);highgui模块是可视化与交互的模块;feature2d是特征点与特征匹配相关算法所在的模块;ml是机器学习相关的模块;dnn是深度学习相关的模块,可以使用OpenCV进行深度学习模型的部署。这些是很多的书和课程都不会讲的。3、讲解细致本课程会从环境搭建开始讲解,环境搭建尤为重要。从我多年的授课经验总结来看,如果只是给了代码,很多的入门用户环境问题处理不好的话,后面的学习很难进行下去,甚至会丧失学习的信心。4、会讲解C++和Python的开发语法问题是入门用户的大难关,特别是C++语言。大学只是教授了C语言相关的内容,C++很多同学只懂点皮毛,所以写代码步履维艰,我们在讲解代码的过程中会顺带讲解C++和Python的内容。我们还会讲解编译相关知识,还有库的装载与链接,这些是学校里不会教的,目前也几乎没有课程讲解。5、讲师经验丰富我讲解过C++OpenCV的多个课程,广受学员好评。我出版过两本图书《深度学习计算机视觉实战》和《学习OpenCV4》,两本书都是细致入微的讲解,主要针对的就是初学者,所以能够很好的处理课程的难易程度。6、讲义准备充分讲义准备的充分细致,标识清楚明确,重点和疑难点突出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值