简介
环境搭建
跳过,Windows可以去OpenCV官网下载动态库。
简单入门
图形读取与显示
cpp
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
cv::Mat src = cv::imread("D:\\python\\picture\\1.jpg",IMREAD_GRAYSCALE);//图片路径,第二个参数指定加载灰色图形
namedWindow("test",WINDOW_FREERATIO); //可以让图片全部填充满
cv::imshow("test", src);
cv::waitKey(0);
cv::destroyAllWindows();
cout << "Hello Opencv!" << endl;
return 0;
}
图形色彩空间转换
什么是HSV图像呢?
HSV 图像是一种基于人类视觉感知的颜色模型,它将颜色表示为色调(Hue)、饱和度(Saturation)和明度(Value)三个属性。HSV 模型更接近人类对颜色的感知方式,因此在某些图像处理任务中比 RGB 模型更直观和有用。
组成部分:
-
色调(Hue):
-
表示颜色的种类,通常用角度来表示,范围从 0 到 360 度。
-
0 度通常对应红色,120 度对应绿色,240 度对应蓝色,其他颜色则位于这些主色之间。
-
-
饱和度(Saturation):
-
表示颜色的纯度或强度,范围从 0(灰色)到 100%(最纯的颜色)。
-
饱和度越高,颜色越纯;饱和度越低,颜色越接近灰色。
-
-
明度(Value):
-
表示颜色的亮度,范围从 0(黑色)到 100%(白色)。
-
明度越高,颜色越亮;明度越低,颜色越暗。
-
应用:
HSV 模型在图像处理和计算机视觉中有许多应用,特别是在颜色分割和颜色识别方面。例如:
-
颜色分割:通过设置特定的色调、饱和度和明度范围,可以从图像中提取特定颜色的对象。
-
颜色校正:调整图像的色调、饱和度和明度,以改善图像的视觉效果。
-
颜色识别:识别图像中特定颜色的对象,如交通信号灯识别、水果分类等。
在OpenCV中,BGR就是RGB.
COLOR_BGR2GRAY = 6 BGR到GRAY
COLOR_GRAY2BGR = 8 GRAY到BGR
COLOR_BGR2HSV = 40 BGR到HSV
COLOR_HSV2BGR = 54 HSV到BGR
cpp
void QuickDemo::colorspace_demo( Mat& image)
{
// imshow("test",image);
Mat gray,hsv;
//这里打开的时候图片imread不能以灰度图IMREAD_GRAYSCALE打开,不然会core
cvtColor(image,hsv,COLOR_BGR2HSV);
cvtColor(image,gray,COLOR_BGR2GRAY);
imshow("hsv",hsv);
imshow("gray",gray);
imwrite("./gray.png",gray);
imwrite("./hsv.png",hsv);
}
图像对象的创建和赋值

cpp
void QuickDemo::mat_cration_demo(Mat &image)
{
Mat dst1,dst2 ;
dst1 = image.clone(); //深拷贝
image.copyTo(dst2); //深拷贝
Mat dst3 = image;//浅拷贝
// cout << image.data<<endl;//char*指针 image是三维数组
cout <<"clonse "<< (image.data == dst1.data )<<endl;
cout <<"copyto "<< (image.data == dst2.data)<<endl;
cout <<"=== "<< (image.data == dst3.data)<<endl;
//创建空白图像
Mat m3 = Mat::zeros(Size(8,8),CV_8UC3); //全是0zeros CV_8UC1
// m3 = 100; //赋值第一个通道
m3 = Scalar(2,3,4);//同时给3通道赋值
printf("width:%d height:%d,channels:%d\n",m3.rows,m3.cols,m3.channels());
cout<< m3<<endl;
}
图像像素的读写操作
图像像素的算术操作
图像几何形状绘制
cpp
void QuickDemo::drawing_demo(Mat &image)
{
//电脑屏幕的坐标系是左上角
//数学坐标是屏幕中心。
Rect rect;
rect.x = 10;
rect.y = 10;
rect.width = 100;
rect.height = 100;
Mat bg = Mat::zeros(image.size(),image.type());
rectangle(bg,rect,Scalar(0,0,255),-1,8,0);
circle(bg,Point(100,100),15,Scalar(0,255,0),2,8,0);
line(bg,Point(10,10),Point(100,100),Scalar(255,0,0),10,LINE_AA,0);
RotatedRect rrt;
rrt.center = Point(50,50);
rrt.size = Size(20,20);
rrt.angle = 0;
ellipse(bg,rrt,Scalar(0,255,255),4,LINE_AA);
Mat dst;
addWeighted(image,0.7,bg,0.3,0,dst);
imshow("drawing_demo",dst);
}
人脸检测
cpp
#include <iostream>
#include <opencv2/opencv.hpp>
#include "quickdemo.h"
using namespace std;
using namespace cv;
int main()
{
#if 1
// 路径使用双反斜杠或原始字符串字面量
std::string pb_path = "D:/C++/project/OpenCV/opencv_tutorial_data/models/face_detector/opencv_face_detector_uint8.pb";
std::string pbtxt_path ="D:/C++/project/OpenCV/opencv_tutorial_data/models/face_detector/opencv_face_detector.pbtxt";
// std::string pb_path = "D:/C++/project/OpenCV/cmake_test/opencv_face_detector_uint8.pb";
// std::string pbtxt_path ="D:/C++/project/OpenCV/cmake_test/opencv_face_detector.pbtxt";
// 加载模型
dnn::Net net = cv::dnn::readNetFromTensorflow(pb_path, pbtxt_path);
VideoCapture cap(0);
Mat frame;
while (1)
{
cap.read(frame);
if (frame.empty())
{
continue;
}
Mat blob = dnn::blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false);
net.setInput(blob);
Mat probs = net.forward();
// 1 x1 xNx7
Mat detectMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());
for (int row = 0; row < detectMat.rows; row++)
{
float conf = detectMat.at<float>(row, 2);
if (conf > 0.5)
{
float x1 = detectMat.at<float>(row, 3) * frame.cols;
float y1 = detectMat.at<float>(row, 4) * frame.rows;
float x2 = detectMat.at<float>(row, 5) * frame.cols;
float y2 = detectMat.at<float>(row, 6) * frame.rows;
Rect box(x1, y1, x2 - x1, y2 - y1);
rectangle(frame, box, Scalar(0, 0, 255), 2, 8);
}
}
flip(frame,frame,1); //镜像翻转 左右互换
imshow("Opencv人脸检测", frame);
char c = waitKey(1);
if (c == 27)
break;
}
// 确保所有窗口都被关闭
return 0;
#endif
}