OpenCV--图像基本操作

环境配置:

  • 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.15

  • IDE:如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)
image.png
# 只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv_show('G',cur_img)
image.png
# 只保留B
cur_img = img.copy()
cur_img[:,:,1] = 0
cur_img[:,:,2] = 0
cv_show('B',cur_img)
image.png

边界填充
扩充图像边界 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()

image.png

数值计算

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]
image.png

图像融合

  • 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 #不能直接相加


image.png
image.png
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()
image.png
  • 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)

image.png
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键退出

你可能感兴趣的:(OpenCV--图像基本操作)