openCV (c++)

文章目录

    • openCV 配置 (C++)
    • chapter 1 读取图像、视频和摄像头
    • chapter 2 基本功能
    • chapter 3 调整大小和裁剪
    • chapter4 绘制形状和文本
    • chapter 5 Warp Perspective 透视调整
    • chapter 6 Color Detection 颜色检测
    • Chapter 7 - Shapes/Contour Detection形状/轮廓检测
    • Chapter 8 - Face Detection 人脸检测

openCV 配置 (C++)

课程链接:

https://www.bilibili.com/video/BV11A411T7rL/?spm_id_from=333.788

  1. 下载visual studio

  2. github 下载 opencv :

    Release->选择windows 的 .exe文件

    openCV (c++)_第1张图片

openCV (c++)_第2张图片

配置环境变量: 本文将opencv放在了以下路径中:

G:\github_code\rep\opencv\build\x64\vc15\bin

重启计算机

  1. 打开vs,创建c++ 工程: 并将plateform target 设置为 x64

image-20220509094323956

  1. 工程配置

    • vc++ 目录:

    ​ 包含目录:G:\github_code\rep\opencv\build\include

    ​ 库目录:G:\github_code\rep\opencv\build\x64\vc15\lib

    • 链接器:

    输入:附加依赖项 opencv_world455d.lib (版本号从

    G:\github_code\rep\opencv\build\x64\vc15\bin 可以看到)

VC++ directories:

  • 点击工程名称 -> 项目 -> 属性

openCV (c++)_第3张图片

  • 配置vc++ 的包含目录和库目录

openCV (c++)_第4张图片

  • 配置链接器以及版本号查询

openCV (c++)_第5张图片

openCV (c++)_第6张图片

  1. 测试
#include
#include
#include
#include

using namespace cv;
using namespace std;

//Images
int main() {
	string path = "Resources/test.jpg";
	Mat img = imread(path);//由Opencv 引入的矩阵数据类型
	imshow("Image", img);
	waitKey(0); // 0 :指等待事件无穷大(infinite),这样打开的图片就不会关闭
	return 0;
}

代码能够成功运行,显示图片,说明环境配置正确

chapter 1 读取图像、视频和摄像头

对于图片:由opencv引入的矩阵类型 Mat 来进行读取

对于视频:是由一系列的图片组成的,需要使用while循环读取所有的img

对于摄像头:与读取视频的方式一致,区别在于路径获取 为摄像头的编号VideoCapture cap(0); 如果只有一个摄像头,通常设置为ID=0 ,如果有多个摄像头,注意修改ID的值

#include
#include
#include
#include

using namespace cv;
using namespace std;
//----------------------------------------------------------------------//
//Images
int main() {
	string path = "Resources/test.jpg";
	Mat img = imread(path); //由Opencv 引入的矩阵数据类型
	imshow("Image", img);
	waitKey(0);
	return 0;
}
//----------------------------------------------------------------------//
//video
int main() {
	string path = "Resources/test_video.mp4"; //视频的位置
	//读取视频
	VideoCapture cap(path);
	Mat img;
	//显示视频
	while (true) {
		cap.read(img);
		imshow("Image", img);
		waitKey(20); //等待时间20ms
	}
	return 0;
}
//----------------------------------------------------------------------//
//摄像头
int main() {
	
	//读取视频
	VideoCapture cap(0);
	Mat img;
	//显示视频
	while (true) {
		cap.read(img);
		imshow("Image", img);
		waitKey(1); //等待时间1ms 
	}
	return 0;
}

chapter 2 基本功能

  1. 转换成灰度图 :

使用函数 cvtColor(src,dst,code_color,dstCn)

函数说明:将图片从一个色域转换成另一个色域。注意OpenCV的默认颜色格式是BGR而不是RGB。 code_color 可以从 ColorConversionCodes 中查看。dstCn:目标图片的通道数,如果为0,通道数自动从 src 和 code 派生

  1. 高斯模糊 : GaussianBlur(src,dst,Size(),x,y)

  2. 边缘检测:canny

  3. 腐蚀erode()膨胀dilate()

    c++ 中没有 numpy,因此使用getStructuringElement为erode和dilate创建kernal

