[Aprendizaje de OpenCV] "Introducción a la programación de OpenCV3" - Mao Xingyun 01 Encuentro con OpenCV (conceptos básicos y arquitectura básica de OpenCV) y aplicaciones en el sistema ROS (implementación de Python)

Notas de estudio para el primer capítulo de "Introducción a la programación OpenCV3": Comprenda qué es la visión por computadora, qué es OpenCV y las conexiones entre ellos, etc.

PD: Este libro se publicó en 2014 y la versión y la interfaz de opencv también son algo inconsistentes con las actuales. Tomé esta nota principalmente para aprender los conceptos básicos y principios operativos de opencv. Gracias al maestro Qianmo, este libro van de la mano con los pensamientos de Qianmo.

PD: Como nota de estudio, mi idea es leer primero este libro en detalle y luego memorizar los puntos de conocimiento clave para formar mi propia estructura para aprender opencv.

El mapa mental es el siguiente:

 

Tabla de contenido

1.1 Cognición de conceptos periféricos OpenCV

         1.1.1 Procesamiento de imágenes, visión por computadora y OpenCV

         1.1.2 Descripción general de OpenCV

         1.1.3 Origen y desarrollo

         1.1.4 Descripción general de la aplicación

1.2 Análisis de la arquitectura básica de OpenCV

1.3 Qué trae OpenCV3

1.4 Descarga, instalación y configuración de OpenCV

1.5 Comience rápidamente con el procesamiento de imágenes OpenCV

1.5.1 Lectura de imágenes y visualización de imágenes

1.5.2 Corrosión de la imagen

1.5.3 Imagen borrosa

1.5.4 Detección de bordes

 1.6 Conceptos básicos de operación de video OpenCV

1.6.1 Leer y reproducir vídeo

1.6.2 Llamar a la cámara para recopilar imágenes


1.1 Cognición de conceptos periféricos OpenCV

1.1.1 Procesamiento de imágenes, visión por computadora y OpenCV

       El procesamiento de imágenes se refiere al análisis informático de imágenes para lograr el efecto deseado y generalmente incluye tres partes: compresión, mejora y restauración de imágenes, comparación, descripción y reconocimiento.

        El procesamiento de imágenes generalmente se refiere al procesamiento de imágenes digitales, que se refiere a una gran matriz bidimensional capturada por cámaras industriales, cámaras de video, escáneres y otros equipos. Los elementos de esta matriz se denominan píxeles y sus valores se denominan valores de escala de grises. El procesamiento de imágenes digitales es un método y una tecnología que utiliza computadoras para eliminar ruido, mejorar, restaurar, segmentar y extraer características de las imágenes.

       La visión por computadora se refiere al uso de cámaras y computadoras en lugar de ojos humanos para realizar visión artificial, como el reconocimiento, seguimiento y medición de objetivos, y además realiza el procesamiento de gráficos.

La diferencia         entre el procesamiento de imágenes y la visión por computadora es que el procesamiento de imágenes se enfoca en "procesar" imágenes, como mejora, restauración, eliminación de ruido, segmentación, etc.; mientras que la visión por computadora se enfoca en usar computadoras para simular la visión humana, por lo que la simulación es visión por computadora. objetivo final del campo.

 1.1.2 Descripción general de OpenCV

        OpenCV (Biblioteca de visión por computadora de código abierto) es una biblioteca de visión por computadora multiplataforma basada en distribución de código abierto que implementa algoritmos generales en procesamiento de imágenes y visión por computadora.

        OpenCV fue establecido por Intel en 1999 y ahora cuenta con el respaldo de Willow Garage. Es una biblioteca de visión por computadora multiplataforma basada en una distribución de código abierto y puede ejecutarse en Linux, Windows, Mac OS, Android, iOS y otros sistemas operativos. OpenCV consta de una serie de funciones C y clases C ++, que son livianas y eficientes, y también proporciona interfaces en C ++, Python, Ruby, MATLAB y otros lenguajes, e implementa muchos algoritmos comunes en el procesamiento de imágenes y la visión por computadora.

