欢迎光临散文网 会员登陆 & 注册

OpenCV: 颜色变换及空间变换

2023-04-14 23:38 作者:Uncle_LL  | 我要投稿

目标1

  • 在本教程中,将学习如何将图像从一个色彩空间转换到另一个,像BGR↔灰色,BGR↔HSV等

  • 除此之外,将创建一个应用程序,以提取视频中的彩色对象

  • 学习以下函数:CV2.cvtColorCV2.inRange

改变颜色空间

OpenCV中有超过270种颜色空间转换方法。但是我们研究两个最广泛使用的, BGR↔灰色和BGR↔HSV。

对于颜色转换,使用CV2.cvtColor(input_image, flag),其中flag决定转换的类型。

import CV2
flag = [i for i in dir(CV2if i.startswith('COLOR_')]
print(flag)

 
 

大概274种。

注意 HSV的色相范围为[0,179],饱和度范围为[0,255],透明度值范围为[0,255]。不同的软件使用不同

的规模。因此,如果要将OpenCV值和它们比较,需要将这些范围标准化。

img = CV2.imread('messi.png')
img_hsv = CV2.cvtColor(img, CV2.COLOR_BGR2HSV)
CV2.imshow('hsv', img_hsv)
CV2.waitKey(0)
CV2.destroyAllWindows()

 
 

对象追踪

现在知道了如何将BGR图像转换成HSV,可以使用它来提取一个有颜色的对象。在HSV中比在BGR颜色空间中更容易表示颜色。在应用程序中,将尝试提取一个蓝色的对象的一个简单例子。方法如下: 取视频的每一帧 - 转换从BGR到HSV颜色空间 - 对HSV图像设置蓝色范围的阈值 - 现在单独提取蓝色对象,可以对图像做任何想做的事情。

import CV2
import numpy as np
cap = cv.VideoCapture(0)
while(1):
    # 读取帧
    _, frame = cap.read()
    # 转换颜色空间 BGR 到 HSV
    hsv = CV2.cvtColor(frame, CV2.COLOR_BGR2HSV)
    # 定义HSV中蓝色的范围
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    # 设置HSV的阈值使得只取蓝色
    mask = CV2.inRange(hsv, lower_blue, upper_blue)
    # 将掩膜和图像逐像素相加
    res = CV2.bitwise_and(frame,frame, mask= mask)
    CV2.imshow('frame',frame)
    CV2.imshow('mask',mask)
    CV2.imshow('res',res)
    k = CV2.waitKey(5) & 0xFF
    if k == 27:
        break
CV2.destroyAllWindows()

 

注意 图像中有一些噪点。将在后面的章节中看到如何删除它们。 这是对象跟踪中最简单的方法。一旦学习了轮廓,就可以做很多事情,例如找到该对象的质心并使用它来跟踪对象,仅通过将手移到相机前面以及其他许多有趣的东西就可以绘制图表。

如何找到要追踪的HSV值

这是在stackoverflow.com上发现的一个常见问题。它非常简单,你可以使用相同的函数

CV2.cvtColor()。只需传递你想要的BGR值,而不是传递图像。例如,要查找绿色的HSV值,

请在Python终端中尝试以下命令:

green = np.uint8([[[0,255,0]]])
hsv_green = CV2.cvtColor(green, CV2.COLOR_BGR2HSV)
print(hsv_green)

# [[[ 60 255 255]]]

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

目标2

  • 学习将不同的几何变换应用到图像上,如平移、旋转、仿射变换等。

  • 函数: cv.getPerspectiveTransform

变换

OpenCV提供了两个转换函数CV2.warpAffineCV2.warpPerspective,可以使用它们进行各种转换。CV2.warpAffine采用2x3转换矩阵,而CV2.warpPerspective采用3x3转换矩阵作为输入。

缩放

缩放只是调整图像的大小。为此,OpenCV带有一个函数CV2.resize()。图像的大小可以手动指定,也可以指定缩放比例。也可使用不同的插值方法。首选的插值方法是CV2.INTER_AREA用于缩小,CV2.INTER_CUBIC(慢)和CV2.INTER_LINEAR用于缩放。默认情况下,出使用的插值方法为CV2.INTER_LINEAR。可以使用以下方法调整输入图像的大小:

import CV2
import numpy as np
img = CV2.imread('messi.png')
res = CV2.resize(img, None, fx=2, fy=2, interpolation=cv.INTER_CUBIC)
#或者
height, width = img.shape[:2]
res = CV2.resize(img,(2*width, 2*height), interpolation=CV2.INTER_CUBIC)

平移

平移是物体位置的移动。如果知道在(x,y)方向上的位移,则将其设为(t_x, t_y ),可以创建转换矩阵M ,如下所示:

 

可以将其放入np.float32类型的Numpy数组中,并将其传递给CV2.warpAffine函数。参见下面偏移为(100, 50)的示例:

import CV2
import numpy as np
img = CV2.imread('messi.png'0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])  # 方向
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()

警告 CV2.warpAffine函数的第三个参数是输出图像的大小,其形式应为(width,height)。记住width =列数,height =行数。

 
  

旋转

图像旋转角度为θ是通过以下形式的变换矩阵实现的:

 

但是OpenCV提供了可缩放的旋转以及可调整的旋转中心,因此可以在自己喜欢的任何位置旋转。修改后的变换矩阵为

 

其中:

 

为了找到此转换矩阵,OpenCV提供了一个函数CV2.getRotationMatrix2D。请检查以下示例,该示例将图像相对于中心旋转90度而没有任何缩放比例。

img = CV2.imread('messi.png'0)
rows,cols = img.shape
M = CV2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 90,1)  # cols-1 和 rows-1 是坐标限制
dst = CV2.warpAffine(img, M, (cols,rows))

 

仿射变换

在仿射变换中,原始图像中的所有平行线在输出图像中仍将平行。为了找到变换矩阵,需要输入图像中的三个点及其在输出图像中的对应位置。然后CV2.getAffineTransform将创建一个2x3矩阵,该矩阵将传递给CV2.warpAffine

查看以下示例,并查看选择的点(以绿色标记):

img = CV2.imread('draw.png')
rows,cols,c = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = CV2.getAffineTransform(pts1, pts2)
dst = CV2.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')

查看结果:

 

透视变换

对于透视变换,需要3x3变换矩阵。即使在转换后,直线也将保持直线。要找到此变换矩阵,需要在输入图像上有4个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然后可以通过函数CV2.getPerspectiveTransform找到变换矩阵。然后将CV2.warpPerspective应用于此3x3转换矩阵。

img = CV2.imread('sudo.png')
rows, cols, ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = CV2.getPerspectiveTransform(pts1, pts2)
dst = CV2.warpPerspective(img, M, (300,300))
plt.subplot(121),plt.imshow(img), plt.title('Input')
plt.subplot(122),plt.imshow(dst), plt.title('Output')
plt.show()

 

其他资源

  • Computer Vision: Algorithms and Applications, Richard Szeliski


OpenCV: 颜色变换及空间变换的评论 (共 条)

分享到微博请遵守国家法律