OpenCV中的图像处理 —— 改变颜色空间+图像几何变换

OpenCV中的图像处理 —— 改变颜色空间+图像几何变换

这一部分主要介绍OpenCV图像处理中的改变颜色空间和图像的几何变换,颜色空间的改变应用非常广泛,在处理图像的实际问题中,经常需要要图像变换为单通道灰度图像等形式操作,在文中会有一个追踪颜色的小实例便于理解,图像的几何变换是老生常谈的东西了,但是在图像处理中有一些新的概念,例如仿射变换和透视变换,废话不多说直接开干!

1. 改变颜色空间

关于颜色空间的改变我们要掌握两个重要的功能函数:cv.cvtColorcv.inRange

1.1 改变颜色空间

OpenCV中有超150中颜色空间转换方法,但是我们只掌握应用最广泛的两种即可:

BGR <-> 灰度 和 BGR <-> HSV

颜色转换的函数cv.cvtColor()非常简单,往其中传入两个参数即可吗,第一个参数是我们的图像对象,第二个参数代表我们要转换称为的类型标志

对于BGR→灰度转换,我们使用标志cv.COLOR_BGR2GRAY。类似地,对于BGR→HSV,我们使用标志cv.COLOR_BGR2HSV

要获取其他标志只需要在python终端把库中的标志名全部输出即可查看

>>> import cv2 as cv
>>> flags = [i for i in dir(cv) if i.startswith('COLOR_')]
>>> print( flags )

1.2 颜色对象追踪

我们通过一个实例来展示颜色对象追踪,其本质上就是在显示的视频中只显示我们要求的颜色,以达到追踪颜色的效果

在HSV中比在BGR中更容易显示颜色

代码实现

import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
     # 读取帧
     _, frame = cap.read()
     # 转换颜色空间 BGR 到 HSV
     hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
     # 定义HSV中蓝色的范围
     lower_blue = np.array([110,50,50])
     upper_blue = np.array([130,255,255])
     # 设置HSV的阈值使得只取蓝色
     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(5) & 0xFF
     if k == 27:
    	 break
cv.destroyAllWindows()

在这里插入图片描述

首先我们创建了一个VideoCapture对象用来捕获视频,再通过while来逐帧读取视频,在读取视频的过程中因为我们要单独筛出蓝色,所以还需要一些列操作

HSV比BGR更容易显示颜色,为了显示效果能够更好所有我们选择使用HSV的图像,这个过程用cv.cvtColor()将BGR转换为HSV,在代码中有一个很重要的函数cv.inRange()函数,这个函数就用来筛选处于给定像素区间的图像,其中有三个参数,第一个便是当前“帧”,第二第三个参数就是给定的像素区间了

这里还有一个很重要的函数cv.bitwise_and(),这个函数主要有两个用途:

  • 提取掩膜选定的区域:cv.bitwise_and(img1,img2,mask = mask)

首先我们要知道我们是掩膜mask,我们在处理一些图像时,需要选定我们要处理的部分,我们怎么确定这一块儿部分呢?那就是用一块儿掩膜mask来遮住这一块儿区域

  • 求两种图片的交集:cv.bitwise_and(img1,img2)

这个用法就很简单了,传入的两个参数就是两个图像对象,返回的结果就是这两个图像的交集

2. 图像几何变换

对于OpenCV的图像几何变换,其提供了两个转换函数:cv.warpAffine()cv.warpPerspective()

cv.warpAffine采用2x3转换矩阵,而cv.warpPerspective采用3x3转换矩阵作为输入

2.1 缩放

图像的缩放我们可以通过cv.resize()没错就是重置图像的大小,这里有两个插值方式值得注意,一个是cv.INTER_AREA用于缩小,另一个是cv.INTER_CUBIC用于缩放

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

2.2 平移

图像的平移我们通过创建转换矩阵M来完成,并且需要使用函数cv.wrapAffine()

我们把转换矩阵放入np.float32类型的Numpy数组中,并将其传递给cv.wrapAffine()函数

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',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()

在这里插入图片描述

cv.wrapAffine()函数的参数:第一个为显示的图像,第二个是转换矩阵,第三个是图像的尺寸

2.3 旋转

图像的旋转同样需要一个转换矩阵,这个转换矩阵我们通过**cv.getRotationMatrix2D()**这个函数来得到,其中需要传递三个参数,第一个参数是旋转位置的坐标,它通过一个二元组来传递,第二个参数是旋转角度吗,第三个参数是用来做调整的参数,如果传入1,则按照正常的逆时针旋转,如果传入0则不会显示图片,如果传入-1会显示顺时针旋转的结果

import numpy as np
import cv2 as cv

# cols-1 和 rows-1 是坐标限制
img = cv.imread(r'E:imagewqw.png', 0)
rows, cols = img.shape
M = cv.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), 90, 1)
dst = cv.warpAffine(img, M, (cols, rows))
cv.imshow('img', dst)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

2.4 仿射变换

还记得我们在上面说的另一个函数cv.getAffineTransform吗?现在我们要开始使用它了

在仿射变换中,原始图像中的所有平行线在输出图像中仍将平行,为了找到变换矩阵,我们需要输入图像中的三个点的位置,然后使用cv.getAffineTransform()函数创建一个2*3的矩阵,再将其传入cv.wrapAffine()完成仿射变换

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

在这里插入图片描述

2.5 透视变换

对于透视变换,需要3x3变换矩阵,即使在转换后,直线也将保持直线,要找到此变换矩阵,需要在输入图像上有4个点(在这四个点中,其中三个不应共线)

可以通过函数cv.getPerspectiveTransform找到变换矩阵。然后将cv.warpPerspective应用于此3x3转换矩阵

img = cv.imread('sudoku.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 = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.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()

在这里插入图片描述


(注:文章内容参考OpenCV4.1中文官方文档)
如果文章对您有所帮助,记得一键三连支持一下哦

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>