c++ opencv 批量resize图片_深度视觉笔记(一):图片处理

本文介绍了使用C++的OpenCV库批量处理图片,特别是如何进行图片resize操作。首先简要提及PIL(Python Imaging Library)及其在Python 3中的兼容版本Pillow。然后详细讨论了OpenCV的基础,包括读取图片、BGR与RGB的颜色空间差异,以及图片的裁剪、Resize、HSV空间和Gamma变换等图像处理技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9cb4034d65232ffbaf960bf46ea70a09.png

一、PIL

PIL(Python Imaging Library)是Python中一个图像处理标准库。PIL功能非常强大,但API却非常简单易用。PIL仅支持到Python 2.7,后来在PIL的基础上创建了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用Pillow。

1. 安装

sudo pip3 install pillow

2. 基本使用

打开图像文件

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# 定义一个函数后面用
def show_img(pos,title, img):
    plt.subplot(pos)
    plt.title(title)
    plt.imshow(img)

# 打开图像文件
img = Image.open('/root/workspace/liuzhen/dataset/cat.png')
# 看看长啥样
plt.imshow(img)
plt.show()

4ce51acc7749a94352d5c972c7fedd9d.png
Original

查看基本属性

print(img.format)
print(img.size)
print(img.mode)

# Output
JPEG
(1044, 722)
RGB

裁剪与Resize

crop_box = (400, 0, 1000, 600)
img_crop = img.crop(crop_box)
img_resize = img.resize((1024, 720))
plt.figure()
show_img(121, 'Corp Image', img_crop)
show_img(122, 'Resize Image', img_resize)
plt.show()plt.imshow(img_crop)
plt.show()

92c3a86c0387067390fd5325d812da85.png
Corp and Resize

旋转与翻转

img_gray = img.convert('F') # 灰度图,这里不展开介绍了
img_rotate = img.rotate((90)) # 旋转90度
img_transpose_1 = img.transpose(Image.FLIP_LEFT_RIGHT) # 左右翻转
img_transpose_2 = img.transpose(Image.FLIP_TOP_BOTTOM) # 上下翻转

plt.figure(figsize=(8,8))
show_img(221, 'Gray', img_gray)
show_img(222, 'Rotate', img_rotate)
show_img(223, 'Transpose_left_right', img_transpose_1)
show_img(224, 'Transpose_top_bottom', img_transpose_2)
plt.show()

192f03826b76665c530e8a175e92455c.png
Rotate and Transpose

二、OpenCV

OpenCV的强大就不废话了。这部分主要是对 @YE Y 《给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV》的学习过程与笔记。

import cv2

新手需要注意的是,在三通道图片中,最常见的是RGB,但是由于历史遗留问题,cv2默认读取的是BGR。如果你发现自己读取或者保存的图片泛着紫光或者绿光,多半是没注意这个问题。

bgr_color_image = cv2.imread('/root/workspace/liuzhen/dataset/cat.png')
rgb_color_image = cv2.cvtColor(bgr_color_image, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(8, 8))
show_img(121, 'BGR Color Image', bgr_color_image)
show_img(122, 'RGB Color Image', rgb_color_image)
plt.show()

4a2fe5c53d5a1eac83b4fbc569874de4.png
BGR and RGB

裁剪与Resize

patch_color_image = rgb_color_image[0:600, 400:1000]
resize_color_image = cv2.resize(rgb_color_image, (1024, 720))
plt.figure()
show_img(121, 'Patch Image', patch_color_image)
show_img(122, 'Resize Image', resize_color_image)
plt.show()

3b8eb1e218dc5faed358e29fada1961e.png
Patch and Resize

HSV空间

HSV空间是由美国的图形学专家A. R. Smith提出的一种颜色空间,HSV分别是色调(Hue),饱和度(Saturation)和明度(Value)。在HSV空间中进行调节避免了直接在RGB空间中调节时还需要考虑三个通道的相关性。OpenCV中H的取值是[0, 180),其他两个通道的取值都是[0, 256)
# HSV空间:HSV分别是色调(Hue),饱和度(Saturation)和明度(Value)
img_hsv = cv2.cvtColor(bgr_color_image, cv2.COLOR_BGR2HSV)
# 调整H
change_h = img_hsv.copy()
change_h[:, :, 0] = (change_h[:, :, 0] + 15) % 180
chagne_h_img = cv2.cvtColor(change_h, cv2.COLOR_HSV2RGB)

# 调整S 图片会损失鲜艳,变得更灰
change_s = img_hsv.copy()
change_s[:, :, 1] = 0.5 * change_s[:, :, 1] 
change_s_img = cv2.cvtColor(change_s, cv2.COLOR_HSV2RGB)