#include
#include
#include
#include

using namespace cv;
using namespace std;

//Images
int main() {
	string path = "Resources/test.jpg";
	Mat img = imread(path);
	Mat dst_img, gauss_img, canny_img,dilate_img,erode_img;
	//颜色转换
	cvtColor(img, dst_img, ColorConversionCodes::COLOR_BGR2GRAY);
	
	//高斯模糊
	GaussianBlur(img, gauss_img, Size(7, 7), 3, 0);

	//边缘检测 canny
	Canny(gauss_img, canny_img, 50, 150);//threashold1,2  自己设定 ,可以使用拖拽栏来调节参数,从而设置这两个阈值,找到最佳检测
	
	//腐蚀erode()和膨胀dilate()
	//c++ 中没有 numpy,因此使用如下方式创建kernal,为dilate() 使用
	Mat kernal = getStructuringElement(MORPH_RECT, Size(3, 3));

	//膨胀
	dilate(canny_img, dilate_img, kernal);

	//腐蚀
	erode(canny_img, erode_img, kernal);
	
	imshow("Image", erode_img);
	waitKey(0);
	return 0;
}

chapter 3 调整大小和裁剪

  • resize

    int main() {
    	string path = "Resources/test.jpg";
    	Mat img = imread(path);
    	Mat imgResize;
    
    	cout << img.size() << endl; //查看当前图片的大小 ,显示为 [640*480]
    	//修改图片的大小为指定的宽和高
    	resize(img, imgResize, Size(320, 240));
    	//按照比例进行缩小
    	resize(img, imgResize, Size(), 0.5, 0.5);
    	imshow("img", img);
    	imshow("Image", imgResize);
    	waitKey(0);
    	return 0;
    }
    
  • 裁剪: ROI

    对于object 对其进行修剪以找到ROI (感兴趣区域)

    int main() {
    	string path = "Resources/test.jpg";
    	Mat img = imread(path);
    	Mat imgCrop;
    
    	Rect roi(100, 100, 300, 250); //定义了一个矩形的ROI,x,y, width,height
    	imgCrop = img(roi);//将roi 放到img()中,从而裁剪出一个新的图片
    
    	imshow("img", imgCrop);
    	
    	waitKey(0);
    	return 0;
    }
    

chapter4 绘制形状和文本

学习如何在图片上画 矩形、圆形,添加文本的操作

  • 画圆 :circle(图片,圆心位置,半径,颜色,粗细)(粗细用FILLED 是填充)
  • 画矩形:rectangle(图片,左上角点,右下角点,颜色,粗细)
  • 划线:line (图片,起点,重点,颜色,粗细)
  • 添加text:putText(图片,“内容”,起点,字体,字体大小,颜色)
int main() {
//Blank Image
	//Mat img(512, 512, CV_8UC3,Scalar(255,0,0)); //创建图片:0-255 (2^8 unsigned) ,3通道(C3)的图片,Scalar(255,0,0):分别代表BGR三个颜色
	Mat img(512, 512, CV_8UC3, Scalar(255, 255, 255));//创建白色的图片
	//在图片上绘制一个圆形,输入圆心、半径
	circle(img, Point(256, 256), 155, Scalar(0, 69, 255), FILLED); //FILLED 指填充颜色
	//在图片上绘制一个蓝色的矩形,输入矩形的左上角点,右下角点,颜色和线条粗细
	rectangle(img, Point(130, 266), Point(382, 286), Scalar(255, 0, 0), 2);
	//在圆形上面画一条线
	line(img, Point(130, 296), Point(382, 296), Scalar(255, 255, 255), 2);
	//text:
	putText(img, "Elio", Point(137, 262),FONT_HERSHEY_COMPLEX,0.75,Scalar(0,255,255));
	imshow("img",img);
	waitKey(0);
	return 0;
}

openCV (c++)_第7张图片

