欢迎关注我的公众号 [极智视界],获取我的更多笔记分享
大家好,我是极智视界,本文介绍一下 opencv 你真的会用吗?
OpenCV 是一个实时优化的计算机视觉库,它还支持机器学习 (ML) 和 人工智能 (AI) 的模型执行。很多深度学习领域的人在用 opencv 往往只会用一些它的 图像预处理 如 读图 (这构建了图像处理的数据结构)、resize 等基础操作,而这往往会让大家忽略一点:opencv 是个功能十分强大、齐全的计算机视觉库,你平时在用的可能只是它功能的一小部分而已。这篇文章,我们一起来看看 opencv 有哪些常用的方面。
1 opencv 做图像预处理
在做视觉图像处理的时候,第一个环节就是要加载图像,不管你的数据来源是视频流还是单张图,最基础的处理单元还是图片,而 opencv 用 cv::Mat 基本图像数据结构来定义了这一标准。基于 cv::Mat 后,咱们就可以使用很多 opencv 提供的图像处理接口,如 cv::resize (包含了丰富的插值算法实现)、cv::cvtColor (包含了丰富的通道转换实现) 等,这样一套下来基本足够满足咱们的图像预处理了。除了这些基本的图像处理接口,还有像边缘检测 (如 cv::Canny)、图像图形学操作 (如 cv::dilate、cv::erode)等。
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> void main() { std::string path = "data/test.png"; cv::Mat img = cv::imread(path); cv::Mat imgGray, imgBlur, imgCanny, imgDil, imgErode; // 图像处理:将照片转换为灰度 cv::cvtColor(img, imgGray, cv::COLOR_BGR2GRAY); // 图像处理:高斯模糊 cv::GaussianBlur(imgGray, imgBlur, cv::Size(3, 3), 3, 0); // 边缘检测:Canny边缘检测器 一般在使用Canny边缘检测器之前会做一些模糊处理 cv::Canny(imgBlur, imgCanny, 25, 75); // 创建一个可以使用膨胀的内核 cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); // 图形学:图像膨胀 cv::dilate(imgCanny, imgDil, kernel); // 图形学:图像侵蚀 cv::erode(imgDil, imgErode, kernel); }
2 opencv 做模型推理
你一定不要忘了,opencv 还能够做模型推理,而且功能也是越来越全面。而这一切都要源于 opencv 的 dnn 模块。咱们拿最新的 opencv-4.6 来看,先来看一下 cv::dnn::Backend 后端 和 cv::dnn::Target 目标平台 ,你就知道为啥说它 全面 了。
可以看到它后端的优化方法甚至还包括了编译优化HALIDE,目标平台也是十分的丰富,不只是常见的 CPU、CUDA,还有 OPENCL、FPGA、VULKAN 等。
对于深度学习模型的推理,opencv 库里封装了图像预处理函数:cv::dnn::blobFromImage,在里面可以直接做图像标准化、归一化的操作,免得再自己写好几句来实现这些功能,这就很类似 pytorch 中加载图像数据。opencv 当然也支持直接加载从成熟的训练框架出来的模型进行推理,支持的比较好的框架有:caffe、darknet、tensorflow、onnx。当然你可能还在用其他的一些训练框架,如 pytorch、mxnet,甚至国产的训练框架如pp、mindspore,这个时候因为有了 onnx,就会给你无尽的想象。
3 opencv 做相机标定
做工业视觉 或 其他场景一些视觉测量、定位领域的小伙伴对于相机标定一定不会陌生吧。因为涉及到精度、甚至是高精度;二维、设置三维,相机标定一定不是一个简单的事情,它不仅需要计算图像世界和真实世界的仿射变换(平面)/透射变换(三维),还需要解畸变。这中间涉及十分复杂的高等数学、矩阵论的推理计算。好在人们聪明,发明了 标定板 这个工具来对相机进行标定,常见的有棋盘格标定(张有正标定法)、九点标定等。这大大简化了映射变化的计算,而强大的 opencv 也对采用 标定板 进行相机标定的接口进行了实现,包括找圆(九点标定需要)、找角点(棋盘格标定需要)、计算映射矩阵等。
4 opencv 做人脸分析
上述讲的 opencv 做图像预处理、做模型推理、做相机标定主要是针对某个模块的应用,opencv 还有个强大的地方在 使用它能够快速构建应用。拿人脸检测来说,使用 opencv,你可能只需要几行代码就可以构建一个可用的人脸检测应用程序:
import cv2 import numpy as np import cv2 cap = cv2.VideoCapture(0) # 打开默认摄像头 while 1: ret, image = cap.read() # 读取摄像头 # 加载分类分类器模型 faceCascade=cv2.CascadeClassifier("opencv\haarcascade_frontalface_default.xml") gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces=faceCascade.detectMultiScale( gray, scaleFactor=1.15, minNeighbors=5, minSize=(5,5) ) # 逐个标注人脸 for (x,y,w,h) in faces: cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0),2) if cv2.waitKey(1) == 27: # 按下esc停止 break cv2.imshow("dect", image) cv2.waitKey() cv2.destroyAllWindows()
这看起来应该十分方便,除了人脸检测,使用 opencv 还可以快速构建人脸识别应用,你可以自行尝试。
5 opencv 做三方库
在实际工程中,咱们经常把 opencv 作为 3rdparty 来用,这还是源于它可以方便的做图像加载/保存 以及 图像预处理。可能会有这么一个场景:用 opencv 加载图像,做图像预处理,然后把 cv::Mat 转换为 float* 送入后续操作;甚至是 只用 opencv 加载图像,在 cv::Mat 转换到 float* 的过程中同时就把图像预处理给做了。上面的这一波操作,需要你十分清楚 cv::Mat 中的像素排布 (包括单通道、多通道的像素排布),因为你需要用指针对像素进行操作。
// 读图 cv::Mat source = cv::imread("data/test.png"); // 接收 float* 数据的变量 float *data = new float[batch * 3 * imgW * imgH]; int mat_data_id = 0; // 标准化 for (int i = 0; i < imgH; i++) { const uchar* current = source.ptr<uchar>(i); for (int j = 0; j < imgW; j++) { data[n * 3 * imgW * imgH + mat_data_id] = (current[3 * j + 0] / 255.0 - 0.48) / 0.27; // range by channel data[n * 3 * imgW * imgH + imgW * imgH + mat_data_id] = (current[3 * j + 1] / 255.0 - 0.46) / 0.26; data[n * 3 * imgW * imgH + 2 * imgW * imgH + mat_data_id] = (current[3 * j + 2] / 255.0 - 0.41) / 0.28; mat_data_id++; } } // data 接收到 float* 数据后,再进行后续操作 ...
...... (...结束不了,以上还只是部分功能)
当然,看文章不如多行动,你可以直接去 opencv 官网下载相应的库操作一波 (当然,官方下载比较慢,可以选择点我这里下载,不限速)。
- opencv4.5.2-win10&win11 安装包:https://download.csdn.net/download/weixin_42405819/86806969;
- opencv-4.5.2-source源码:https://download.csdn.net/download/weixin_42405819/86806756;
- opencv3.4.6-win10&win11 安装包:https://download.csdn.net/download/weixin_42405819/86806591;
- opencv-3.4.6-source源码:https://download.csdn.net/download/weixin_42405819/86806710
好了,以上分享了 opencv 你真的会用吗?希望我的分享能对你的学习有一点帮助。