基于OpenCV 的图像 基本操作(一)

805 阅读3分钟

语言:Python 3.8.3

依赖库:

numpy,matplotlib,opencv-python

一、图像宽、高、通道数获取

import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
# opencv 默认读取是BGR
mat = cv.imread('pj.jpeg')
# matplotlib 默认显示是RGB
mat = cv.cvtColor(mat, cv.COLOR_BGR2RGB) 
(h, w , c) = mat.shape[0:3]
print('宽:{0}\n高:{1}\n通道:{2}'.format(w, h, c))
宽:299
高:300
通道:3

二、修改图像像素点

# 左边区域像素点修改
c_mat = np.array(mat)
c_mat[0:cy, 0:cx] = (0, 255, 0)
plt.imshow(c_mat)
plt.show()

三、图像裁剪

cx = w // 2
cy = h // 2
left_top = mat[0:cy, 0:cx]
left_bottom = mat[cy:h, 0:cx]
right_top = mat[0:cy, cx:w]
right_bottom = mat[cy:h, cx:w]
imgs = [mat, left_top, right_top, left_bottom, right_bottom]
# matplot 默认是显示RGB
plt.figure(figsize=(12,2))
for i in range(5):
    plt.subplot(1, 5, i+1)
    plt.imshow(imgs[i])
plt.show()

四、图像平移

# [1,0,150] x:移动150 ,[0,1,150] y:移动100
translation_m = np.float32([[1, 0, 150], [0, 1, 100]])
t_mat = cv.warpAffine(mat, translation_m, (w, h))
plt.imshow(t_mat)
plt.show()                           

五、图像旋转

# (cx, cy)中心点旋转;正:逆时针旋转40度 负:顺时针旋转40度;1.0 缩放比例
rotation_m = cv.getRotationMatrix2D((cx, cy), 40,1.0)
rotation_mat = cv.warpAffine(mat, rotation_m, (w, h))
plt.imshow(rotation_mat)
plt.show()

六、图像大小重定义

interpolation的五种模式

  • interpolation=cv.INTER_NEAREST 最领近
  • interpolation=cv.INTER_LINEAR 双线性
  • interpolation=cv.INTER_AREA 基于像素区域的
  • interpolation=cv.INTER_CUBIC 立方插值
  • interpolation=cv.INTER_LANCZOS4 兰索斯插值
# 重新定义图像宽度
width = 80
# 重新定义图像高度
height = width * h // w
resize_mat = cv.resize(mat, (width, height), interpolation=cv.INTER_LANCZOS4)
plt.imshow(resize_mat)
plt.show()
print(mat.shape)
print(resize_mat.shape)

七、图像翻转

flip_mat_h = cv.flip(mat, 1)
flip_mat_v = cv.flip(mat, 0)
flip_mat_h_v = cv.flip(mat, -1)
imgs = [mat, flip_mat_h, flip_mat_v, flip_mat_h_v]
plt.figure(figsize=(10,2))
for i in range(4):
    plt.subplot(1, 4, i+1)
    plt.imshow(imgs[i])
plt.show()

八、图像算术

  • 利用opencv 加法 提亮图像
m = np.ones(mat.shape, dtype='uint8')*100 # 创建
add_mat = cv.add(mat, m)
imgs = [mat, add_mat]
plt.figure(figsize=(6,2))
for i in range(2):
    plt.subplot(1, 2, i+1)
    plt.imshow(imgs[i])
plt.show()

  • 利用opencv 减法 使图像变暗
sub_mat = cv.subtract(mat, m)
imgs = [mat, add_mat, mat, sub_mat]
plt.figure(figsize=(6,6))
for i in range(4):
    plt.subplot(2, 2, i+1)
    plt.imshow(imgs[i])
plt.show()

  • 与 运算

1 & 1 = 1; 1 & 0 = 0; 0 & 1 = 0; 0 & 0 = 0;

