OpenCV

文章目录

  • CV入门路线
  • 图像基础知识
      • 像素坐标系
      • 图像坐标系
      • 相机坐标系到图像坐标系
  • Opencv API
    • 模块
    • 基础
      • Mat图像存储容器
    • 图像的基础操作
      • 1.图像的IO操作
        • 1.1读取图像
        • 1.2显示图像
        • 1.3保存图像
        • 1.4 图像复制
      • 2 绘制几何图形
        • 2.1 绘制直线
        • 2.2 绘制圆形
        • 2.3 绘制矩形
        • 2.4 向图像中添加文字
      • 3 获取图像的属性
      • 4.图像通道拆分和合并
      • 5.色彩空间的改变
    • 图像的算数操作
      • 1.图像的加法
      • 2.图像的混合
    • 图像处理
      • 1.图像缩放
      • 2.图像平移
      • 3.图像旋转
      • 4.仿射变换
    • 视频操作
      • 创建视频对象
      • 读取视频帧
      • 释放视频对象
      • 属性设置
        • 属性获取
      • 播放视频文件

CV入门路线

1.CV综述及图像简介
2.Alexnet net《ImageNet Classification with Deep Convolutional Neural Networks》
3.VGG net:《Very Deep Convolutional Networks for Large-Scale Image Recognition》google netv1 v2v3v4 (串讲) :
4.v1:《Going deeper with convolutions》
5.v2:《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》
6.v3:《Rethinking the Inception Architecture for Computer Vision
7.v4:《Inception- ResNet and the Impact of Residual Connections on Learning》
8.resnet:《Deep Residual Learning for Image Recognition》
9.densenet:《Densely Connected Convolutional Networks》
10.SEnet: 《Squeeze- and- Excitation Networks》
11.ResNeXt:《Aggregated Residual Transformations for Deep Neural Networks》

图像基础知识

数字图像的本质就是一个元素为像素的矩阵,在计算机中以数组的形式存储,数组的第一个索引对应矩阵的行,第二个索引对应矩阵的列。

世界坐标系通过平移和旋转得到相机坐标系相机坐标系通过成像模型中的相似三角形原理得到图像坐标系图像坐标系通过平移和缩放得到像素坐标系

OpenCV_第1张图片

像素坐标系

以图像左上角为原点建立以像素为单位的直接坐标系u-v。像素的横坐标u与纵坐标v分别是在其图像数组中所在的列数与所在行数。

OpenCV_第2张图片

像素坐标系中的一个像素点(u,v)对应图像数组的元素img(v,u)

图像坐标系

由于(u,v)只代表像素的列数与行数,而像素在图像中的位置并没有用物理单位表示出来,所以,我们还要建立以物理单位(如毫米)表示的图像坐标系x-y。将相机光轴与图像平面的交点(一般位于图像平面的中心处,也称为图像的主点(principal point)定义为该坐标系的原点 O 1 O_1 O1,且x轴与u轴平行,y轴与v轴平行,假设 ( u 0 , v 0 ) (u_0,v_0) (u0,v0)代表 O 1 O_1 O1在u-v坐标系下的坐标,dx与dy分别表示每个像素在横轴x和纵轴y上的物理尺寸,则图像中的每个像素在u-v坐标系中的坐标和在x-y坐标系中的坐标之间都存在如下的关系:
u = x d x + u 0 v = y d y + v 0 u=\dfrac{x}{dx}+u_0\\v=\dfrac{y}{dy}+v_0 u=dxx+u0v=dyy+v0
其中,我们假设物理坐标系中的单位为毫米,那么dx的的单位为:毫米/像素。那么x/dx的单位就是像素了,即和u的单位一样都是像素。为了使用方便,可将上式用齐次坐标与矩阵形式表示为:
[ u v 1 ] = [ 1 d x 0 u 0 0 1 d y v 0 0 0 1 ] [ x y 1 ] \begin{bmatrix}u\\v\\1\end{bmatrix}=\begin{bmatrix}\dfrac{1}{dx}&0&u_0 \\ 0&\dfrac{1}{dy}&v_0\\0&0&1\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix} uv1=dx1000dy10u0v01xy1

相机坐标系到图像坐标系

OpenCV_第3张图片

从图中可知, x c x = y c y = z c f \dfrac{x_c}{x}=\dfrac{y_c}{y}=\dfrac{z_c}{f} xxc=yyc=fzc,其中f为焦距。通过变换可得 , x = x c z c f , y = y c z c f x=\dfrac{x_c}{z_c}f,y=\dfrac{y_c}{z_c}f x=zcxcf,y=zcycf由此可得其增广形式
( x y 1 ) = 1 z c ( f 0 0 0 0 f 0 0 0 0 1 0 ) ( x c y c z c 1 ) \begin{pmatrix}x\\y\\1\end{pmatrix}=\dfrac{1}{z_c}\begin{pmatrix}f&0&0&0 \\ 0&f&0&0\\0&0&1&0\end{pmatrix}\begin{pmatrix}x_c\\y_c\\z_c\\1\end{pmatrix} xy1=zc1f000f0001000xcyczc1

Opencv API

模块

  • core:最核心的数据结构

  • highgui:视频与图像的读取、显示、存储

  • imgproc:图像处理的基础方法

  • features2d:图像特征以及特征匹配

基础

Mat图像存储容器

//矩阵转置
cv::Mat::t();
cv::transpose(InputArray src,OutputArray dst)

图像的基础操作

1.图像的IO操作

1.1读取图像

1.API

cv2.imread(filepath,flags)

参数:

  • filepath:要读取的图像的完整路径

  • flags:读取方式的标志

    • cv2.IMREAD_COLOR:以彩色模式加载图像,任何图像的透明度都被忽略,这是默认参数
    • cv.IMREAD_GRAYSCALE:以灰度模式加载图像
    • cv.IMREAD_UNCHANGED:包括 Alpha通道(透明度) 的加载图像模式

    可以使用1、0、-1来代替上面三个标志

参考代码

import numpy as np
import cv2 
# 以灰度图的形式读取图像
img=cv2.imread(" .jpg",0)

1.2显示图像

1.API

cv2.imshow(windowName,img)

参数:

  • windowName:显示图像的窗口名称,以字符串类型表示
  • img要加载的图像

注意:在调用显示图像的API后,要调用cv2.waitKey()给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来

参考代码

# opencv中显示
cv.imshow("image",img)
cv.waitKey(0)
# matplotlib中显示
plt.imshow(img[:,:,::-1])

1.3保存图像

1.API

cv.imwrite(file,img,num)

参数:

  • file:文件名,要保存在哪
  • img:要保存的图像
  • num:第三个参数表示的是压缩级别。默认为3.

2.参考代码

cv.imwrite(" .png",img)

1.4 图像复制

img.copy()

2 绘制几何图形

2.1 绘制直线

cv.line(img,start,end,color,thickness)

参数:

  • img:要绘制直线的图像
  • start,end:直线的起点和终点
  • color:线条的颜色
  • thickness:线条宽度

2.2 绘制圆形

cv.circle(img,centerpoint,r,color,thickness)

参数:

  • img:要绘制直线的图像
  • centerpoint,r:圆心和半径
  • color:线条的颜色
  • thickness:线条宽度

2.3 绘制矩形

cv.rectangle(img,leftupper,rightdown,color,thickness)

参数:

  • img:要绘制直线的图像
  • leftupperrightdown:矩形的左上角和右下角坐标,元组形式(x,y) (x+w,y+h)
  • color:线条的rgb颜色,元组形式,例如(0,255,0)
  • thickness:线条宽度

2.4 向图像中添加文字

cv.putText(img,text,station,font,fontsize,color,thickness)

参数:

  • img:要绘制直线的图像
  • text:要写入的文本数据、
  • station:文本的放置位置
  • font:字体
  • Fontsize:字体大小
  • color:线条的颜色
  • thickness:线条宽度

3 获取图像的属性

cv2.boundingRect(img)

返回图像的四值属性,分别是x,y,w,h; x,y是矩阵左上点的坐标,w,h是矩阵的宽和高。

属性 API
形状 img.shape
图像大小 img.size
数据类型 img.dtype

4.图像通道拆分和合并

#通道拆分
b,g,r=cv.split(img)
#通道合并
img=cv.merge((b,g,r))

5.色彩空间的改变

API:

cv2.cvtColor(input_image,flag)

参数:

  • input_image:进行颜色空间转换的图像
  • flag:转换类型
    • cv2.COLOR_BGR2GRAY:BGR ↔ \leftrightarrow Gray
    • cv2.COLOR_GRAY2RGB:Gray ↔ \leftrightarrow BGR
    • cv2.COLOR_BGR2HSV:BGR ↔ \leftrightarrow HSV

图像的算数操作

1.图像的加法

cv.add(img1,img2)

2.图像的混合

d s t = α ⋅ i m g 1 + β ⋅ i m g 2 + γ dst=\alpha\cdot img1+\beta\cdot img2+\gamma dst=αimg1+βimg2+γ

API:

cv.addWeighted(img1,权重1,img2,权重2,偏置)

图像处理

