一、 OpenCV之图像简易处理

一、图像基本操作

1.1 图像的读取

import cv2
import numpy as np  # 数据处理工具包

"""
cv2.IMREAD_COLOR  彩色图像
cv2.IMREAD_GRAYSCALE  灰度图像
"""


def cv_show(name, img):
    # 显示图片, 也可以创建多个窗口,在窗口上显示图片
    cv2.imshow(name, img)  # 第一个参数代表图像名称,第二个参数代表图像
    # 等待时间,毫秒级, 0 代表任意终止,按任意键关闭
    cv2.waitKey(0)
    # 关闭窗口
    cv2.destroyAllWindows()


# 读取彩色图片
img_color = cv2.imread("../images/cat.jpg", cv2.IMREAD_COLOR)  # opencv 读取的格式是BGR, 不是RGB, 输出也是 BGR格式
cv_show("img_color", img_color)
# print(img_color)  # 输出像素点的矩阵
"""
[[[142 151 160]
  [146 155 164]
  [151 160 170]
  ...
  [183 198 200]
  [128 143 145]
  [127 142 144]]]
"""
# print(type(img_color))  # <class 'numpy.ndarray'>
# 获取图像的 H(高), W(宽), C(3, 代表BGR的彩色图)
# print(img_color.shape)  # (414, 500, 3)

# 读取灰度图
img_grayscale = cv2.imread("../images/cat.jpg", cv2.IMREAD_GRAYSCALE)
cv_show("img_grayscale", img_grayscale)
# 获取图像的 H(高), W(宽),
# print(img_grayscale.shape)  # (414, 500)  灰度图只有两个结果


# 保存图片
cv2.imwrite("my_cat.png", img_grayscale)

# 获取图片类型
print(type(img_grayscale))  # <class 'numpy.ndarray'>
# 获取图片大小
print(img_grayscale.size)  # 207000
# 获取像素点数据类型
print(img_grayscale.dtype)  # uint8

1.2 图像的截取

import cv2


def cv_show(name, img):
    # 显示图片, 也可以创建多个窗口,在窗口上显示图片
    cv2.imshow(name, img)  # 第一个参数代表图像名称,第二个参数代表图像
    # 等待时间,毫秒级, 0 代表任意终止,按任意键关闭
    cv2.waitKey(0)
    # 关闭窗口
    cv2.destroyAllWindows()


img = cv2.imread("../images/cat.jpg")
cv_show("source picture", img)
# 截取部分图像数据 
cat = img[0:50, 0:200]  # 代表图片截取,长为0-50, 宽为 0-200的像素点
cv_show("split picture", cat)

 

"""
OpenCV中,图像通常是以 NumPy数组的形式存储的,并且通常是三维的: 高度,宽度,颜色通道,对于彩色图像,通道的顺序通常是 BGR(蓝, 绿, 红)

image[:, :, 0] 是一个使用NumPy数组切片来获取图像中特定通道的方法, 0代表通道的索引, 对于BGR图像,表示蓝色通道,1表示绿色通道,2代表红色通道
"""

# 颜色通道截取
b, g, r = cv2.split(img)
# print(len(b), b)  # 414  [[142 146 151 ... 156 155 154]...]]
# print(b.shape)  # (414, 500), b, g, r都是一样的

img = cv2.merge((b, g, r))  # merge 可以将b, g, r重新组装成图片
print(img)
print(img.shape)  # (414, 500, 3)
cv_show("rebuild picture", img)

# 只保留 R  (B, G, R)  (图R)
cur_img_R = img.copy()
cur_img_R[:, :, 0] = 0
cur_img_R[:, :, 1] = 0

# 只保留 G  (B, G, R)  (图G)
cur_img_G = img.copy()
cur_img_G[:, :, 0] = 0
cur_img_G[:, :, 2] = 0

# 只保留 B  (B, G, R) (图B)
cur_img_B = img.copy()
cur_img_B[:, :, 1] = 0
cur_img_B[:, :, 2] = 0

res = np.hstack((cur_img_R, cur_img_G, cur_img_B))
cv_show("res", res)

 

1.3 图像的边界填充

import cv2
import matplotlib.pyplot as plt


def subplot(num, picture, name, title):
    plt.subplot(num)
    plt.imshow(picture, name)
    plt.title(title)


# 上下左右各填充50
top_size, bottom_size, left_size, right_size = (50, 50, 50, 50)

img = cv2.imread("../images/cat.jpg")

