【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的高效数组操作,以提高代码的执行效率。**掌握像素操作的底层逻辑,能更灵活地实现自定义图像处理算法。

相关推荐
_深海凉_6 分钟前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦29 分钟前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu37 分钟前
Python 语法之数据结构详细解析
python
AI问答工程师1 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
MWWZ1 小时前
最近的一些软件更新
opencv·算法·计算机视觉
zfan5202 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕2 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙2 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
格鸰爱童话3 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
悟空爬虫-彪哥3 小时前
VRChat开发环境配置,零基础教程
python