opencv中读取图片、视频以及对其基本操作
一、清华TUNA提供的Anaconda仓库镜像
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
二、图像读取与基本操作
在执行下述代码时,出现的问题有:
If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or config
解决的办法是,降低opencv-contrib-python==3.4.3.18.的版本:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn opencv-contrib-python==3.4.3.18
在解决问题中,大多是说,由于没有安装opencv-python或者是没有安装opencv-opencv-contrib-python,但是这两个模块均已近安装。
执行代码:
import cv2 import matplotlib.pyplot as plt import numpy as np # %matplotlib inline = plt.show img = cv2.imread('cat.png') print(img) cv2.imshow("image",img) # 等待时间,毫秒级,0表示任意键终止 cv2.waitKey(0) cv2.destroyAllWindows()
输出:
[[[255 255 255]
[220 219 223]
[109 116 131]....
并读取到图片:
# 每次写上述的三行就比较的麻烦,于是定义如下的函数 def cv_show(name, img): cv2.imshow(name, img) cv2.waitKey(1000) cv2.destroyAllWindows() # 获取图像的属性,HWC print(img.shape) # 运行结果(158, 226, 3) 读取到的是一个RGB的彩色图 # 读取灰度图像 img = cv2.imread('cat.png', cv2.IMREAD_GRAYSCALE) print(img) print(img.shape) # 运行结果:[[255 220 119 ... 255 255 255] # [167 66 67 ... 186 255 255] # [ 65 65 67 ... 117 175 255] # ... # [ 97 96 97 ... 112 173 255] # [178 91 92 ... 186 255 255] # [255 224 135 ... 255 255 255]] # (158, 226) 此处可以看到的是,只有了HW,变成灰度图像,只有两个中括号 # 展示显示结果 或者:
cv_show('image',img) cv2.imshow('image',img) cv2.waitKey(1000) cv2.destroyAllWindows()
显示的灰度图像:
# 保存 cv2.imwrite('mycat.png', img) print(type(img)) # 保存成功,运行结果:<class 'numpy.ndarray'>,注意在mycat中要加上.png # 展示尺寸 结果为:35708 print(img.size) # 数据类型 uint8 print(img.dtype)
三、视频的读取与基本操作
视频是图像静止的时间变化的。所以视频的处理就是一张一张的图像连接起来的。
第一步。将视频拆分成图像。
实例代码:
import cv2 import matplotlib.pyplot as plt # # 对视频的读取 vc =cv2.VideoCapture('test.mp4') # # # 每次写上述的三行就比较的麻烦,于是定义如下的函数 def cv_show(name, img): cv2.imshow(name, img) cv2.waitKey(1000) cv2.destroyAllWindows() # 检查打开是否是正确的,vc.read()循环检查每一张图像 if vc.isOpened(): # open打开图像返回True,frame打开结果 open, frame = vc.read() else: open = False # 遍历每一帧,组成一个视频 while open: # 读取图片 ret, frame = vc.read() # 若视频只有10秒,十秒之后,就为空,所以,如果读取为空,就跳出循环 if frame is None: break # 如果读取的这一帧图像正确 if ret ==True: # 将当前图像(frame)图像转化成黑白的 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 展示结果 cv2.imshow('result', gray) # 操作完视频的速度 if cv2.waitKey(50) & 0xFF ==27: break vc.release() cv2.destroyAllWindows() # 截取部分图像数据 ,结果就是显示部分的图像 img = cv2.imread('cat.png') cat = img[0:100,0:200] # H=100,W=200 cv_show('cat',cat) # 颜色通道的提取 b,g,r = cv2.split(img) print(b) print(b.shape) # 运行结果:[[255 220 109 ... 255 255 255] # [163 47 44 ... 178 255 255] # [ 43 45 44 ... 87 164 255] # ... # [ 66 62 63 ... 76 158 255] # [170 59 59 ... 175 255 255] # [255 222 118 ... 255 255 255]] # (158, 226) shape 的结果都是一样的无论是哪一个通道 # 拆开后组合在一起 img = cv2.merge((b, g, r)) print(img.shape) # 结果:(158, 226, 3) # 只保留R R的索引值为2,GBR cur_img = img.copy() cur_img[:,:,0] = 0 cur_img[:,:,1] = 0 cv_show('R', cur_img) # 只保留G G的索引值为0,GBR cur_img = img.copy() cur_img[:,:,1] = 0 cur_img[:,:,2] = 0 cv_show('G', cur_img) # 只保留B B的索引值为1,GBR cur_img = img.copy() cur_img[:,:,0] = 0 cur_img[:,:,2] = 0 cv_show('B', cur_img) # 边界填充 top_size, bottom_size, left_size, right_size = (50, 50, 50, 50) # BORDER_REPLICATE:复制发,复制的最边缘的像素 replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE) # BORDER_REFLECT: 反射法,对感兴趣的图像图像中的像素,在两边进行复制 reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT) # BORDER_REFLECT_101: 以最边缘像素为轴,对称 reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101) # BORDER_WRAP:外包装法 wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP) # BORDER_CONSTANT: 常数法,常数值填充 constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_CONSTANT,value=0) 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') plt.show() # 数值计算 img_cat = cv2.imread('cat.png') img_dog = cv2.imread('dog.png') # 三个通道上,每一个都加10 img_cat2 = img_cat + 10 # 打印前五行 print(img_cat[:5, :, 0]) print(img_cat2[:5,: ,0]) # 运行结果:[[255 220 109 ... 255 255 255] # [163 47 44 ... 178 255 255] # [ 43 45 44 ... 87 164 255] # [ 46 46 45 ... 94 89 181] # [ 46 45 46 ... 95 94 93]] # [[ 9 230 119 ... 9 9 9] # [173 57 54 ... 188 9 9] # [ 53 55 54 ... 97 174 9] # [ 56 56 55 ... 104 99 191] # [ 56 55 56 ... 105 104 103]] print((img_cat+img_cat2)[:5,: ,0]) # 运行结果:[[ 8 194 228 ... 8 8 8] # [ 80 104 98 ... 110 8 8] # [ 96 100 98 ... 184 82 8] # [102 102 100 ... 198 188 116] # [102 100 102 ... 200 198 196]] 超过255的用大数%255得8 print(cv2.add(img_cat,img_cat2)[:5,: ,0]) #超过255取255,没有超过则取本身 # 图像融合 # print(img_cat + img_dog) 图像得GBR不匹配 print(img_cat.shape) print(img_dog.shape) # (158, 226, 3) # (371, 500, 3) img_dog = cv2.resize(img_dog,(226,158)) print(img_dog.shape)
# R=ax1+bx2+b 0.4就是权重a,0.6就是权重b,0就是偏置 res = cv2.addWeighted(img_cat,0.4, img_dog, 0.6, 0) plt.imshow(cv2.cvtColor(res, cv2.COLOR_BGR2RGB)) plt.show() # 拉伸 res = cv2.resize(img_dog, (0,0),fx = 3, fy=1) plt.imshow(cv2.cvtColor(res, cv2.COLOR_BGR2RGB)) plt.show() res = cv2.resize(img_dog,(0,0),fx = 1, fy=3) plt.imshow(cv2.cvtColor(res, cv2.COLOR_BGR2RGB)) plt.show()