rect = np.ones((200, 200, 3), dtype='uint8')
white = (255, 255, 255)
cv.rectangle(rect, (25,25), (200-25, 200-25), white, -1)

circle = np.ones(rect.shape, dtype='uint8')
cv.circle(circle, (100, 100), 100, white, -1)

bit_and = cv.bitwise_and(rect, circle)
imgs = [rect, circle, bit_and]
plt.figure(figsize=(10,4))
for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.imshow(imgs[i])
plt.show()

  • 或 运算 1 | 1 = 1; 1 | 0 = 1; 0 | 1 = 1; 0 | 0 = 0
bit_or = cv.bitwise_or(rect, circle)
imgs = [rect, circle, bit_or]
plt.figure(figsize=(10,4))
for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.imshow(imgs[i])
plt.show()

  • 异或 运算

1 ^ 1 = 0; 0 ^ 1 = 1; 1 ^ 0 = 1; 0 ^ 0 = 0

bit_xor = cv.bitwise_xor(rect, circle)
imgs = [rect, circle, bit_xor]
plt.figure(figsize=(10,4))
for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.imshow(imgs[i])
plt.show()

  • 非 运算

^ 1 = 0; ^ 0 = 1

bit_rect_no = cv.bitwise_not(rect)
bit_circle_no = cv.bitwise_not(circle)
imgs = [rect, bit_rect_no, circle, bit_circle_no]
plt.figure(figsize=(6,6))
for i in range(4):
    plt.subplot(2, 2, i+1)
    plt.imshow(imgs[i])
plt.show()

  • 按位运算创建遮挡
rect = np.zeros(mat.shape, dtype='uint8')
white = (255, 255, 255)
cv.rectangle(rect, (50, 50), (w-50, h-50), white, -1)
bit_mat_and = cv.bitwise_and(mat, rect)
# 原图,遮挡物,生成遮挡图
imgs = [mat, rect, bit_mat_and]
plt.figure(figsize=(6,6))
for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.imshow(imgs[i])
plt.show()

九、图像通道切分与合并

(R, G, B) = cv.split(mat)
merged = cv.merge([R, G, B])
# 原图;R 单通道;G 单通道; B 单通道;合并
imgs  = [mat, R, G, B, merged]
plt.figure(figsize=(12,6))
for i in range(4):
    plt.subplot(1, 4, i+1)
    plt.imshow(imgs[i])
plt.show()

十、高斯金字塔 和 拉普拉斯金字塔

  • 高斯金字塔
plt.figure(figsize=(12,6))
# 通过高斯加权平均 缩小图片尺寸
mat1 = cv.pyrDown(mat)
imgs = [mat, mat1]
titles = ['{0}'.format(mat.shape),'{0}'.format(mat1.shape)]
for i in range(4):
    mat2 = cv.pyrDown(mat1)
    mat1 = mat2
    imgs.append(mat2)
    titles.append('{0}'.format(mat2.shape))
for i in range(5):
    plt.subplot(1, 5, i+1)
    plt.imshow(imgs[i])
    plt.title(titles[i])
plt.show()

plt.figure(figsize=(12,6))
# 通过高斯加权平均 放大图片
mat1 = cv.pyrUp(mat)
imgs = [mat, mat1]
titles = ['{0}'.format(mat.shape),'{0}'.format(mat1.shape)]
for i in range(4):
    mat2 = cv.pyrUp(mat1)
    mat1 = mat2
    imgs.append(mat2)
    titles.append('{0}'.format(mat2.shape))
for i in range(5):
    plt.subplot(1, 5, i+1)
    plt.imshow(imgs[i])
    plt.title(titles[i])
plt.show()

  • 拉普拉斯金字塔
down_mat1 = cv.pyrDown(mat)
down_mat2 = cv.pyrDown(down_mat1)
up_mat1 = cv.pyrUp(down_mat2)
laplacian = down_mat1 - up_mat1
plt.imshow(laplacian)
plt.show()