El objetivo de diseño          de OpenCV es ejecutarse lo más rápido posible, centrándose principalmente en aplicaciones en tiempo real. Está escrito en código C/C++ optimizado y puede aprovechar al máximo los procesadores multinúcleo; su objetivo principal es establecer un marco de visión por computadora simple y fácil de usar para ayudar a los desarrolladores a diseñar aplicaciones de visión por computadora más complejas de manera más rápida y conveniente. .

         OpenCV cubre múltiples áreas de aplicación de la visión por computadora , como inspección de productos en fábrica, imágenes médicas, seguridad de la información, interfaz de usuario, calibración de cámaras, visión estéreo y robótica.

 Página de inicio del sitio web oficial de OpenCV: Inicio - OpenCV

 Página de inicio de OpenCV Github: https://github.com/Itseez/opencv

       Página de inicio Wiki de la placa de desarrollo OpenCV: http://code.opencv.org

 1.1.3 Origen y desarrollo

        Intel lanzó por primera vez el proyecto OpenCV en 1999 para promover aplicaciones con uso intensivo de CPU.

        Con la ayuda del equipo de biblioteca de rendimiento de Intel, OpenCV implementó algunos códigos y algoritmos centrales y los envió al equipo de biblioteca de Intel en Rusia. A partir de ahí, el nacimiento de OpenCV se originó en Intel y se implementó y optimizó en Rusia.

        Al principio, OpenCV tenía los siguientes tres objetivos :

  •  Proporcionar código fuente abierto y optimizado para aplicaciones de visión básicas para evitar "hacer cosas a puerta cerrada"
  • Proporciona un marco común para difundir el conocimiento visual y el código es fácil de leer y reescribir.
  • El protocolo adoptado por la biblioteca OpenCV no requiere que los productos comerciales continúen desarrollando código y promueve el desarrollo de aplicaciones comerciales basadas en visión.

 1.1.4 Descripción general de la aplicación

  • la interacción persona-ordenador
  • reconocimiento de objetos
  • partición de imagen
  • Reconocimiento facial
  • Reconocimiento de acción
  • Seguimiento deportivo
  • robot 

 1.2 Análisis de la arquitectura básica de OpenCV

Eche un vistazo a la arquitectura de componentes de OpenCV         a través del almacenamiento clasificado de archivos de encabezado en el directorio de inclusión en la ruta de instalación de OpenCV .

        Ingrese al directorio ..\opencv\build\include y podrá ver las dos carpetas opencv y opencv2. opencv es el archivo de encabezado de la versión anterior y opencv2 es el archivo de encabezado de la nueva versión.

         En el directorio ..\opencv\build\include\opencv2, hay un archivo llamado opecv_modules.hpp, que almacena el código de descripción relacionado con la construcción de nuevos módulos en OpenCV2, que define las macros de todos los componentes en OpenCV2.

Este método debe ser coherente con opencv3, la única diferencia es la actualización.

OpenCV todos los módulos
Nombre del módulo Contenido del módulo
【calib3d】 La abreviatura combinada de Calibración y 3D. Principalmente relacionado con la calibración de la cámara y la reconstrucción tridimensional, incluidos algoritmos geométricos básicos de múltiples vistas, calibración de una sola cámara, estimación de la pose del objeto, algoritmos de similitud estéreo, reconstrucción de información 3D, etc.
【contribuir】 Abreviatura de Stuf Contribuido/Experimental. Se han añadido nuevas tecnologías como el reconocimiento facial, la comparación estéreo y los modelos de retina artificial.
【centro】 Módulos funcionales principales
  • Estructura de datos básica de OpenCV
  • estructuras de datos dinámicas
  • función de trazado
  • Funciones relacionadas con la operación de matriz
  • Accesibilidad y funciones y macros del sistema.
  • Interoperabilidad con OpenGL
