图像基本操作
-
图像构成
图像素点构成图像,像素点由R、G、B三颜色通道构成,值0-255越来越亮
R:红色,G:绿色,B:蓝色
灰度图只有一个通道表示亮度
-
图像的基本操作
读取图像、显示图像、保存图像
数据读取
-
cv2.IMREAD_COLOR:彩色图片
-
cv2.IMREAD_GRAYSCALE:灰度图片
import cv2 # 读取的格式时BGR
import matplotlib.pyplot as plt
import numpy as np
# 魔法指令,免去plt.show方法
%matplotlib inline
img = cv2.imread('./img/cat.jpg')
img
# 三个维度
# [h,w,c]
# 图像的显示,可以创建多个窗口
cv2.imshow('image', img)
# 等待时间,毫秒数,0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()
# 封装成函数
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 读入图片的属性
img.shape # h,w,c
# 显示灰度图
img = cv2.imread('./img/cat.jpg', cv2.IMREAD_GRAYSCALE)
img
img.shape
# 只有h,w,相当于只有一个颜色通道
cv_show('image', img)
# 图像保存
cv2.imwrite('./img/cat_gray.png', img)
type(img) # 底层格式
img.size # 像素点个数
img.dtype # 数据类型
数据读取-视频
-
cv2.VideoCapture 可以捕获摄像头,用数字来控制不同的设备,例如0,1
-
如果是视频文件,直接指定好路径即可
vc = cv2.VideoCapture('./video/test.mp4')
# 检查是否正确打开
if vc.isOpened():
oepn, frame = vc.read() # 能否读入,bool值;当前帧的图像,三维数组(一个图片)
else:
open = False
while open:
ret, frame = vc.read() # 读入帧
if frame is None:
break
if ret == True: # 正常读入
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 彩色转灰度
cv2.imshow('reslult', gray)
if cv2.waitKey(50) & 0xFF == 27: # 27表示退出键,播放过程中点击退出键值为27
break
vc.release() # 用于在对象超出范围或被删除之前释放视频捕获对象所持有的任何资源
cv2.destroyAllWindows()
### 截取部分图像数据
img = cv2.imread('./img/cat.jpg')
# 通过切片截取
cat = img[0:200, 0:200]
cv_show('cat', cat)
颜色通道提取
# 两种颜色通道提取方式
b, g, r = cv2.split(img)
b1 = img[:, :, 0]
g1 = img[:, :, 1]
r1 = img[:, :, 2]
b, g, r
b1, g1, r1
# 颜色通道组合
img1 = cv2.merge((b, g1, r))
cv_show('img1', img1)
img.shape
# 只保留R
cur_img = img.copy()
cur_img[:, :, 0] = 0
cur_img[:, :, 1] = 0
cv_show('R', cur_img)
边界填充
# 指定填充值
top_size, bottom_size, left_size, right_size = (50,50, 50, 50)
# 复制法,复制最边缘的像素
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
# 反射法,对指定图像中的像素在两边进行复制,复制方式如: fedcba|abcdefgh|hgfedcb
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT)
# 反射法,以最边缘像素为轴,进行对称,如: gfedcb|abcdefg|fedcba
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
# 外包装法,如 cdefgh|abcdefgh|abcdefg
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_WRAP)
# 常量法,常数值填充,外边框
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_CONSTANT)
import matplotlib.pyplot as plt
# 创建一个2x3的子图,并在第1个子图中显示灰度图像img,并添加标题为'ORIGINAL'
plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('replicate')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('reflect')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('reflect101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('wrap')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('constant')
数值计算
img_cat = cv2.imread('./img/cat.jpg')
img_dog = cv2.imread('./img/dog.png')
img_cat2 = img_cat + 10
img_cat[:5,:,0] # 取前5行打印
img_cat2[:5,:,0]
# 结果会对256取余
(img_cat + img_cat2)[:5,:,0]
# add结果不会取余,越界取最大值
cv2.add(img_cat, img_cat2)[:5,:,0]
图像融合
# 指定图片的shape值
img_dog.shape
img_cat = cv2.resize(img_cat, (512, 675)) # (w, h)
img_cat.shape
# addWeighted 两个输入图像、它们各自的权重系数、以及一个可选的gamma参数
res = cv2.addWeighted(img_cat, 0.5, img_dog, 0.5, 0)
plt.imshow(res)
# resize 指定倍数关系,(h, w)设置为0
res = cv2.resize(img, (0, 0), fx=3, fy=1)
plt.imshow(res)
res = cv2.resize(img, (0, 0), fx=5, fy=3)
plt.imshow(res)