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

相关推荐
锐学AI2 分钟前
从零开始学LangChain(二):LangChain的核心组件 - Agents
人工智能·python
风送雨10 分钟前
多模态RAG工程开发教程(上)
python·langchain
棒棒的皮皮13 分钟前
【OpenCV】Python图像处理形态学之膨胀
图像处理·python·opencv·计算机视觉
小草cys16 分钟前
HarmonyOS Next调用高德api获取实时天气,api接口
开发语言·python·arkts·鸿蒙·harmony os
爬山算法16 分钟前
Netty(25)Netty的序列化和反序列化机制是什么?
开发语言·python
未知数Tel19 分钟前
Dify离线安装插件
python·阿里云·pip·dify
龘龍龙21 分钟前
Python基础学习(六)
开发语言·python·学习
热爱专研AI的学妹39 分钟前
【搭建工作流教程】使用数眼智能 API 搭建 AI 智能体工作流教程(含可视化流程图)
大数据·数据库·人工智能·python·ai·语言模型·流程图
databook1 小时前
拒绝“凭感觉”:用回归分析看透数据背后的秘密
python·数据挖掘·数据分析
Psycho_MrZhang1 小时前
Flask 设计思想总结
后端·python·flask