首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于Numpy图像处理基础技巧

基于Numpy图像处理基础技巧

原创
作者头像
皮大大
发布2025-05-07 15:43:12
发布2025-05-07 15:43:12
29300
代码可运行
举报
文章被收录于专栏:图像处理图像处理
运行总次数:0
代码可运行

公众号:尤而小屋 编辑:Peter 作者:Peter

大家好,我是Peter~

图像基础处理是计算机视觉数字图像处理的第一步,旨在通过简单而有效的操作改善图像质量或提取关键信息。

常见的处理技术包括:

  • 灰度化(将彩色图像转换为单通道灰度图)
  • 二值化(通过阈值分割突出目标区域)
  • 平滑滤波(如高斯模糊去除噪声)
  • 边缘检测(如Sobel、Canny算子提取轮廓)
  • 几何变换(如旋转、缩放、裁剪)。

这些方法通常基于像素级操作或卷积运算,能够快速优化图像数据,为后续高级分析(如目标识别、特征匹配)奠定基础。

例如,直方图均衡化可增强低对比度图像的细节,而形态学操作(如腐蚀、膨胀)能优化二值图像中的连通区域。基础处理技术因其高效性和广泛适用性,在工业检测、医学影像、安防监控等领域发挥着重要作用。

本文给大家介绍10个图像处理的基本操作,所有的操作都是基于Numpy实现,用个人本地图片代码复制即可运行

代码语言:python
代码运行次数:0
运行
复制
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

from PIL import Image

图像基础操作

读取图像

首先读取我们需要处理的图像:

代码语言:python
代码运行次数:0
运行
复制
img = Image.open("Mona_Lisa.jpg")
type(img)

PIL.JpegImagePlugin.JpegImageFile
代码语言:python
代码运行次数:0
运行
复制
# 创建矩阵
M = np.array(img)
type(M)  # numpy数组

结果显示是:

numpy.ndarray

代码语言:python
代码运行次数:0
运行
复制
M[:2]
代码语言:python
代码运行次数:0
运行
复制
array([[[ 99, 110,  93],
        [ 85,  98,  80],
        [ 80,  95,  76],
        ...,
        [ 76,  90,  65],
        [ 73,  82,  63],
        [ 92,  96,  82]],

       [[101, 113,  93],
        [ 93, 106,  86],
        [ 78,  93,  72],
        ...,
        [ 60,  74,  49],
        [ 64,  73,  54],
        [ 58,  62,  48]]], dtype=uint8)

图像基本信息

代码语言:python
代码运行次数:0
运行
复制
M.shape  

(447, 300, 3)

可以看到该创建的是一个三维矩阵,表示图像的高度、宽度和颜色通道数

  • height:图像的高度(垂直方向的像素行数)。
  • width:图像的宽度(水平方向的像素列数)。
  • channels:颜色通道数(如RGB图像为3,灰度图像为1)。
代码语言:python
代码运行次数:0
运行
复制
M.size  # 图像大小  447*300*3

402300

显示图像

方式1:通过show函数显示

代码语言:python
代码运行次数:0
运行
复制
# img.show() # 方式1:新建窗口打开图片

方式2:通过display函数显示该图像:Image.fromarray()是图像处理库Pillow (PIL) 中的一个核心方法,其作用是将 NumPy 数组转换为 PILImage 对象

代码语言:python
代码运行次数:0
运行
复制
display(Image.fromarray(M))  # 将numpy数组转成Image对象

或者直接使用img,因为通过读取进行本身就是Image对象中的JpegImageFile类型。

代码语言:python
代码运行次数:0
运行
复制
type(img)

PIL.JpegImagePlugin.JpegImageFile

代码语言:python
代码运行次数:0
运行
复制
display(img)

缩小图像

代码语言:python
代码运行次数:0
运行
复制
def reduce_img_size(img, n):
    h,w,c = img.shape  # h---height   w---width   c---channel
    
    # 将图像缩小n倍;得到缩小后的高度和宽度
    new_h = h // n  
    new_w = w // n
    
    # 创建一个新矩阵来存储缩小后的图像
    new_img = np.zeros((new_h,new_w,c), dtype=img.dtype) # 保持和原图像相同的dtype
    
    for i in range(new_h):
        for j in range(new_w): # 遍历每个像素位置(i,j)
            new_img[i,j] = img[n*i, n*j]  # 新图像的每个像素 (i, j),从原图像中取位置为 (n*i, n*j) 的像素值赋值给它
    return new_img
代码语言:python
代码运行次数:0
运行
复制
reduced_M = reduce_img_size(M,2)  # 缩小为原来一半
display(Image.fromarray(reduced_M))