# borderType 填充方法
"""
BORDER_REPLICATE: 复制法, 也就是复制最边缘像素
BORDER_REFLECT: 反射法,对感兴趣的图像的像素在两边进行复制, 如  fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101: 反射法, 也就是一最边缘像素为轴对称, 如  gfedcb|abcdefgh|gfedcba, 比上面反射优化了点
BORDER_WRAP: 外包装法   cdefg|abcdefgh|abcdefg
BORDER_CONSTANT: 常量法, 常数值填充
"""
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size,left_size, right_size,cv2.BORDER_CONSTANT, value=0)  # 0 代表黑框

subplot(231, img, "gray", "ORIGINAL")
subplot(232, replicate, "gray", "REPLICATE")
subplot(233, reflect, "gray", "REFLECT")
subplot(234, reflect101, "gray", "REFLECT101")
subplot(235, wrap, "gray", "WRAP")
subplot(236, constant, "gray", "CONSTANT")

plt.show()

1.4 图像的数值计算

import cv2

img_cat = cv2.imread("../images/cat.jpg")
img_dog = cv2.imread("../images/dog.jpg")

img_cat2 = img_cat + 10
print(img_cat[:5, :, 0])  # :5 只打印前五行
"""
[[142 146 151 ... 156 155 154]
 [108 112 118 ... 155 154 153]
 [108 110 118 ... 156 155 154]
 [139 141 148 ... 156 155 154]
 [153 156 163 ... 160 159 158]]
"""
print(img_cat2[:5, :, 0])
"""
[[152 156 161 ... 166 165 164]
 [118 122 128 ... 165 164 163]
 [118 120 128 ... 166 165 164]
 [149 151 158 ... 166 165 164]
 [163 166 173 ... 170 169 168]]
"""
print((img_cat + img_cat2)[:5, :, 0])  # 142 + 152 = 294   %    256  = 38
"""
[[ 38  46  56 ...  66  64  62]
 [226 234 246 ...  64  62  60]
 [226 230 246 ...  66  64  62]
 [ 32  36  50 ...  66  64  62]
 [ 60  66  80 ...  74  72  70]]
"""
# add 函数, 越界之后就取 255
print(cv2.add(img_cat, img_cat2)[:5, :, 0])
"""
[[255 255 255 ... 255 255 255]
 [226 234 246 ... 255 255 255]
 [226 230 246 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]]
"""

1.5 图像的融合

"""
addWeighted(arg1, arg2, arg3, arg4, arg5)
arg1: 输入图像1
arg2: 输入图像1的权重
arg3: 输入图像2
arg4: 输入图像2的权重
arg5: 可选值,默认为0
"""

import cv2
import time
import matplotlib.pyplot as plt

img_cat = cv2.imread("../images/cat.jpg")
img_dog = cv2.imread("../images/dog.jpg")
print(img_cat.shape)  # (414, 500, 3)
print(img_dog.shape)  # (429, 499, 3)
# print(img_cat + img_dog)  # ValueError: operands could not be broadcast together with shapes (414,500,3) (429,499,3)

img_dog = cv2.resize(img_dog, (500, 414))
# print(img_dog.shape)  # (414, 500, 3)


res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)  # 代表 ax1 + bx2  --> a, b代表权重
# plt.imshow(img_cat)
# res_rgb = cv2.cvtColor(res, cv2.COLOR_BGR2RGB)  # 将 BGR 转换成 RGB
plt.imshow(res)
plt.show()

# (0, 0) 代表不指定具体数值
res = cv2.resize(img_cat, (0, 0), fx=3, fy=1)  # 相当于x轴3倍, y轴1倍
plt.imshow(res)
plt.show()

res = cv2.resize(img_cat, (0, 0), fx=1, fy=3)  # 相当于x轴1倍, y轴3倍
plt.imshow(res)
plt.show()

 

二、视频基本操作

# 视频读取为一帧一帧读取,读取的一帧数据相当于一个图片,然后按照图片的方式来处理
import cv2

vc = cv2.VideoCapture("../images/test.mp4")
# print(vc)  # < cv2.VideoCapture 0B6F9ED0>

if vc.isOpened():  # 检查是否正常打开
    openFlag, frame = vc.read()  # 读取视频第一帧,返回第一个读取成功与否,第二个返回的帧图像信息
else:
    openFlag = False

while openFlag:
    ret, frame = vc.read()  # 每次read继续一帧一帧往下读
    if frame is None:  # 读完了
        break
    if ret:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 将图像转换成灰度图
        cv2.imshow("result", gray)
        if cv2.waitKey(10) & 0xFF == 27:  # 10 代表读取速度,速度越小越快, 27 代表退出键 (esc)
            break
vc.release()
cv2.destroyAllWindows()

 

posted on 2024-03-11 15:27  软饭攻城狮  阅读(45)  评论(0)    收藏  举报

导航