本文基于opencv的官方文档,是本人在学习中的学习笔记。Linux下开发,程序基于opencv4.2,程序无bug,可运行。

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 查看所有色彩空间转换方法
flags = [i for i in dir(cv) if i.startswith('COLOR_')]
print(flags)

# 对于颜色转换,我们使用cv函数。cvtColor(input_image, flag),
# 其中flag决定转换的类型。对于BGR→灰度转换,我们使用标志cv.COLOR_BGR2GRAY。
# 类似地,对于BGR→HSV,我们使用标志cv.COLOR_BGR2HSV

image = cv.imread('girl.jpg', 1)
image = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
cv.imshow('image', image)
cv.waitKey(0)
cv.destroyAllWindows()


# BGR图像转换成HSV,我们可以使用它来提取一个有颜色的对象。
# 在HSV中比在BGR颜色空间中更容易表示颜色。
# 在我们的应用程序中,我们将尝试提取一个蓝色的对象。
# 方法如下: - 取视频的每一帧 - 转换从BGR到HSV颜色空间 -
# 我们对HSV图像设置蓝色范围的阈值 - 现在单独提取蓝色对象,
# 阈值的设定由轨迹栏输入,美中不足有很多噪点

def nothing(x):
    pass


cap = cv.VideoCapture(0)
cv.namedWindow('image')
cv.createTrackbar('HL', 'image', 0, 179, nothing)
cv.createTrackbar('VL', 'image', 0, 255, nothing)
cv.createTrackbar('SL', 'image', 0, 255, nothing)

cv.createTrackbar('HH', 'image', 0, 179, nothing)
cv.createTrackbar('VH', 'image', 0, 255, nothing)
cv.createTrackbar('SH', 'image', 0, 255, nothing)

while 1:
    a = cv.getTrackbarPos('HL', 'image')
    b = cv.getTrackbarPos('VL', 'image')
    c = cv.getTrackbarPos('SL', 'image')
    a1 = cv.getTrackbarPos('HH', 'image')
    b1 = cv.getTrackbarPos('VH', 'image')
    c1 = cv.getTrackbarPos('SH', 'image')

    # 读取帧
    _, frame = cap.read()
    # 转换颜色空间 BGR 到 HSV
    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
    # 定义HSV中蓝色的范围
    lower_blue = np.array([a, b, c])
    upper_blue = np.array([a1, b1, c1])
    # 设置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('image', res)
    k = cv.waitKey(5) & 0xFF
    if k==27:
        break
cv.destroyAllWindows()

# 缩放只是调整图像的大小。
# 为此,OpenCV带有一个函数cv.resize()。
# 图像的大小可以手动指定,也可以指定缩放比例。也可使用不同的插值方法。
# 首选的插值方法是cv.INTER_AREA用于缩小,
# cv.INTER_CUBIC(慢)和cv.INTER_LINEAR用于缩放。
# 默认情况下,出于所有调整大小的目的,使用的插值方法为cv.INTER_LINEAR。
# 使用以下方法调整输入图像的大小:
img = cv.imread('bird.png')
res = cv.resize(img, None, fx=3, fy=2, interpolation=cv.INTER_CUBIC)
cv.imshow('image', res)
cv.waitKey(0)
cv.destroyAllWindows()
# 或者
height, width = img.shape[:2]
res = cv.resize(img, (80, 80), interpolation=cv.INTER_LINEAR)
cv.imshow('image', res)
cv.waitKey(0)
cv.destroyAllWindows()

# OpenCV提供了两个转换函数cv.warpAffine和cv.warpPerspective,
# 可以使用它们进行各种转换。cv.warpAffine采用2x3转换矩阵,
# 而cv.warpPerspective采用3x3转换矩阵作为输入。
# 实质是矩阵运算操作

# 图像的平移分为两步:首先定义好图像的平移矩阵,
# 分别指定x方向和y方向上的平移量tx和ty,平移矩阵的形式如下:
# M = |  1   0  tx |
#     |  0   1  ty |
# 第二部 将其放入np.float32类型的Numpy数组中,并将其传递给cv.warpAffine函数

img = cv.imread('girl.jpg', 1)
rows, cols, m = img.shape
M = np.float32([[1, 0, 100], [0, 1, 50]])
# 接收三个参数,操作对象 平移矩阵 行列数
# cv.warpAffine函数的第三个参数是输出图像的大小,
# 其形式应为(width,height)。记住width =列数,height =行数。
dst = cv.warpAffine(img, M, (cols, rows))
cv.imshow('img', dst)
cv.waitKey(0)
cv.destroyAllWindows()

# 图像的旋转同样分为两步
# 首先创建旋转矩阵,在将参数传到cv.warpAffine函数
# M = |  a   b  (1-a)*center.x-b*center.y |
#     | -b   a  b*center.x+(1-a)*center.y |
# 其中 a = scale*cosC , b = scale*sinC
# 为了找到此转换矩阵,OpenCV提供了一个函数cv.getRotationMatrix2D。
# 所以只需用此函数将矩阵的参数传入,进行创建即可

image = cv.imread('bird.png', 1)
rows, cols, x = image.shape
# 参数  旋转中心(x,y)  旋转角度   缩放倍数
M = cv.getRotationMatrix2D(((cols-1)/2, (rows-1)/2), 180, 2)
# 注意 旋转缩放后由于原来的图像大小不变,所以会丢失图像意外的区域
dst = cv.warpAffine(image, M, (cols, rows))
cv.imshow('img', dst)
cv.waitKey(0)
cv.destroyAllWindows()

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

img = cv.imread('girl.jpg')
rows,cols,x = img.shape
# 变换前位置
pts1 = np.float32([[50,50],[200,50],[50,200]])
# 变换后位置
pts2 = np.float32([[10,200],[200,10],[100,250]])
# 传入参数形成矩阵
M = cv.getAffineTransform(pts1,pts2)
# 传入矩阵
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img', dst)
cv.waitKey(0)
cv.destroyAllWindows()

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

img = cv.imread('girl.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 = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()