首页>>人工智能->OpenCV Tutorials 03

OpenCV Tutorials 03

时间:2023-11-29 本站 点击:2

简单物体追踪和几何转换

一、更改颜色空间

有时候,我们需要对图像的颜色空间进行转换,比如说在图像进行阈值处理、边缘检测时,三个通道的图像难以进行梯度检测,所以我们进行色域转换:BGR <-> gray, BGR <-> HSV

另外,接下来我们将会尝试将一个视频中的有色物体提取出来。

下面我们将会学习两个函数:cv.cvtColor()转换颜色空间,cv.inRange()等

1. 改变图像色域

OpenCV里面包含了150多种色域转换的方式,但是我们只需关注两种:BGR <-> gray, BGR <-> HSV,色域转换函数如下:

cv.cvtColor(input_image, flag) ,其中flag决定了转换类型,有如下取值:

cv.COLOR_BGR2GRAY,实现BGR -> gray 转换

cv.COLOR_BGR2HSV,实现BGR -> HSV 转换

import cv2 as cvimport numpy as npimport matplotlibimport matplotlib.pyplot as plt%matplotlib inline

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()

def compare(imgs):  #  for i in range(len(imgs)): #       imgs[i][:,-3:-1,:] = [255,255,255]    res = np.hstack(imgs)    cv_show('Compare', res)

# 打印查看flag的取值flags = [i for i in dir(cv) if i.startswith('COLOR_')]flags

['COLOR_BAYER_BG2BGR', 'COLOR_BAYER_BG2BGRA', 'COLOR_BAYER_BG2BGR_EA', 'COLOR_BAYER_BG2BGR_VNG', 'COLOR_BAYER_BG2GRAY', ... 'COLOR_YUV420sp2GRAY', 'COLOR_YUV420sp2RGB', 'COLOR_YUV420sp2RGBA', 'COLOR_mRGBA2RGBA']

注意:对于 HSV,色相范围是[0,179] ,饱和度范围是[0,255] ,值范围是[0,255]。不同的软件使用不同的尺度。因此,如果在OpenCV中使用HSV ,则需规范化这些取值范围

2. 物体跟踪

在了解到BGR图像转化为HSV图像的方法之后,我们可以使用它来提取有色对象。相比较BGR图像爱,在HSV图像中,我们更易于表示一种颜色。接下来的应用中,我们将使用以下步骤来提取有色物体:

获取到视频的每一帧

将帧图像的色域从BGR转换到HSV

将HSV图像阈值处理为蓝色范围

单独提取出蓝色,便于我们之后处理

cv.inRange的用法: cv.inRange( src, lowerb, upperb[, dst]  ) ->    dst,得到一副二值图像

OpenCV中HSV的BGR角度范围:

红色:0

绿色:60

蓝色:120

黄色:30

青色:90

紫色:150

cap = cv.VideoCapture(0)if not cap.isOpened():    print('打开文件失败!')    exit()while(1):    # 逐帧提取    _, frame = cap.read()    # 转换色域    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)    # 设定蓝色色域的上下限,参数分别为:颜色角度、饱和度、明度    lower_blue = np.array([0,50,50])    upper_blue = np.array([20,255,255])    # 在对应颜色范围就置为255,不在的话就归0    mask = cv.inRange(hsv, lower_blue, upper_blue)    # 滤出对应的颜色范围图像    res = cv.bitwise_and(frame,frame, mask= mask)    cv.imshow('frame',frame)    cv.imshow('mask',mask)    cv.imshow('res',res)    k = cv.waitKey(1) & 0xFF    if k == 27:        breakcv.destroyAllWindows()

注意: 可以看见图像中存在一些噪声,稍后我们会讨论解决办法,这是图像追踪的最最简单的一种方式,若是学写了轮廓函数,我们就能做很多事情,比如找到物体的质心,然后用它来跟踪物体,仅仅通过在摄像机前移动你的手绘制图表,还有其他有趣的事情。

3. 怎样了解我们需要跟踪的HSV值?

我们可以在网站:https://www.stackoverflow.com/ 寻求相关答案。另外,我们也可以使用 cv.cvtColor()函数来进行BGR到HSV的转换。不需要传入图像,只需要传入对应的BGR值便可。

# 查看Green的HSV值# 现将BGR格式的纯绿色定义出来green_BGR = np.uint8([[[0, 255, 0]]])green_BGR.shape