# 调整V 图片变暗
change_v = img_hsv.copy()
change_v[:, :, 2] = 0.5 * change_v[:, :, 2]
change_v_img = cv2.cvtColor(change_v, cv2.COLOR_HSV2RGB)

# plot image
plt.figure(num=1, figsize=(8, 8))
show_img(221, 'Origin', color_image)
show_img(222, 'Change H', turn_h_img)
show_img(223, 'Change S', turn_s_img)
show_img(224, 'Change V', turn_v_img)
plt.show()

7a3e07162a6bfa3d62e695de65c17853.png
Change HSV Attribute

Gamma变换

在图像处理中,Gamma变换用于将漂白(相机过曝)的图片或者过暗(曝光不足)的图片进行修正。其数学表达式如下:

equation?tex=S%3DCr%5E%5Cgamma%2C%28r+%5Cin+%5B0%2C+1%5D%29

画个图看一下这个函数:

x = np.arange(0, 1, 0.01)
y_ = x
plt.plot(x, y_, label='Original')
for gamma in [0.1, 0.2, 0.5, 2.5, 5, 10]:
    y = x ** gamma
    plt.plot(x, y, label= 'gamma=%.1f' % gamma)
plt.legend(loc='upper right', bbox_to_anchor=(1.35, 1.02))
# plt.legend(loc='upper right')
plt.xlabel('Input Intensity Level')
plt.ylabel('Output Intensity Level')
plt.show()

4b5032d89314567692ae77064b9c5d87.png
Gamma Function

可以看出,gamma值小于1时,会拉伸图像中灰度级较低的区域,同时会压缩灰度级较高的部分,gamma值大于1时,会拉伸图像中灰度级较高的区域,同时会压缩灰度级较低的部分。

无论是HSV还是RGB,我们都较难一眼就对像素中值的分布有细致的了解,这时候就需要直方图。如果直方图中的成分过于靠近0或者255,可能就出现了暗部细节不足或者亮部细节丢失的情况。这个时候,一个常用方法是考虑用Gamma变换来提升暗部细节。Gamma变换是矫正相机直接成像和人眼感受图像差别的一种常用手段,简单来说就是通过非线性变换让图像从对曝光强度的线性响应变得更接近人眼感受到的响应。
from mpl_toolkits.mplot3d import Axes3D

hist_b = cv2.calcHist([bgr_color_image], [0], None, [256], [0, 256])
hist_g = cv2.calcHist([bgr_color_image], [1], None, [256], [0, 256])
hist_r = cv2.calcHist([bgr_color_image], [2], None, [256], [0, 256])


# 定义Gamma矫正的函数
def gamma_trans(img, gamma):
    # 具体做法是先归一化到1,然后gamma作为指数值求出新的像素值再还原
    gamma_table = [np.power(x/255.0, gamma)*255.0 for x in range(256)]
    gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
    
    # 实现这个映射用的是OpenCV的查表函数
    return cv2.LUT(img, gamma_table)

# 执行Gamma矫正,小于1的值让暗部细节大量提升,同时亮部细节少量提升
img_corrected = gamma_trans(bgr_color_image, 1.5)


# 分通道计算Gamma矫正后的直方图
hist_b_corrected = cv2.calcHist([img_corrected], [0], None, [256], [0, 256])
hist_g_corrected = cv2.calcHist([img_corrected], [1], None, [256], [0, 256])
hist_r_corrected = cv2.calcHist([img_corrected], [2], None, [256], [0, 256])


fig = plt.figure(figsize=(8, 8))

pix_hists = [
    [hist_b, hist_g, hist_r],
    [hist_b_corrected, hist_g_corrected, hist_r_corrected]
]

pix_vals = [[i] for i in range(256)]

for sub_plt, pix_hist in zip([121, 122], pix_hists):
    ax = fig.add_subplot(sub_plt, projection='3d')
    for c, z, channel_hist in zip(['b', 'g', 'r'], [20, 10, 0], pix_hist):
        cs = [c] * 256
        ax.bar(pix_vals, channel_hist, zs=z, zdir='y', color=cs, alpha=0.618, edgecolor='none', lw=0)
    ax.set_xlabel('Pixel Values')
    ax.set_xlim([0, 256])
    ax.set_ylabel('Channels')
    ax.set_zlabel('Counts')

plt.show()

c09ad2cd94c4f4744e8681771ae209fd.png
Channel Histogram
gamma_corrected_image = cv2.cvtColor(img_corrected, cv2.COLOR_BGR2RGB)
plt.figure()
show_img(121, 'Gamma Corrected Image', gamma_corrected_image)
show_img(122, 'Origin Image', rgb_color_image)
plt.show()

3d21918c9d8262bbad9b39f68370bee8.png
Gamma Corrrected Image
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值