【imgproc】 La abreviatura de las dos palabras Imagen y Proceso. Módulo de procesamiento de imágenes.
  • Filtrado de imágenes lineales y no lineales.
  • Transformación geométrica de imágenes.
  • Conversión de imágenes varias
  • Relacionado con el histograma
  • Análisis estructural y descripción de formas.
  • Análisis de movimiento y seguimiento de objetos.
  • Detección de características
  • Detección de objetivos y otros contenidos
【características2d】

marco funcional 2D

  • Detección y descripción de características
  • Interfaz común de detectores de funciones
  • Interfaz común de extractores de descriptores (extractores de descripciones)
  • Interfaz común de Descriptor Matchers (Description Matchers)
  • Interfaz común del comparador de descriptores genéricos
  • Función de dibujo de puntos clave y función de dibujo de función coincidente
【flanco】

Biblioteca de algoritmos de búsqueda rápida del vecino más cercano aproximado de alta dimensión

  • Búsqueda rápida aproximada del vecino más cercano
  • agrupamiento
【gpu】 Uso de módulos de visión por computadora acelerados por GPU
【gui alto】 La interfaz gráfica de usuario GUI de alto nivel incluye entrada y salida de medios, captura de video, codificación y decodificación de imágenes y videos, interfaces de interfaz gráfica interactiva, etc.
【legado】 Algunas bases de código obsoletas
【ml】

Módulo de aprendizaje automático, básicamente modelos estadísticos y algoritmos de clasificación.

  • modelo estadístico
  • Clasificador bayesiano general
  • K-vecino más cercano
  • Máquinas de vectores de soporte
  • árbol de decisión
  • promover
  • Árbol potenciado de gradiente
  • número aleatorio
  • Números súper aleatorios
  • Maximización de expectativas
  • Redes neuronales
  • DatosML
【no libre】 Algunos módulos de algoritmos patentados, incluida la detección de funciones y el contenido relacionado con la GPU
【detección de objetos】 El módulo de detección de objetivos incluye Clasificación en cascada y SVM latente.
【ocl】 Módulo de componente de visión por computadora acelerado usando OpenCL
【foto】

包含图像修复和图像去噪两部分

【stitching】 图像拼接模块
  • 拼接流水线
  • 特点寻找和匹配图像
  • 估计旋转
  • 自动校准
  • 图片歪斜
  • 接缝估测
  • 曝光补偿
  • 图片混合
【superres】 超分辨率技术的相关功能模块
【ts】 OpenCV测试相关代码
【video】 视频分析组件,包括运动估计、背景分离、对象跟踪等视频处理相关内容
【Videostab】 视频稳定相关组件

可以这么说,OpenCV就是多模块组合的SDK。


 1.3 OpenCV3带来了什么

这部分可能有点过时了,就跳过了,有兴趣的读者可以读读文中相关部分。


1.4 OpenCV的下载、安装与配置

 同理,根据自身设备进行下载安装。

我使用的是ROS系统,20.04 noetic,那么使用以下命令就可以进行安装了

$ sudo apt install ros-noetic-vision-opencv libopencv-dev python3-opencv 

默认安装的版本是opencv4,安装好后的文件放置在/usr/include/opencv4/opencv2中,上文提及到的opecv_modules.hpp同样放置在此文件夹中,其中涉及的模块会有所不同

