2 - 基本概念及操作


图像基本概念

计算机里图像是每个像素拼接而成的。

每个像素的值是0-255,代表亮度,0是黑色,255是白色。

彩色有RED,GREEN,BLUE三个通道,灰度图只有一个通道。

基本操作

读取并显示图像

import cv2

img1 = cv2.imread('cat.jpg')  # 读为彩色图
img2 = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)  # 读为灰度图

# 图像的显示,也可以创建多个窗口
cv2.imshow('image', img1)
# 等待时间,毫秒,0标识任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()

读取视频

视频是由一帧一帧的图像组成的。

vc = cv2.VideoCapture('test.mp4')
if vc.isOpened():
    # 遍历所有帧
    while True:
        ret, frame = vc.read()
        if frame is None:
            break
        if ret:
            cv2.imshow('result', cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY))
            if cv2.waitKey(1) & 0xFF == 27:  # esc按键
                break
vc.release()
cv2.destroyAllWindows()

shape属性

img1 = cv2.imread('cat.jpg')
print(img1.shape)
# (367, 444, 3),H(高)、W(宽)、C(彩色图)

img2 = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)
print(img2.shape)
# (367, 444),因为是灰度图,只有HW

保存图片

cv2.imwrite('mycat.png',img)

获取像素个数

img.size

截取部分图像数据

img = cv2.imread('cat.jpg')
cat = img[0:200, 0:200]
cv2.imshow('image', cat)
cv2.waitKey(0)
cv2.destroyAllWindows()

颜色通道操作

img = cv2.imread('cat.jpg')
b, g, r = cv2.split(img)
print(b.shape)  
# (367, 444)

改变图像宽高

# 会改变图像的宽高比
dogImg1 = cv2.imread('dog.jpg')
# 指定宽高,W,H
dogImg2 = cv2.resize(dogImg, (444, 367))
# 指定拉长比例
dogImg3 = cv2.resize(dogImg, (0, 0), fx=3, fy=1)
# 可以同时指定宽高和拉长比例

边界填充

img = cv2.imread('cat.jpg')
# 上下填充 10 像素,左右填充 20 像素
top, bottom, left, right = (10, 10, 20, 20)

# 复制最边缘像素
replicate = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REPLICATE)
# 边界倒影,edcba|abcdefgh|hgfed
reflect = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REFLECT)
# 边界倒影,edcb|abcdefgh|gfed
reflect101 = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REFLECT_101)
# 外包装,defgh|abcdefgh|abcde
wrap = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_WRAP)
# 用常量填充
constant = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, 0)

cv2.imshow('image', replicate)
cv2.waitKey(0)
cv2.destroyAllWindows()

replicate

# 复制最边缘像素
replicate = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REPLICATE)

reflect

# 边界倒影,edcba|abcdefgh|hgfed
reflect = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REFLECT)

reflect101

# 边界倒影,edcb|abcdefgh|gfed
reflect101 = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REFLECT_101)

wrap

# 外包装,defgh|abcdefgh|abcde
wrap = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_WRAP)

constant

# 用常量填充
constant = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, 0)

图片数值相加

catImg1 = cv2.imread('cat.jpg')
# 每个像素值都会 + 10
catImg2 = catImg1 + 10
# 两个图像 shape 要一样
# 像素值和 % 256
catImg3 = catImg1 + catImg2
# if 像素值和 <= 255,取像素值和,else 取 255
catImg4 = cv2.add(catImg1, catImg2)

图像融合

cat shape(367, 444, 3)

dog shape(383, 448, 3)

catImg = cv2.imread('cat.jpg')
dogImg = cv2.imread('dog.jpg')
dogImg = cv2.resize(dogImg, (444, 367))
# 两个图像 shape 要一样
# 比重,颜色偏移值
res = cv2.addWeighted(catImg, 0.4, dogImg, 0.6, 0)
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

res

图像阈值

ret,dst=cv2.threshold(src,thresh,maxval,type)

  • src:输入图,只能输入单通道图像,通常来说为灰度图
  • dst:输出图
  • thresh:阈值
  • maxval:当像素值超过了阈值(或者小于阈值,根据 type 来决定),所赋予的值
  • type:二值化操作的类型
img = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)
ret, img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

原始

THRESH_BINARY:超过阈值部分取maxval,否则取0

THRESH_BINARY_INV:THRESH_BINARY的反转,未超过阈值部分取maxval,否则取0

THRESH_TRUNC:大于阈值部分设为阈值,否则不变

THRESH_TOZERO:大于阈值部分不改变,否则设置0

THRESH_TOZERO_INV:THRESH_TOZERO的反转,小于阈值部分不改变,否则设置0