极智AI | opencv 你真的会用吗?

  携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 12 天 点击查看活动详情

欢迎关注我的公众号 [极智视界],获取我的更多笔记分享

  大家好,我是极智视界,本文介绍一下 opencv 你真的会用吗?

   OpenCV 是一个实时优化的计算机视觉库,它还支持机器学习 (ML) 和 人工智能 (AI) 的模型执行。很多深度学习领域的人在用 opencv 往往只会用一些它的 图像预处理 如 读图 (这构建了图像处理的数据结构)、resize 等基础操作,而这往往会让大家忽略一点:opencv 是个功能十分强大、齐全的计算机视觉库,你平时在用的可能只是它功能的一小部分而已。这篇文章,我们一起来看看 opencv 有哪些常用的方面。

1 opencv 做图像预处理

  在做视觉图像处理的时候,第一个环节就是要加载图像,不管你的数据来源是视频流还是单张图,最基础的处理单元还是图片,而 opencv 用 cv::Mat 基本图像数据结构来定义了这一标准。基于 cv::Mat 后,咱们就可以使用很多 opencv 提供的图像处理接口,如 cv::resize (包含了丰富的插值算法实现)cv::cvtColor (包含了丰富的通道转换实现) 等,这样一套下来基本足够满足咱们的图像预处理了。除了这些基本的图像处理接口,还有像边缘检测 (如 cv::Canny)、图像图形学操作 (如 cv::dilatecv::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);
}
复制代码

WX20221024-134924@2x.png

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 官网下载相应的库操作一波 (当然,官方下载比较慢,可以选择点我这里下载,不限速)。


  好了,以上分享了 opencv 你真的会用吗?希望我的分享能对你的学习有一点帮助。


 【公众号传送】

《极智AI | opencv 你真的会用吗?》


logo_show.gif

猜你喜欢

转载自juejin.im/post/7157979206993838094