#define HAVE_OPENCV_ARUCO
#define HAVE_OPENCV_BGSEGM
#define HAVE_OPENCV_BIOINSPIRED
#define HAVE_OPENCV_CALIB3D
#define HAVE_OPENCV_CCALIB
#define HAVE_OPENCV_CORE
#define HAVE_OPENCV_DATASETS
#define HAVE_OPENCV_DNN
#define HAVE_OPENCV_DNN_OBJDETECT
#define HAVE_OPENCV_DNN_SUPERRES
#define HAVE_OPENCV_DPM
#define HAVE_OPENCV_FACE
#define HAVE_OPENCV_FEATURES2D
#define HAVE_OPENCV_FLANN
#define HAVE_OPENCV_FREETYPE
#define HAVE_OPENCV_FUZZY
#define HAVE_OPENCV_HDF
#define HAVE_OPENCV_HFS
#define HAVE_OPENCV_HIGHGUI
#define HAVE_OPENCV_IMG_HASH
#define HAVE_OPENCV_IMGCODECS
#define HAVE_OPENCV_IMGPROC
#define HAVE_OPENCV_LINE_DESCRIPTOR
#define HAVE_OPENCV_ML
#define HAVE_OPENCV_OBJDETECT
#define HAVE_OPENCV_OPTFLOW
#define HAVE_OPENCV_PHASE_UNWRAPPING
#define HAVE_OPENCV_PHOTO
#define HAVE_OPENCV_PLOT
#define HAVE_OPENCV_QUALITY
#define HAVE_OPENCV_REG
#define HAVE_OPENCV_RGBD
#define HAVE_OPENCV_SALIENCY
#define HAVE_OPENCV_SHAPE
#define HAVE_OPENCV_STEREO
#define HAVE_OPENCV_STITCHING
#define HAVE_OPENCV_STRUCTURED_LIGHT
#define HAVE_OPENCV_SUPERRES
#define HAVE_OPENCV_SURFACE_MATCHING
#define HAVE_OPENCV_TEXT
#define HAVE_OPENCV_TRACKING
#define HAVE_OPENCV_VIDEO
#define HAVE_OPENCV_VIDEOIO
#define HAVE_OPENCV_VIDEOSTAB
#define HAVE_OPENCV_VIZ
#define HAVE_OPENCV_XIMGPROC
#define HAVE_OPENCV_XOBJDETECT
#define HAVE_OPENCV_XPHOTO

1.5 快速上手OpenCV图像处理

1.5.1 读取图像与图像显示

读取图像只需要使用imread函数即可,图像显示只需要使用imshow函数即可。

#!/usr/bin/env python3
import rospy
import cv2

rospy.init_node("showimg") 
img = cv2.imread("/home/spark/Pictures/bluebox.png")
cv2.imshow('box',img)
cv2.waitKey(0)

然后在终端输入以下命令:

rosrun opencv_learn showimg.py

 那么,对代码部分进行解析:

  1. #!/usr/bin/env python3  #告诉操作系统执行这个脚本的时候,调用/usr/bin下的python3解释器
  2. import rospy #导入ros python库
    import cv2 #导入opencv的库
  3. rospy.init_node("showimg")  #初始化ros节点,创建名为showmsg的节点
  4. img = cv2.imread("/home/spark/Pictures/bluebox.png") #使用imread读取绝对路径下的图片文件
  5. cv2.imshow('box',img) #使用imshow函数,后面接的是显示的窗口名和显示对象
  6. cv2.waitKey(0) #调用waitKey函数等待按键按下,以便让窗口一直显示,直到有按键按下

 由于在显示过程中,图像窗口过于大,影响到观察与操作了,所以添加窗口调节大小的部分:

#!/usr/bin/env python3
import rospy
import cv2

rospy.init_node("showimg") 
img = cv2.imread("/home/spark/Pictures/bluebox.png")
cv2.namedWindow("box",0)
cv2.resizeWindow("box",500,500)
cv2.imshow('box',img)
cv2.waitKey(0)

  1.  cv2.namedWindow("box",0) # 创建一个空窗口,名为box
  2. cv2.resizeWindow("box",500,500) # 调整窗口的大小,指定窗口的名称,设置宽度与高度 

 如此,就能方便用户观察了。
 

1.5.2 图像腐蚀

图像腐蚀是指用图像中的暗色部分“腐蚀”掉图像中的高亮部分。

使用getStructuringElement函数获取指定形状和尺寸结构元素,代表进行腐蚀操作时使用的结构类型。

#!/usr/bin/env python3
import rospy
import cv2

rospy.init_node("showimg") 
img = cv2.imread("/home/spark/Pictures/bluebox.png")
cv2.namedWindow("erode_box",0)
cv2.resizeWindow("erode_box",500,500)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(15,15))
img = cv2.erode(img,kernel)

