Jizhi AI | opencv, savez-vous vraiment comment l'utiliser ?

  Travailler ensemble pour créer et grandir ensemble ! C'est le 12ème jour de ma participation au "Nuggets Daily New Plan · October Update Challenge" Cliquez voir les détails de l'événement

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

  Bonjour à tous, je suis Jizhi Vision. Cet article présente opencv. Savez-vous vraiment comment l'utiliser ? .

   OpenCV est une bibliothèque de vision par ordinateur optimisée en temps réel qui prend également en charge l'exécution de modèles pour l'apprentissage automatique (ML) et l'intelligence artificielle (IA). De nombreuses personnes dans le domaine de l'apprentissage en profondeur n'utilisent souvent qu'une partie de son prétraitement d'image, comme la lecture d'image (qui construit la structure de données du traitement d'image), le redimensionnement et d'autres opérations de base lors de l'utilisation d'opencv, ce qui fait souvent ignorer un point : opencv est une fonction Une bibliothèque de vision par ordinateur très puissante et complète, vous n'utilisez peut-être qu'une petite partie de ses fonctions . Dans cet article, examinons les aspects communs d'opencv.

1 opencv fait le prétraitement des images

  Lorsque vous effectuez un traitement d'image visuelle, la première étape consiste à charger l'image. Peu importe que votre source de données soit un flux vidéo ou une image unique, l'unité de traitement la plus élémentaire est toujours une image et opencv utilise la structure de données d'image de cv::Matbase pour la définir. .norme. Basé cv::Matsur , nous pouvons utiliser de nombreuses interfaces de traitement d'image fournies par opencv, telles que cv::resize (包含了丰富的插值算法实现), cv::cvtColor (包含了丰富的通道转换实现)etc. Cet ensemble est fondamentalement suffisant pour satisfaire notre prétraitement d'image. En plus de ces interfaces de traitement d'image de base, il existe des éléments tels que la détection des contours (par exemple cv::Canny), les opérations graphiques d'image (par exemple cv::dilate, cv::erode), etc.

#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 fait l'inférence de modèle

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


  Eh bien, l'opencv partagé ci-dessus, savez-vous vraiment comment l'utiliser ? J'espère que mon partage pourra vous aider un peu dans votre étude.


 【Transmission des numéros publics】

"Jizhi AI | opencv savez-vous vraiment comment l'utiliser ?


logo_show.gif

Guess you like

Origin juejin.im/post/7157979206993838094