图像亮度调整Image Brightness Adjustment

基本原理

基本原理:图像亮度调整的原理是通过数学运算改变图像像素的强度值(即亮度),从而整体提亮或压暗图像。

其核心是对每个像素的RGB(或灰度)通道值进行线性或非线性变换,同时确保结果在有效范围内(如0~255)。

案例

np.clip()NumPy 中的一个重要函数,用于限制数组值的范围,将超出指定范围的值截断到边界值。它在图像处理中常用于防止像素值溢出或归一化数据。

具体用法为:

代码语言:python
代码运行次数:0
运行
复制
np.clip(array, min, max, out=None)
  • array: 输入数组(可以是 NumPy 数组或类似数组的对象)。
  • min: 最小值,所有比 min 小的值会被替换为 min(可选,默认为 None)。
  • max: 最大值,所有比 max 大的值会被替换为 max(可选,默认为 None)。
  • out: 可选参数,指定输出数组(避免创建新数组)。
代码语言:python
代码运行次数:0
运行
复制
# 增加亮度

# 原数组M 乘以1.5,即扩大50%,然后将值限制在0~255;并转成标准np.uint格式
brightened_M = np.clip(M * 1.5, 0, 255).astype(np.uint8)  
代码语言:python
代码运行次数:0
运行
复制
display(Image.fromarray(brightened_M))
代码语言:python
代码运行次数:0
运行
复制
# 降低亮度

darkened_M = np.clip(M * 0.5, 0, 255).astype(np.uint8)  # 亮度降低50%

display(Image.fromarray(darkened_M))

图像翻转Image Flipping

  • Horizontal水平翻转即沿 垂直轴(Y轴) 翻转图像,相当于对图像的 列(width) 进行逆序排列。
  • Vertical垂直翻转即沿 水平轴(X轴) 翻转图像,相当于对图像的 行(height) 进行逆序排列

NumPy 的切片操作是 零拷贝(view),速度极快,适合大规模图像处理

代码语言:python
代码运行次数:0
运行
复制
# 方式1

# 水平翻转(左右镜像)
flipped_horizontal = M[:, ::-1, :]

# 垂直翻转(上下镜像)
flipped_vertical = M[::-1, :, :]

# 显示结果
plt.figure(figsize=(12, 4))
plt.subplot(131), plt.imshow(img), plt.title("Original"), plt.axis('off')
plt.subplot(132), plt.imshow(flipped_horizontal), plt.title("Horizontal Flip"), plt.axis('off')
plt.subplot(133), plt.imshow(flipped_vertical), plt.title("Vertical Flip"), plt.axis('off')
plt.show()
代码语言:python
代码运行次数:0
运行
复制
# 方式2
def flip_image(image):
    # 水平翻转函数
    flip_image = image[:, ::-1]
    return flip_image
 
    
def rotate_image(image):
    # 垂直翻转函数
    rotated_img = Image.fromarray(np.rot90(image, k=n, axes=(1, 0))) 
    return rotated_img

其中np.rot90为内置的矩阵旋转函数,其中:

  • k=n:表示旋转次数(90°*n)
  • axes=(1, 0):指定旋转的轴平面((1, 0) 表示沿高度(行)和宽度(列)组成的平面旋转,即顺时针旋转)。

图像裁剪Image Cropping

代码语言:python
代码运行次数:0
运行
复制
# 定义裁剪函数
def crop_image(image, crop_ratio, zoom_ratio):
    """
    image:待裁剪的函数,(h,w,c)三个参数
    crop_ratio:裁剪比例,控制裁剪范围的中心位置
    zoom_ratio:缩放比例,控制裁剪后区域的放大倍数
    """
    
    # 获取图像的高度shape[0]、宽度shape[1]和通道数shape[2]
    
    # top:从图像顶部向下裁剪 1/crop_ratio 的部分(例如 crop_ratio=4 表示从 25% 高度处开始裁剪)
    # bottom:在 top 的基础上,放大 zoom_ratio 倍(例如 zoom_ratio=2 表示裁剪区域高度为原图的 2/crop_ratio)
    top = image.shape[0] // crop_ratio
    bottom = zoom_ratio * image.shape[0] // crop_ratio
    left = image.shape[1] // crop_ratio
    right = zoom_ratio * image.shape[1] // crop_ratio
    
    focused_img = image[top:bottom, left:right]
    return focused_img

display(Image.fromarray(crop_image(M, 3, 5)))

RGB通道

RGB简介

