环境配置:
Anaconda:https://www.anaconda.com/download/
Python 3.6
安装opencv和拓展包3.4.1.15(opencv-python、opencv-contrib-python):
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python==3.4.1.15
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python==3.4.1.15IDE:如PyCharm、VScode、Eclipse等,按自己的喜好,选择一个能debug就好
-
图片组成:
图片由h * w * c个像素组成(一般分为R/G/B三个通道时,每个通道图片由h * w个像素组成),像素范围在0-255(即黑-白),故图片的numpy数组格式为uint8足以。
1.数据读取-图像
- cv2.IMREAD_COLOR:彩色图像
- cv2.IMREAD_GRAYSCALE:灰度图像
【注】matplotlib inline 在jupyter展示中,图绘制完了直接进行展示,不用plt.show()显示
opencv读取的格式是BGR
import cv2 # opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
img = cv2.imread('cat.jpg')
图像的显示
# 图像的显示,也可以创建多个窗口
cv2.imshow('image',img)
# 等待时间,毫秒级,0表示任意键终止。 如果设定1000,大概10s就销毁窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
规范一下,写个小函数,定义图像名 并 传入已读取的图像,即可显示
def cv_show(img_name,img): #函数作为后面调用
cv2.imshow('image',img)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()
读取格式的转换
读取图片的同时转换为灰度图像
img.shape 图像的形状
img_gray = cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE) #按照灰度图片读取
print(img_gray, img_gray.shape) # 灰度图是2维 (414, 500)
cv_show('cat_gray',img_gray)
图像保存
imwrite需要两个参数:(路径名)图片名, 图
cv2.imwrite('cat_gray.jpg',img_gray)
基础属性
- img.shape 图片形状 (h, w, c)
- img.size 文件大小
- img.dtype 数据类型
- type(img) 图像类型
截取部分图像数据
感兴趣区域(ROI)的截取 [x:x+w,y:y+h]
img = cv2.imread('cat.jpg')
img_crop = img[100:200,50:200]
cv2.imshow('cat_crop',img_crop)
颜色通道提取、组合
- split 分离颜色通道
- merge 组合颜色通道(注 两个括号)
import cv2
b,g,r = cv2.split(img) # cv2.split(img)[0] 等同于 img[:,:,0]取第一个通道
b[100:200,50:200] = 0
img_new = cv2.merge((b,g,r)) #将提取出的b,g,r赋值给img_new形成一个彩图
cv2.imshow('img_new',img_new)
cv2.waitKey(0)
单独保留某个通道,其他通道置0
比如将蓝色通道都置0,绿 红通道 这块区域的值没变,则组合成黄色
# 只保留R
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,1] = 0
cv_show('R',cur_img)
# 只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv_show('G',cur_img)
# 只保留B
cur_img = img.copy()
cur_img[:,:,1] = 0
cur_img[:,:,2] = 0
cv_show('B',cur_img)
边界填充
扩充图像边界 copyMakeBorder,需要6个参数:图+上+下+左+右(填充的像素大小)+填充方式
填充方式如下:
- BORDER_REPLICATE:复制法,也就是复制最边缘像素。
- BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
- BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
- BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
- BORDER_CONSTANT:常量法,常数值填充。
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('cat.jpg')
top_size,bottom_size,left_size,right_size = (50,50,50,50)
img_replace = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REPLICATE)
img_reflect = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT)
img_reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
img_wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
img_constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)
# cv_show('img_wrap',img_wrap)
plt.subplot(231),plt.imshow(img,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(img_replace,'gray'),plt.title('Replace')
plt.subplot(233), plt.imshow(img_reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(img_reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(img_wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(img_constant, 'gray'), plt.title('CONSTANT')
plt.savefig('cat_fill.jpg')
plt.show()
数值计算
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')
img_cat2= img_cat +10
img_cat[:5,:,0]
img_cat2[:5,:,0]
图像融合
- cv2.resize(img, (新img的宽, 高)) 融合两张图的前提是尺寸一致
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')
#img_cat + img_dog # 不能直接相加
# 普通resize
img_dog = cv2.resize(img_dog,(img_cat.shape[1],img_cat.shape[0]))
print(img_dog.shape)
cat_dog = img_cat+img_dog
cv_show('cat_dog',cat_dog)
img_cat + img_dog #不能直接相加
import matplotlib.pyplot as plt
# 放大倍数的resize
big_cat = cv2.resize(img_cat,(0,0),fx=4,fy=4)
long_cat = cv2.resize(img_cat,(0,0),fx=3,fy=1)
plt.subplot(121),plt.imshow(big_cat),plt.title('big_cat')
plt.subplot(122),plt.imshow(long_cat),plt.title('long_cat')
plt.show()
- cv2.addWeighted 就相当于α * X1 + β * X2 + b,α=0.4,β=0.6,分别是两张图片的权重,以这样的形式融合
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')
# 普通resize
img_dog = cv2.resize(img_dog,(img_cat.shape[1],img_cat.shape[0]))
res = cv2.addWeighted(img_cat,0.4,img_dog,0.6,0)
cv_show('res',res)
2、视频数据读取
- cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1。
- 如果是视频文件,直接指定好路径即可。
vc = cv2.VideoCapture('test.mp4')
# 检查是否打开正确
if vc.isOpened():
open, frame = vc.read()
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('result', gray)
if cv2.waitKey(100) & 0xFF == 27:
break
vc.release()
cv2.destroyAllWindows()
- cv2.waitKey(100) 隔多少毫秒显示下一张图片,设置稍大点,符合我们看视频的一个速度。太大就像看视频卡顿的感觉;太小就像几倍速播放,太快了。
- 0xFF == 27 指定退出键退出
- 0xFF == ord(‘q’) 指定q键退出