chapter 5 Warp Perspective 透视调整

在windows自带的绘图软件中打开img,在该软件的下部能够显示出图片相应点的坐标

#include
#include
#include
using namespace cv;
using namespace std;

int main() {
//读取图片
	Mat img,imgdst;
	string path = "Resources/card.jpg";
	img = imread(path);
	//设置需要变换的区域,src的四个点均为float,使用Point2f 创建
	Point2f src[4] = { {216,48},{349,25},{254,183},{416,156} };//添加扑克牌的四个点
    
    //设置扑克的宽度和长度
	float width = sqrtf(pow(src[1].x - src[0].x, 2) + pow(src[1].y - src[0].y, 2));
	float height = sqrtf(pow(src[1].x - src[2].x, 2) + pow(src[1].y - src[2].y, 2));
	cout << "宽度: " << width << "  高度:" << height << endl;
   //设置目标图片的显示坐标,注意dst和src的坐标顺序要一一对应
	Point2f dst[4] = { {0.0f,0.0f},{width,0.0f},{0.0f,height},{width,height} };

	//进行透视变换
	Mat matrix;
	matrix = getPerspectiveTransform(src, dst);
	warpPerspective(img, imgdst, matrix, Point(width, height));
    
    for(int i=0;i<4,i++){ //圈出待测区域的四个点
        circle(img,src[i],10,Scalar(0,0,255),FILLED); 
    }
	
	imshow("image", img);
	imshow("目标图片", imgdst);


	waitKey(0);
	return 0;
}

效果如下:

原图:(坐标点是自己找的)

openCV (c++)_第8张图片

效果图:

openCV (c++)_第9张图片

chapter 6 Color Detection 颜色检测

  1. 需要将图片转换为HSV space因为在HSV 中查找颜色更加容易,cvtColor(img,imgHSV,COLOR_BGR2HSV)

  2. 选择需要的颜色inRange(imgHSV,lower,upper,mask) 颜色通常设置成一个范围,例如红色可以选择从深红到浅红,因为阴影光线等会造成颜色的误差。输出是一个mask (Mat)

  3. 颜色都是用 Scalar(B,G,R) 来定义

  4. 如何找到需要的颜色范围?

    创建一个跟踪栏(track bar),opencv 中具有内置的功能,跟踪栏需要写在while 循环中

    namedWindow("名称",(大小x,y))

#include
#include
#include
#include
#include
using namespace cv;
using namespace std;

int main() {
//读取图片
	string path = "Resources/color.jpg";
	Mat img;
	img = imread(path);
//1. 将图片转成HSV
	Mat imgHSV;
	cvtColor(img, imgHSV, COLOR_BGR2HSV);

//2. 绘制颜色选择框窗口
	int hmin=0, hmax = 0, smin = 0, smax = 0, vmin = 0, vmax = 0;

	namedWindow("颜色选择", (640, 200)); //窗口名称,窗口大小
	createTrackbar("Hue Min", "颜色选择", &hmin, 179);//179:h的最大范围
	createTrackbar("Hue Max", "颜色选择", &hmax, 179);

	createTrackbar("Sat Min", "颜色选择", &smin, 255);
	createTrackbar("Sat Max", "颜色选择", &smax, 255);

	createTrackbar("Val Min", "颜色选择", &vmin, 255);
	createTrackbar("Val Max", "颜色选择", &vmax, 255);

	
	Mat mask;
    //绘制mask, 注意waitKey(1) ,将显示的内容放到while循环中,可以实时变化
	while (true) {
		Scalar lower(hmin, smin, vmin); //设置lower值
		Scalar upper(hmax, smax, vmax);//设置upper值
		inRange(imgHSV, lower, upper, mask);

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

显示效果如下:通过拖拽可以识别出不同的颜色。

openCV (c++)_第10张图片

openCV (c++)_第11张图片

Chapter 7 - Shapes/Contour Detection形状/轮廓检测

Chapter 8 - Face Detection 人脸检测

你可能感兴趣的:(opencv,计算机视觉,visual,studio)