【OpenCV】Python图像处理之像素操作

OpenCV-Python 中的像素操作是图像处理的基础,包括像素值的读取、修改、算术运算、逻辑运算等。由于图像在 OpenCV 中以 NumPy 数组表示,像素操作本质上是对数组的操作,结合 NumPy 的高效运算可实现灵活的像素级处理。以下详细介绍常见的像素操作方法及示例:

一、像素值的读取与修改

1. 单个像素操作

通过数组索引访问像素值,注意 OpenCV 图像的索引顺序为[行, 列, 通道](行对应 y 轴,列对应 x 轴)。

python 复制代码
import cv2
import numpy as np

# 读取彩色图像(BGR格式)
img = cv2.imread('image.jpg')

# 读取单个像素值(第100行,第200列)
b, g, r = img[100, 200]  # BGR顺序
print(f"原始像素值(BGR): ({b}, {g}, {r})")

# 修改单个像素值(设为红色)
img[100, 200] = (0, 0, 255)  # BGR: 蓝=0, 绿=0, 红=255
print(f"修改后像素值(BGR): {img[100, 200]}")

# 灰度图像的像素操作
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
pixel = gray_img[100, 200]
print(f"灰度像素值: {pixel}")
gray_img[100, 200] = 255  # 设为白色
2. 区域像素操作

通过切片操作修改图像的特定区域,效率远高于逐个像素修改。

python 复制代码
# 将图像中左上角100x100区域设为绿色
img[0:100, 0:100] = (0, 255, 0)  # BGR: 绿色

# 将灰度图像中某区域设为黑色
gray_img[50:150, 50:150] = 0

# 提取图像的ROI(感兴趣区域)
roi = img[200:400, 300:500]  # 行200-400,列300-500
img[0:200, 0:200] = roi  # 将ROI复制到左上角

二、像素的算术运算

1. 加减运算(亮度调整)

对像素值进行加减可调整图像亮度,需注意像素值溢出(超过 0 或 255),可通过cv2.add()/cv2.subtract()自动截断,或手动处理。

python 复制代码
# 方法1:直接算术运算(可能溢出)
img_bright = img + 50  # 增加亮度(值>255时会溢出,如250+50=44)
img_dark = img - 50    # 降低亮度(值<0时会溢出,如10-50=216)

# 方法2:使用OpenCV函数(自动截断)
img_bright_safe = cv2.add(img, np.ones_like(img) * 50)
img_dark_safe = cv2.subtract(img, np.ones_like(img) * 50)
2. 乘除运算(对比度调整)

乘法增强对比度,除法降低对比度,同样需注意溢出

python 复制代码
# 增强对比度(乘以1.5)
img_contrast = np.clip(img * 1.5, 0, 255).astype(np.uint8)

# 降低对比度(除以2)
img_contrast_low = (img / 2).astype(np.uint8)
3. 图像混合(加权和)

使用cv2.addWeighted()实现两幅图像的线性混合,公式:dst = α·img1 + β·img2 + γ

python 复制代码
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))  # 统一尺寸

# 图像混合(α=0.7, β=0.3, γ=0)
blended = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)

三、像素的逻辑运算

包括与(AND)、或(OR)、非(NOT)、异或(XOR),常用于图像掩码、区域提取等。

python 复制代码
# 创建两幅测试图像
img_a = np.zeros((200, 200), dtype=np.uint8)
img_a[50:150, 50:150] = 255  # 白色正方形

img_b = np.zeros((200, 200), dtype=np.uint8)
img_b[100:200, 100:200] = 255  # 白色正方形

# 逻辑运算
and_img = cv2.bitwise_and(img_a, img_b)
or_img = cv2.bitwise_or(img_a, img_b)
not_img = cv2.bitwise_not(img_a)
xor_img = cv2.bitwise_xor(img_a, img_b)

四、像素值的统计分析

通过 NumPy 函数统计图像的像素特征,如均值、最值、方差等。

python 复制代码
# 彩色图像的通道均值
mean_b = np.mean(img[:, :, 0])  # 蓝色通道均值
mean_g = np.mean(img[:, :, 1])  # 绿色通道均值
mean_r = np.mean(img[:, :, 2])  # 红色通道均值
print(f"通道均值(BGR): ({mean_b:.2f}, {mean_g:.2f}, {mean_r:.2f})")

# 灰度图像的最值与方差
min_val = np.min(gray_img)
max_val = np.max(gray_img)
std_val = np.std(gray_img)
print(f"灰度图像: 最小值={min_val}, 最大值={max_val}, 标准差={std_val:.2f}")

# 像素值直方图
hist = cv2.calcHist([gray_img], [0], None, [256], [0, 256])

五、像素阈值处理

将像素值与阈值比较,实现二值化或分段处理,常用cv2.threshold()

OpenCV中‌cv2.threshold()函数用于图像阈值处理,将灰度图像转换为二值图像或其他形式。以下是核心信息:

函数定义:

cv2.threshold(src, thresh, maxval, type)

  • src:输入灰度图像
  • thresh:设定的阈值(若使用‌Otsu方法,此值设为0)
  • maxval:像素值高于/低于阈值时的设定值(如255)
  • type:‌阈值类型,常用类型包括:
    • cv2.THRESH_BINARY:大于阈值设为maxval,否则0
    • cv2.THRESH_BINARY_INV:反转上述结果
    • cv2.THRESH_TRUNC:大于阈值设为thresh,否则不变
    • cv2.THRESH_TOZERO:大于阈值不变,否则0
    • cv2.THRESH_TOZERO_INV:反转上述结果
  • 返回值:ret(实际使用的阈值,如Otsu方法自动计算)和处理后的图像

示例代码:

python 复制代码
# 简单阈值处理
ret, binary = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)  # >127设为255,否则0
ret, binary_inv = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV)  # 反向

# 自适应阈值(局部阈值)
adaptive_binary = cv2.adaptiveThreshold(
    gray_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2
)

注意事项:

  • 阈值类型需与maxval配合使用,例如THRESH_BINARY要求maxval为255。
  • 若使用cv2.THRESH_OTSU,需将thresh设为0,函数会自动计算最优阈值 。

六、像素的遍历与批量处理

1. 逐像素遍历(效率较低,适合简单操作)
python 复制代码
# 遍历灰度图像并反转像素值
height, width = gray_img.shape
for i in range(height):
    for j in range(width):
        gray_img[i, j] = 255 - gray_img[i, j]  # 反色
2. 批量处理(推荐,利用 NumPy 向量化运算)
python 复制代码
# 批量反色(效率远高于逐像素遍历)
gray_img_inverted = 255 - gray_img

# 批量将像素值限制在[50, 200]
img_clipped = np.clip(img, 50, 200)

七、掩码操作(卷积核滤波)

通过自定义卷积核对像素进行邻域运算,实现模糊、锐化等效果。

python 复制代码
# 均值模糊(3x3卷积核)
kernel = np.ones((3, 3), np.float32) / 9
blurred = cv2.filter2D(img, -1, kernel)

# 图像锐化
kernel_sharpen = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharpened = cv2.filter2D(img, -1, kernel_sharpen)

八、完整示例:像素操作综合应用

python 复制代码
import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 1. 修改区域像素(画红色矩形)
img[50:150, 200:300] = (0, 0, 255)

# 2. 调整亮度和对比度
img_bright = cv2.add(img, np.ones_like(img) * 30)
img_contrast = np.clip(img * 1.2, 0, 255).astype(np.uint8)

# 3. 灰度图像二值化
_, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)

# 4. 显示结果
cv2.imshow('Original', img)
cv2.imshow('Bright', img_bright)
cv2.imshow('Contrast', img_contrast)
cv2.imshow('Binary', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结

像素操作是 OpenCV 图像处理的核心,需结合 NumPy 的数组运算特性:

  • 单个 / 区域像素操作通过索引或切片实现;
  • 算术 / 逻辑运算可调整图像亮度、对比度或实现掩码;
  • 批量处理优先使用 NumPy 向量化运算,避免低效的逐像素遍历;
  • 阈值处理和掩码操作常用于图像分割、特征提取等场景。

通过这些操作,你可以读取、修改和保存图像中的像素数据,实现各种图像处理任务。**记得在进行大量或复杂的像素操作时优先使用NumPy的高效数组操作,以提高代码的执行效率。**掌握像素操作的底层逻辑,能更灵活地实现自定义图像处理算法。

相关推荐
向上的车轮1 小时前
图像处理OpenCV与深度学习框架YOLOv8的主要区别是什么?
图像处理·深度学习·opencv·yolov8
ChrisitineTX1 小时前
警惕数据“陷阱”:Python 如何自动发现并清洗 Excel 中的异常值?
开发语言·python·excel
AndrewHZ1 小时前
【图像处理基石】图像处理中的色彩经典算法原理与实战解析
图像处理·算法·计算机视觉·白平衡·色彩科学·经典算法·k means
꒰ঌ小武໒꒱1 小时前
Trae CN IDE 使用教程
前端·python·编辑器
向上的车轮1 小时前
基于深度学习与OpenCV的物体计数技术全解析
人工智能·深度学习·opencv
xrn19971 小时前
Android OpenCV SDK 编译教程(WSL2 Ubuntu 22.04 环境)
android·c++·opencv
csdn_aspnet1 小时前
用Python抓取ZLibrary元数据
开发语言·python·zlibrary
一个处女座的程序猿1 小时前
AI之Algorithms:TheAlgorithms_Python(所有用 Python 实现的算法)的简介、安装和使用方法、案例应用之详细攻略
人工智能·python·算法
A-程序设计1 小时前
基于Django短视频推荐系统设计与实现-(源码+LW+可部署)
后端·python·django