RGB(Red, Green, Blue)是一种颜色模型,通过 红(R)、绿(G)、蓝(B) 三个颜色通道的组合来表示所有颜色。它是数字图像处理中最常用的色彩模式,适用于显示器、摄像头、照片等。

RGB通道的作用:

  • 红色(R):控制图像中的红色分量。
  • 绿色(G):控制图像中的绿色分量。
  • 蓝色(B):控制图像中的蓝色分量。

通过调整这三个通道的强度(0-255),可以混合出 1677万种(256×256×256) 颜色。

RGB通道的顺序

RGB 通道的顺序取决于使用的库或工具:

库/工具

通道顺序

示例(image.shape = (H, W, 3)

PIL/Pillow、Matplotlib

RGB

image[:, :, 0] = 红(R) image[:, :, 1] = 绿(G) image[:, :, 2] = 蓝(B)

OpenCV

BGR

image[:, :, 0] = 蓝(B) image[:, :, 1] = 绿(G) image[:, :, 2] = 红(R)

提取指定通道

代码语言:python
代码运行次数:0
运行
复制
# 提取 R、G、B 通道(注意通道顺序是 R=0, G=1, B=2)

# 指定提取单个通道的数据
red_channel = M[:, :, 0]    # 红色通道(二维数组)
green_channel = M[:, :, 1]  # 绿色通道
blue_channel = M[:, :, 2]   # 蓝色通道

# 显示单通道(灰度图)
plt.figure(figsize=(12, 4))
plt.subplot(131), plt.imshow(red_channel, cmap='Reds'), plt.title("Red Channel")
plt.subplot(132), plt.imshow(green_channel, cmap='Greens'), plt.title("Green Channel")
plt.subplot(133), plt.imshow(blue_channel, cmap='Blues'), plt.title("Blue Channel")
plt.show()

另外一种方式:定义提取单个通道的函数

代码语言:python
代码运行次数:0
运行
复制
def RGB_image(image,image_color):
    """
    定义RGB函数:提取图像的红-绿-蓝色的单色通道,并将其他两个通道置为零
    通道顺序:R=0, G=1, B=2
    """
    
    if image_color == 'R':
        img_R = image.copy()
        img_R[:, :, (1, 2)] = 0  # 保留 R,G 和 B 置零
        return img_R

    elif image_color == 'G':
        img_G = image.copy()
        img_G[:, :, (0, 2)] = 0  # 保留 G,R 和 B 置零
        return img_G

    elif image_color == 'B':
        img_B = image.copy()
        img_B[:, :, (0, 1)] = 0   # 保留 B,R 和 G 置零
        return img_B
代码语言:python
代码运行次数:0
运行
复制
M_red = Image.fromarray(RGB_image(M, 'R'))
 
display(M_red)

图片灰度化Image Grayscaling

图片灰度化是将彩色图像转换为灰度图像的过程,也就是将包含丰富颜色信息的图像转换为仅包含亮度信息的黑白图像(实际上是不同深浅的灰色)。

基本原理:灰度化通过数学转换将彩色图像(通常由红、绿、蓝三个通道组成)转换为单通道的灰度图像,其中每个像素的值代表该点的亮度。

常用的灰度化方法

  • 平均值灰度法:(R+G+B)/3
  • 加权平均灰度法:0.5*R+0.3*G+0.2*B;OpenCV等库采用
  • 最大值/最小值灰度法:max(R,G,B),min(R,G,B)
代码语言:python
代码运行次数:0
运行
复制
def grayscale_image(image):
    """
    定义加权平均灰度函数
    输入:图像数组np.array
    """
    grayscale_image = np.dot(image[...,:3], [0.5,0.3,0.2])  # 选取RGB通道,忽略可能的alpha通道;自定义加权系数
    grayscale_image = np.clip(grayscale_image,0,255)  # 将像素值限制在0-255内,防止计算溢出
    grayscale_image = grayscale_image.astype(np.uint8) # # 转换数据类型为np.uint8;标准图像格式
    
    return grayscale_image

# 执行灰度转换功能
M_gray = grayscale_image(M)
display(Image.fromarray(M_gray))

图片添加滤镜Image Filter

图像滤镜(Image Filter)的本质:

  • 给图像添加滤镜,本质上是通过数学运算改变像素的颜色值,从而让图像呈现出特定的视觉效果。
  • 滤镜可以模拟自然现象(如老照片)、艺术风格(如油画),或其他的创意表达。
代码语言:python
代码运行次数:0
运行
复制
def apply_sepia(image):
    """
    
    """
    sepia_matrix = np.array([[0.493, 0.769, 0.189],  # 红色通道转换系数
                          [0.349, 0.686, 0.168],  # 绿色
                          [0.282, 0.434, 0.431]]) # 蓝色

    sepia_img = image.dot(sepia_matrix.T)  # .dot  执行矩阵乘法
    sepia_img = np.clip(sepia_img, 0, 255)

    return sepia_img.astype(np.uint8) 

M_sepia = Image.fromarray(apply_sepia(M))

display(M_sepia)

图片像素化Image Pixelation

图像像素化是一种通过减少图像分辨率或合并相邻像素来创建块状、马赛克效果的图像处理技术。它通过将图像分割为若干个小方块(像素块),并用每个方块内像素的平均颜色值替换该区域的所有像素来实现。

简单来说,就是把矢量图形转换成像素点组成的点阵图形,也叫栅格化

基本原理

  • 分块处理:将图像划分为N×N的方块网格
  • 颜色平均:计算每个方块内所有像素的颜色平均值
  • 替换像素:用该平均值替换方块内所有像素
  • 效果控制:通过调整方块大小控制像素化程度

案例

代码语言:python
代码运行次数:0
运行
复制
def pixelate_image(image,block_size):
    """
    image:待处理图片
    block_size:每个像素化方块的大小,比如block_size=10表示10*10的像素
    """
    
    # 计算每个维度的所需分块数
    num_blocks_x = image.shape[1] // block_size  # //表示整除计算
    num_blocks_y = image.shape[0] // block_size
    
    # 计算每个方块的平均颜色值
    block_means = np.zeros((num_blocks_y,num_blocks_x,3), dtype=np.uint8)  # 零矩阵用于存储数据
    for y in range(num_blocks_y):
        for x in range(num_blocks_x):
            # 提取当前方块
            block = image[y * block_size:(y+1) * block_size, x * block_size:(x+1) * block_size]
            # 计算方块内RGB三通道均值
            block_mean = np.mean(block, axis=(0,1))
            # 将均值从浮点数转为 uint8(0~255的整数)
            block_means[y,x] = block_mean.astype(np.uint8) 
            
    # 扩展均值块生成像素化图像:垂直和水平方向使用两次       
    pixelated_image = np.repeat(np.repeat(block_means, block_size, axis=0), block_size, axis=1)
    return pixelated_image  # 生成的是图像数组

M_pixelated = Image.fromarray(pixelate_image(M,block_size=10))
display(M_pixelated)

图像二值化Image Binarization

图像二值化(Image Binarization)是将灰度图像转换为仅包含黑白两色的图像处理技术,通过设定一个阈值将像素分为前景(通常为白色)和背景(通常为黑色)。

二值化基本原理:

  • 选择一个灰度值作为分界点(0-255之间)
  • 大于阈值的像素设为白色(255),小于等于阈值的像素设为黑色(0)
代码语言:python
代码运行次数:0
运行
复制
def binarize_image(image,threshold):
    binarize_image = (image > threshold) * 255
    binarize_image = binarize_image.astype(np.uint8)  # 转成标准格式
    return binarize_image  # 数组格式

M_binarized = Image.fromarray(binarize_image(M,threshold=100))  # 数组---转成
display((M_binarized))

图像融合Image Blending

图像融合是指根据两种图片的透明度将二者的像素进行叠加求和的过程。

代码语言:python
代码运行次数:0
运行
复制
# 读取第二张图
img2 = Image.open("cat.jpg")
# 尺寸转换,和第一张图M的相同
img2 = img2.resize(M.shape[1::-1])
# 创建矩阵
M2 = np.array(img2)
display(Image.fromarray(M2))
代码语言:python
代码运行次数:0
运行
复制
def blend_image(image1,image2,visibility1,visibility2):
    blend_image = image1 * visibility1 + image2 * visibility2 # 根据两个权重进行叠加
    blend_image = blend_image.astype(np.uint8)  # 标准格式
    return blend_image
代码语言:python
代码运行次数:0
运行
复制
blended_image = Image.fromarray(blend_image(M,M2,0.6,0.4))
display(blended_image)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图像基础操作
    • 读取图像
    • 图像基本信息
    • 显示图像
  • 缩小图像
  • 图像亮度调整Image Brightness Adjustment
    • 基本原理
    • 案例
  • 图像翻转Image Flipping
  • 图像裁剪Image Cropping
  • RGB通道
    • RGB简介
    • RGB通道的顺序
    • 提取指定通道
  • 图片灰度化Image Grayscaling
  • 图片添加滤镜Image Filter
  • 图片像素化Image Pixelation
    • 基本原理
    • 案例
  • 图像二值化Image Binarization
  • 图像融合Image Blending
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档