cv2.imshow('erode_box',img)
cv2.waitKey(0)

 然后在终端输入以下命令:

rosrun opencv_learn erodeimg.py

 基本的读取操作没有变化,只是在此基础上添加了腐蚀的操作

1. kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(15,15))

定义一个kernel核心,由getStructuringElement函数设定一个结构类型

cv2.getStructuringElement(shape, ksize) 
  • shape:代表形状类型
    • cv2. MORPH_RECT:矩形结构元素,所有元素值都是1
    • cv2. MORPH_CROSS:十字形结构元素,对角线元素值都是1
    • cv2. MORPH_ELLIPSE:椭圆形结构元素
  • ksize:代表形状元素的大小

2.  img = cv2.erode(msg,kernel)

	dst	=	cv.erode(	src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]	)

其中:

  • src 是需要腐蚀的原始图像
  • kernel 代表腐蚀操作时所采用的结构类型。
  • anchor 代表element结构中锚点的位置,默认为(-1,-1),在核的中心位置。
  • iterations 是腐蚀操作的迭代的次数,默认为1
  • borderType 代表边界样式

opencv官方文档 cv2.erodehttps://docs.opencv.org/4.1.2/d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb

1.5.3 图像模糊

使用均值滤波操作的blur函数

#!/usr/bin/env python3
import rospy
import cv2

rospy.init_node("blurimg") 
img = cv2.imread("/home/spark/Pictures/bluebox.png")
cv2.namedWindow("blurbox",0)
cv2.resizeWindow("blurbox",500,500)

img = cv2.blur(img,(15,15))

cv2.imshow('blurbox',img)
cv2.waitKey(0)

 

 dst = blur(src, ksize, dst=None, anchor=None, borderType=None)

均值滤波器,也称低通滤波器
顾名思义,均值滤波器即对滤波核内的数据求均值,然后将这个值赋值给矩阵核心位置。
均值滤波器可以使用cv2.blur() 方法实现

  • src:图像
  • ksize:滤波核大小,使用元组表示,如(a,b)a表示height(高度),b表示width(宽度)。
  • anchor:波核锚点
  • borderType:边界类型

详细使用方法可查看

【学习笔记】ROS 中常用opencv操作_Howe_xixi的博客-CSDN博客_ros的opencvopencv中一些常用函数笔记https://blog.csdn.net/weixin_44362628/article/details/124888288?spm=1001.2014.3001.5502

 1.5.4 边缘检测

使用canny进行边缘检测。首先载入图像,将其转成灰度图,再使用blur函数进行图像模糊以降噪,再使用canny函数进行边缘检测。

#!/usr/bin/env python3
import rospy
import cv2

rospy.init_node("cannyimg") 
img = cv2.imread("/home/spark/Pictures/bluebox.png")
cv2.namedWindow("cannyimg",0)
cv2.resizeWindow("cannyimg",500,500)

# gray
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# blur
blur_img = cv2.blur(gray_img,(10,10))
#cv2.imshow('blur_img',blur_msg)

# canny
Canny_img = cv2.Canny(blur_img,60,110)

cv2.imshow('cannyimg',Canny_img)
cv2.waitKey(0)

 

 Canny 边缘检测分为如下几个步骤:
步骤 1:去噪。噪声会影响边缘检测的准确性,因此首先要将噪声过滤掉。
步骤 2:计算梯度的幅度与方向。
步骤 3:非极大值抑制,即适当地让边缘“变瘦”。
步骤 4:确定边缘。使用双阈值算法确定最终的边缘信息。

edges = cv.Canny( image, threshold1, threshold2[, apertureSize[, L2gradient]])

