###2.1 OpenCV的色彩空间
最常见的色彩空间就是RGB, 人眼也是基于RGB的色彩空间去分辨 颜色的.
OpenCV默认使用的是BGR. BGR和RGB色彩空间的区别在于图片在色彩通道上的排列顺序不同.
显示图片的时候需要注意适配图片的色彩空间和显示环境的色彩空间.比如传入的图片是BGR色彩空间, 显示环境是RBG空间, 就会出现颜色混乱的情况.
为什么要使用HSV?
方便OpenCV做图像处理.比如根据hue的值就可以判断背景颜色.
HSL和HSV差不多.
Hue: 色相
Saturation: 饱和度
Lightness: 亮度
HSL在顶部是纯白的, 不管是什么颜色.
YUV,是一种颜色编码方法。常使用在各个视频处理组件中。 YUV在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽。
“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。
Y’UV的发明是由于彩色电视与黑白电视的过渡时期。
Y’UV最大的优点在于只需占用极少的带宽。
4:4:4表示完全取样。
4:2:2表示2:1的水平取样,垂直完全采样。
4:2:0表示2:1的水平取样,垂直2:1采样。
4:1:1表示4:1的水平取样,垂直完全采样。
import cv2
def callback(value):
pass
cv2.namedWindow('color', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mouse', 640, 480)
img = cv2.imread('./cat.jpeg')
# 常见的颜色空间转换
colorspaces = [cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2BGRA,
cv2.COLOR_BGR2GRAY, cv2.COLOR_BGR2HSV,
cv2.COLOR_BGR2YUV]
cv2.createTrackbar('curcolor', 'color', 0, 4, callback)
while True:
index = cv2.getTrackbarPos('curcolor', 'color')
#颜色空间转换API
cvt_img = cv2.cvtColor(img, colorspaces[index])
cv2.imshow('color', cvt_img)
key = cv2.waitKey(10)
if key & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
Mat是OpenCV在C++语言中用来表示图像数据的一种数据结构.在python中转化为numpy的ndarray.
在python中Mat数据对应numpy的ndarray, 使用numpy提供的深浅拷贝方法即可实现Mat的拷贝.
import cv2
import numpy as np
img = cv2.imread('./cat.jpeg')
#浅拷贝
img2 = img.view()
#深拷贝
img3 = img.copy()
img[10:100, 10:100] = [0, 0, 255]
cv2.imshow('img', img)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
OpenCV中的Mat在python中已经转化为ndarray, 通过ndarray的属性即可访问Mat图像的属性
import cv2
import numpy as np
img = cv2.imread('cat.jpeg')
#shape属性中包括了三个信息
#高度,长度 和 通道数
print(img.shape)
#图像占用多大空间
#高度 * 长度 * 通道数
print(img.size)
#图像中每个元素的位深
print(img.dtype)
import cv2
import numpy as np
img = np.zeros((480, 640, 3), np.uint8)
b,g,r = cv2.split(img)
b[10:100, 10:100] = 255
g[10:100, 10:100] = 255
img2 = cv2.merge((b, g, r))
cv2.imshow('img', img)
cv2.imshow('b', b)
cv2.imshow('g', g)
cv2.imshow('img2', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
利用OpenCV提供的绘制图形API可以轻松在图像上绘制各种图形, 比如直线, 矩形, 圆, 椭圆等图形.
line(img, pt1, pt2, color, thickness, lineType, shift) 画直线
rectangle() 参数同上 画矩形
circle(img, center, radius, color[, thickness[, lineType[, shift]]]) 中括号内参数表示可选参数. 画圆
ellipse(img, 中心点, 长宽的一半, 角度, 从哪个角度开始, 从哪个角度结束,…)
import cv2
import numpy as np
img = np.zeros((480, 640, 3), np.uint8)
# cv2.line(img, (10, 20), (300, 400), (0, 0, 255), 5, 4)
# cv2.line(img, (80, 100), (380, 480), (0, 0, 255), 5, 16)
# 画矩形
# cv2.rectangle(img, (10,10), (100, 100), (0, 0, 255), -1)
# 画圆
# cv2.circle(img, (320, 240), 100, (0, 0, 255))
# cv2.circle(img, (320, 240), 5, (0, 0, 255), -1)
# 画椭圆
# cv2.ellipse(img, (320, 240), (100, 50), 15, 0, 360, (0, 0, 255), -1)
#画多边形
# pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
# cv2.polylines(img, [pts], True, (0, 0, 255))
#填充多边形
# cv2.fillPoly(img, [pts], (255, 255, 0))
cv2.putText(img, "Hello OpenCV!", (10, 400), cv2.FONT_HERSHEY_TRIPLEX, 3, (255,0,0))
cv2.imshow('draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制中文 opencv本身不支持, 因为没有中文字体.我们可以借助pillow来实现绘制中文
# 安装pillow
import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image
img = np.full((200, 200, 3), fill_value=255, dtype=np.uint8)
# 导入字体文件.
font_path = 'msyhbd.ttc'
font = ImageFont.truetype(font_path, 15)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
draw.text((10, 150), '绘制中文', font=font, fill=(0, 255, 0, 0))
img = np.array(img_pil)
# 中文会显示问号
cv2.putText(img, '中文', (10, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 1)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()