(1, 1, 3)

一行一列三通道,定义多行多列可以直接使用np.zeros

red_BGR = np.zeros((255, 400, 3))red_BGR[...,2] = 255cv_show('Red', red_BGR)

# 进行BGR2HSV转化green_HSV = cv.cvtColor(green_BGR, cv.COLOR_BGR2HSV)green_HSV

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()0

现在你把[ H-10,100,100] 和 [ H + 10,255,255]分别作为下界和上界。除了这个方法,你可以使用任何图像编辑工具,如 GIMP 或任何在线转换器来找到这些值,但不要忘记调整 HSV 范围(主要是第一个角度的范围,要除二)。

4. 练习

尝试提取出多种颜色的物体,如蓝色、绿色一起提取

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()1

二、图像几何变换

本节主要包括应用不同的几何变换图像,如平移,旋转,仿射变换等。主要用到的函数有: cv.getPerspectiveTransform()

1. 重塑图像大小

OpenCV内置了两个转换函数: cv.warpAffine 和 cv.warpPerspective,可以帮助我们进行各类转换。前者的转换矩阵为 2 3,而后者转换矩阵尺寸为 3 3

图像缩放:图像缩放就是重新设置图像的大小。OpenCV提供了cv.resize函数完成此功能。图像大小能手动设置也可以传入缩放因子。根据传入缩放因子的不同,实现的功能也不同:

cv.INTER_AREA:缩小

cv.INTER_CUBIC(缓慢) 和  cv.INTER_LINEAR:放大

一般说来,cv.INTER_LINEAR方法适用于所有的重塑图像大小情况。

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()2

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()3

2. 图像平移

平移就是图像位置的转换,若你明确了(x, y)方向的偏移,并且让他转换到$(t_x, t_y)$,那么你就可以构造出一个变换矩阵M ,$ M =\begin{bmatrix} 1 & 0 & t_x\ 0 & 1 & t_y \end{bmatrix}$。

我们可以将这个矩阵使用Numpy的数组类型(其中的数据类型要保持为 np.float32)存储,便于之后的矩阵运算或传递给 cv.warpAffine ()函数

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()4

注意:cv.warpAffine ()函数的第三个参数是输出图像的大小,它应该是 (width,height) 的形式。记住 width = 列数,height = 行数。

3. 图像旋转

旋转角度为$\theta$的图像旋转是透过变换矩阵来达到的:$M=\left[\begin{array}{cc} \cos \theta & -\sin \theta \ \sin \theta & \cos \theta \end{array}\right]$,这种方法未指定旋转中心。

但是 OpenCV 提供了可调节旋转中心的缩放旋转,这样便可以以任何位置为中心旋转。修改后的变换矩阵为:$\left[\begin{array}{ccc} \alpha & \beta & (1-\alpha) \cdot \text { center. } x-\beta \cdot \text { center. } y \ -\beta & \alpha & \beta \cdot \text { center. } x+(1-\alpha) \cdot \text { center. } y \end{array}\right]$,

其中 center.x, center.y代表了旋转中心的坐标,而$\begin{aligned} \alpha &=\text { scale } \cdot \cos \theta \ \beta &=\text { scale } \cdot \sin \theta \end{aligned}$,scale是缩放比例

上面仅是数学推理过程,OpenCV提供了cv.getRotationMatrix2D 函数来帮助我们找到上面的变换矩阵。

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()5

4. 仿射变换

在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要从输入图像中找到3个点,并在输出图像中找到它们的对应位置。然后,cv.getafinetransform 将创建一个2x3矩阵,该矩阵将传递给 cv.warpAffine进行仿射变换。

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()6

5. 透视变换

对于透视转换,你需要一个3 × 3的变换矩阵。直线即使在变换之后也会保持直线。为了找到这个变换矩阵,你需要在输入图像和输出图像上对应的4个点。在这4点中,有3点不应该是共线的。然后可以通过函数 cv.getPerspectiveTransform 找到变换矩阵。然后应用 cv.warpPerspective 填入这个3x3变换矩阵。

def cv_show(name, img):    cv.imshow(name, img)    cv.waitKey(0)    cv.destroyAllWindows()7

原文:https://juejin.cn/post/7097515225590530062


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/AI/1179.html