其中:

  • edges 为计算得到的边缘图像。
  • image 为 8 位输入图像。
  • threshold1 表示处理过程中的第一个阈值。
  • threshold2 表示处理过程中的第二个阈值。
  • apertureSize 表示 Sobel 算子的孔径大小。
  • L2gradient 为计算图像梯度幅度(gradient magnitude)的标识。其默认值为 False。如果为 True,则使用更精确的 L2 范数进行计算(即两个方向的导数的平方和再开方),否则使用 L1 范数(直接将两个方向导数的绝对值相加)。

 1.6 OpenCV视频操作基础

利用VideoCapture对视频进行读取显示,以及调用摄像头。

1.6.1 读取并播放视频

我暂时还没用到使用opencv处理视频的情况,所以暂且留住,待后续涉及到视频的操作的时候会补上。文中也是用简单的几个语句即可实现视频的载入和读取视频帧了。

1.6.2 调用摄像机采集图像

由于是在ROS上执行,采用订阅话题的方式获取摄像机的画面,然后使用opencv进行处理,如灰度化后的canny边缘检测。

在运行程序前要记得启动摄像机。

#!/usr/bin/env python3
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge


def image_cb(img):
    
    prime_img = CvBridge().imgmsg_to_cv2(img, "bgr8")
    cv2.imshow("prime_img",prime_img)

    cv2.namedWindow("cannyimg",0)
    cv2.resizeWindow("cannyimg",500,500)

    # gray
    gray_img = cv2.cvtColor(prime_img,cv2.COLOR_BGR2GRAY)

    # blur
    blur_img = cv2.blur(gray_img,(10,10))
    #cv2.imshow('blur_img',blur_msg)

    # canny
    Canny_img = cv2.Canny(blur_img,60,110)

    cv2.imshow('cannyimg',Canny_img)
    cv2.waitKey(1)

rospy.init_node('camera_canny', anonymous=False)
rospy.Subscriber("/camera/color/image_raw", Image, image_cb, queue_size=1)
rospy.spin()

 对上面的代码进行一下解释吧。

首先导入头文件部分:
from sensor_msgs.msg import Image # 传入的图片消息格式
from cv_bridge import CvBridge # CVBridge 主要用作将ros的图像格式转换为opencv能够处理的格式,下文会有所提及

El siguiente paso es crear la parte de suscriptor, que se encarga de aceptar las imágenes de la cámara:

rospy.Subscriber("/camera/color/image_raw", Image, image_cb, queue_size=1)
rospy.spin()

La suscripción es una pantalla de imagen en color, el tipo de datos es Imagen, cuando se recibe la información, ingresará a la función de devolución de llamada image_cb para su procesamiento. Cuando utilice la suscripción, recuerde agregar la declaración rospy.spin() al final como una declaración de bucle en espera de servicio; de lo contrario, el programa saltará directamente cuando no pueda recibir la información.

 Finalmente, la explicación del contenido de la función de devolución de llamada image_cb:

def image_cb(img):
    
    prime_img = CvBridge().imgmsg_to_cv2(img, "bgr8")
    cv2.imshow("prime_img",prime_img)

    cv2.namedWindow("cannyimg",0)
    cv2.resizeWindow("cannyimg",500,500)

    # gray
    gray_img = cv2.cvtColor(prime_img,cv2.COLOR_BGR2GRAY)

    # blur
    blur_img = cv2.blur(gray_img,(10,10))
    #cv2.imshow('blur_img',blur_msg)

    # canny
    Canny_img = cv2.Canny(blur_img,60,110)

    cv2.imshow('cannyimg',Canny_img)
    cv2.waitKey(1)

La operación es similar a la detección de bordes astuta anterior, excepto que antes de procesar los datos de imagen entrantes img, debe usar cvbridge para transformar el formato de imagen en un formato de imagen que opencv pueda procesar, como una imagen octal bgr.

cv2.waitKey() también debe cambiarse del 0 original al 1; de lo contrario, solo leerá un fotograma del video y esperará.


En este punto, terminé de estudiar el primer capítulo del libro y lo apliqué a opencv4 de ROS noetic.

Supongo que te gusta

Origin blog.csdn.net/weixin_44362628/article/details/127860361
Recomendado
Clasificación