1.图像缩放

API:

cv.resize(src,dsize,fx=0,fy=0,interpolation)

参数:

  • src:输入图像

  • dsize:绝对尺寸,直接指定调整后图像的大小,以元组形式给出,如(2*cols,2*rows)

  • fx,fy:相对尺寸,将dsize设置为None,然后将fx和fy设置成比例因子即可

  • interpolation:插值方法

    双线性插值法 cv.INTER_LINEAR

    最邻近插值 cv.INTER_NEAREST

    像素区域重采样 cv.INTER_AREA

    双三次插值 cv.INTER_CUBIC

2.图像平移

API:

cv.warpAffine(img,M,dsize)

参数:

  • img:输入图像

  • M:2*3移动矩阵

    对于(x,y)处的像素点,要把它移动到 ( x + t x , y + t y ) (x+t_x,y+t_y) (x+tx,y+ty)处时,M矩阵应如下设置:

    M = [ 1 0 t x 0 1 t y ] M=\begin{bmatrix}1&0&t_x\\0&1&t_y\end{bmatrix} M=[1001txty]

    M[:-1,:]代表方向, t x , t y t_x,t_y tx,ty代表移动距离
    注意:将M设置为np.float32类型的Numpy数组。

  • dsize:输出图像的大小
    注意:输出图像的大小,它应该是(宽度,高度)的形式。请记住,width=列数,height=行数。

3.图像旋转

API:

cv.getRotationMatrix2D(center,angle,scale)
cv.warpAffine(img,M,dsize)

参数:

  • center:旋转中心

  • angle:旋转角度

  • scale:缩放比例

返回旋转矩阵M,之后调用cv.warpAffine

需要注意的是,对于图像而言,宽度方向是x,高度方向是y,坐标的顺序和图像像素对应下标一致。所以原
点的位置不是左下角而是右上角,y的方向也不是向上,而是向下。

4.仿射变换

图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像
的缩放,旋转,翻转和平移等操作的组合�

视频操作

创建视频对象

cap=cv2.VideoCapture(参数)

arguments:

  • 参数是0,表示打开笔记本的内置摄像头;参数是1,则打开外置摄像头;其他数字则代表其他设备;

  • 参数是视频文件的路径则打开指定路径下的视频。

读取视频帧

使用视频对象的read()函数,C++还可以使用>>操作符

retval,frame=cap.read()
  • image是返回的捕获到的帧,如果没有帧被捕获,则该值为空。
  • retval表示捕获是否成功,如果成功则该值为True,不成功则为False。

一般情况下,如果需要读取一个摄像头的视频数据,最简便的方法就是使用函数cv2.VideoCapture.read()。但是,如果需要同步一组或一个多头(multihead)摄像头(例如立体摄像头或Kinect)的视频数据时,该函数就无法胜任了。可以把函数cv2.VideoCapture.read()理解为是由函数cv2.VideoCapture.grab()和函数cv2.VideoCapture.retrieve()组成的。函数cv2.VideoCapture.grab()用来指向下一帧,函数cv2.VideoCapture.retrieve()用来解码并返回一帧。因此,可以使用函数cv2.VideoCapture.grab()和函数cv2.VideoCapture.retrieve()获取多个摄像头的数据。
函数cv2.VideoCapture.grab()用来指向下一帧,其语法格式是:

retval= cv2.VideoCapture.grab( )

如果该函数成功指向下一帧,则返回值retval为True。

函数cv2.VideoCapture.retrieve()用来解码,并返回函数v2.VideoCapture.grab()捕获的视频帧。该函数的语法格式为:

retval, image = cv2.VideoCapture.retrieve( )
  • image为返回的视频帧,如果未成功,则返回一个空图像。
  • retval为布尔型值,若未成功,返回False;否则,返回True。

对于一组摄像头,可以使用如下代码捕获不同摄像头的视频帧:

success0 = cameraCapture0.grab()
success1 = cameraCapture1.grab()
if success0 and success1:
frame0 = cameraCapture0.retrieve()
frame1 = cameraCapture1.retrieve()

释放视频对象

cap.release()

属性设置

属性获取

cv2.VideoCapture.get(propID)

  • 参数propID对应着cv2.VideoCapture类对象的属性

OpenCV_第4张图片
OpenCV_第5张图片

播放视频文件

import cv2
cap = cv2.VideoCapture('output.avi')
while(cap.isOpened()):
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    c = cv2.waitKey(1)
    if c==27:   #ESC键
        break
cap.release()
cv2.destroyAllWindows()

你可能感兴趣的:(SLAM,机器学习,opencv,计算机视觉,人工智能)