前言:
零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能相关知识,成为学习学习和学业的先行者!
欢迎大家订阅专栏:零基础学Python:Python从0到100最新最全教程!
一、改变颜色空间
1.获取颜色转化类型
OpenCV中有超过150种颜色空间转换方法。但是我们将研究只有两个最广泛使用的,BGR↔灰色和BGR↔HSV。
对于颜色转换,我们使用cv函数。cvtColor(input_image, flag),其中flag决定转换的类型。
对于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.1 dir(cv)函数
dir 语法:**
dir([object])
参数说明:object – 对象、变量、类型。
返回值:返回模块的属性列表。
即返回cv模块所有的属性列表
1.2 startswith()函数
startswith()函数是Python的字符串函数。startswitch()用于检测字符串是否以指定字符串开头。如果是则返回True,否则返回False.
语法及参数:
str.startswith(str2)
str 待检测的字符串
str2 检测str2字符串是否是str字符串的开头 不可省略的参数
举例说明:
>>> pro.startswith("Chi")
True
>>> pro.startswith("hi")
False
- 注意: HSV的色相范围为[0,179],饱和度范围为[0,255],值范围为[0,255]。不同的软件使用不同的规模。因此,如果你要将OpenCV值和它们比较,你需要将这些范围标准化。
2.对象追踪
现在我们知道了如何将BGR图像转换成HSV,我们可以使用它来提取一个有颜色的对象。在HSV中比在BGR颜色空间中更容易表示颜色。在我们的应用程序中,我们将尝试提取一个蓝色的对象。方法如下: - 取视频的每一帧 - 转换从BGR到HSV颜色空间 - 我们对HSV图像设置蓝色范围的阈值 - 现在单独提取蓝色对象,我们可以对图像做任何我们想做的事情。
蓝色
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
或者蓝色
low_blue = np.array([94, 80, 2])
high_blue = np.array([126, 255, 255])
红色
low_red = np.array([161, 155, 84])
high_red = np.array([179, 255, 255])
绿色
low_green = np.array([25, 52, 72])
high_green = np.array([102, 255, 255])
除白色之外的颜色
low = np.array([0, 42, 0])
high = np.array([179, 255, 255])
2.1只取蓝色区域:
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
# 读取帧
ret, 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)
mask_inv = cv.bitwise_not(mask)
# 将掩膜和图像逐像素相加
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()
2.2不取蓝色区域:
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
# 读取帧
ret, 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)
mask_inv = cv.bitwise_not(mask)
# 将掩膜和图像逐像素相加
res = cv.bitwise_and(frame,frame, mask= mask_inv)
cv.imshow('frame',frame)
cv.imshow('mask',mask)
cv.imshow('res',res)
k = cv.waitKey(5) & 0xFF
if k == 27:
break
cv.destroyAllWindows()
二、图像的几何变换
1.图像的旋转变换
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread('haojin.jpg',0)
rows,cols = img.shape
print(rows,cols)
# cols-1 和 rows-1 是坐标限制
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),-60,1)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
1.1 图像平移 cv.warpAffine()函数用法:
放射变换函数,可实现旋转,平移,缩放;变换后的平行线依旧平行
dst = cv.warpAffine(img,M,(cols,rows))
中,img为需要变换的图像,M为需要平移的位置,(cols,rows)为平移后图像尺寸。
1.2 cv2.getRotationMatrix2D()实现图像旋转
M=cv2.getRotationMatrix2D(center, angle, scale)
中参数含义:
- center:图片的旋转中心
- angle:旋转角度
- scale:旋转后图像相比原来的缩放比例
- M:计算得到的旋转矩阵
效果展示:
2.图像的仿射变换
图像的旋转加上拉升就是图像仿射变换,仿射变化也是需要一个M矩阵就可以,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵,OpenCV提供了根据变换前后三个点的对应关系来自动求解M。这个函数是
M=cv2.getAffineTransform(pos1,pos2)
,其中两个位置就是变换前后的对应位置关系。输 出的就是仿射矩阵M
。然后再使用函数cv2.warpAffine()
。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('haojin.jpg')
rows,cols,ch = img.shape # 行数、列数、通道数
print(rows,cols,ch)
pts1 = np.float32([[50,50],[200,50],[100,200]])
pts2 = np.float32([[100,100],[200,50],[100,200]])
M = cv.getAffineTransform(pts1,pts2) # 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')
plt.show()
2.1 函数详析
rows,cols,ch = img.shape
行数、列数、通道数
M = cv.getAffineTransform(pts1,pts2)
pts1:原始图像,三个点; pts2:目标图像,三个点。
效果展示:
3.图像的透视变换
透视需要的是一个3*3的矩阵,同理opencv在构造这个矩阵的时候还是采用一种点对应的关系来通过函数自己寻找的,因为我们自己很难计算出来。这个函数是M = cv2.getPerspectiveTransform(pts1,pts2)
,其中pts需要变换前后的4个点对应位置。得到M后在通过函数cv2.warpPerspective(img,M,(200,200))
进行。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('haojin.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) # pts1原始图像,四个点 pts2目标图像,四个点
dst = cv.warpPerspective(img,M,(1080,1080))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()
3.1 cv.warpPerspective()函数
透视变换函数,可保持直线不变形,但是平行线可能不再平行
其相关参数和cv2.warpAffine函数的类似,不再做介绍
效果展示: