5、颜色空间转换(物体跟踪)几何变换(扩展缩放、平移、仿射变换、旋转、透视变换)

本文介绍了如何在Python中利用OpenCV进行颜色空间转换,如BGR到HSV,并演示了如何通过HSV阈值选择蓝色物体进行跟踪。此外,还涉及了图像缩放、平移、仿射变换和旋转等操作,以及透视变换和关键点应用。

一、颜色空间转换

BGR,即蓝-绿-红色彩空间,每一个像素点都由一个三元数组来表示,分别代表蓝、绿、红三种颜色。另一个与之相似的颜色空间:RGB,它们只是在颜色的顺序上不同。

RGB[A]准换成灰度:Y=0.299R+0.587G+0.114*B
灰度转换为RGB[A]:R=Y,G=Y,B=Y,A=max(ChannelRange)

该空间广泛用于视频和图像压缩,不能算作纯粹的色彩空间,它是RGB颜色空间的一种解码方式Y通道表示亮度,而Cr和Cb表示红色差值(在RGB空间中R通道和Y的差值)和蓝色差值(在RGB空间中B通道和Y的差值)各自的色度分量。

HSV, H(Hue)是色调,S(Saturation)是饱和度,V(Value)表示黑暗的程度(或光谱的另一端的明亮程度)。

物体跟踪:

从视频中获取每一帧图像
将图像转换到 HSV 空间
设置 HSV 阈值到蓝色范围。
获取蓝色物体,当然我们还可以做其他任何我们想做的事

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
ret = cap.set(3, 640)
ret = cap.set(4, 480)

#定蓝色的阈值
lower = np.array([110, 50, 50])
upper = np.array([130, 255, 255])

#黄色-乒乓球
#lower = np.array([20, 90, 90])
#upper = np.array([30, 255, 255])

while cap.isOpened():
    # 获取每一帧
    ret, frame = cap.read()
    if not ret:
        print('获取相机图像失败')
        break
    # 换到 HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # 根据阈值构建掩模
    mask = cv2.inRange(hsv, lower, upper)
    # mask = cv2.inRange(hsv, lower_black, upper_black)
    # 对原图像和掩模位运算
    res = cv2.bitwise_and(frame, frame, mask=mask)

    # 显示图像
    cv2.imshow('frame', frame)
    cv2.moveWindow('frame', x=0, y=0)  # 原地
    cv2.imshow('mask', mask)
    cv2.moveWindow('mask', x=frame.shape[1], y=0)#右边
    cv2.imshow('res', res)
    cv2.moveWindow('res', y=frame.shape[0], x=0)#下边

    k = cv2.waitKey(20)  # & 0xFF
    if k == ord('q'):
        break
# 关闭窗口
cap.release()
cv2.destroyAllWindows()

扩展缩放

在缩放时我们推荐使用 cv2.INTER_AREA
在扩展时我们推荐使用 v2.INTER_CUBIC 慢) 和 v2.INTER_LINEAR。
默认情况下所有改变图像尺寸大小的操作使用的插值方法 是 cv2.INTER_LINEAR。

在cv2.resize()函数中,目标图像的大小可以通过参数dsize或者参数fx和fy二值之一来指定。

Resize(src, dst, interpolation=CV_INTER_LINEAR)

import cv2
import numpy as np

img = cv2.imread('messi5.jpg')
# 下面的 None 本应 是 出图像的尺寸 但是因为后边我们设置了缩放因子
# 因此这里为 None
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

# OR
# 我们直接设置输出图像的尺寸 所以不用设置缩放因子
# height, width = img.shape[:2]
# res = cv2.resize(img, (2 * width, 2 * height), interpolation=cv2.INTER_CUBIC)

cv2.imshow('resize', res)
cv2.imshow('src img', img)

cv2.waitKey(0)
cv2.destroyAllWindows()

平移

函数 cv2.warpAffine() 的第三个参数的是 出图像的大小 ,它的格式 应 是图像的(宽,高) 。
图像的宽对应的是列数, 高对应的是行数。

import cv2
import numpy as np

img = cv2.imread('messi5.jpg', 0)
rows, cols = img.shape

M = np.float32([[1, 0, 100], [0, 1, 50]])
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imshow('img', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

仿射变换

仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像在完成仿射变换后,平行线仍然是平行线。
OpenCV中的仿射函数为cv2.warpAffine(),其通过一个变换矩阵M实现变换,具体为:
dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)

在仿射变换中 原图中所有的平行线在结果图像中同样平行。
为了创建 这个矩阵,我们需要从原图像中找到三个点以及他们在 出图像中的位置。
然后 cv2.getAffineTransform 会创建一个 2x3 的矩 最后 个矩 会 传给 函数 cv2.warpAffine。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('drawing.png')
rows, cols, ch = img.shape
print(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'))

plt.figure(figsize=(8, 7), dpi=98)
p1 = plt.subplot(211)
plt.imshow(img)
p1.set_title('Input')

p2 = plt.subplot(212)
plt.imshow(dst)
p2.set_title('Output')

plt.show()

旋转

在OpenCV中,图像的翻转采用函数cv2.flip()实现,该函数能够实现图像在水平方向翻转、垂直方向翻转、两个方向同时翻转,其语法结构:
dst=cv.flip(src, flipCode[, dst])

import cv2
import numpy as np

img = cv2.imread('messi5.jpg', 0)
rows, cols = img.shape

# 的第一个参数为旋转中心 第二个为旋转角度
#  第三个为旋转后的缩放因子
# 可以通过设置旋转中心,缩放因子,以及窗口大小来防止旋转后超出边界的问题
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 0.6)

# 第三个参数是输出图像的尺寸中心
dst = cv2.warpAffine(img, M, (2 * cols, 2 * rows))

cv2.imshow('img', dst)

cv2.waitKey(0)  # & 0xFF
cv2.destroyAllWindows()

透视变换

对于透视变换 ,我们需要一个 3x3 变换矩 。
在变换前后直线 是直线。
构建 个变换矩 你需要在输入图像上找 4 个点, 以及他们在输出图 像上对应的位置。
四个点中的任意三个都不能共线。这个变换矩阵可以用函数 cv2.getPerspectiveTransform() 构建。
然后把这个矩阵传给函数 cv2.warpPerspective。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('messi5.jpg')
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.figure(figsize=(8, 7), dpi=98)
p1 = plt.subplot(2,1,1)
plt.imshow(img)
p1.set_title('Input')

p2 = plt.subplot(2,1,2)
plt.imshow(dst)
p2.set_title('Output')

plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值