OpenCV 图像处理基础操作指南(二)

发布于:2025-08-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

一、边界填充 (cv2.copyMakeBorder)

1.1 函数语法

1.2 参数说明

1.3 边界类型详解

1.4 示例代码

二、图像加法运算

2.1 运算符+的特性

2.2 cv2.add()函数的特性

2.3 示例代码

三、图像加权运算

3.1 加权运算公式

3.2 函数语法

3.3 示例代码

四、阈值处理

4.1 函数语法

4.2 参数说明

4.3 阈值类型详解

4.4 示例代码

五、图像平滑处理(模糊处理)

5.1 常用滤波方法

5.2 示例代码


一、边界填充 (cv2.copyMakeBorder)

边界填充是图像处理中常用的技术,用于在图像周围添加额外的边界像素。OpenCV 提供了cv2.copyMakeBorder()函数实现这一功能。

1.1 函数语法

cv2.copyMakeBorder(src: UMat, top: int, bottom: int, left: int, right: int, borderType: int, dst: UMat | None = ..., value: cv2.typing.Scalar = ...)

1.2 参数说明

  • src: 要扩充边界的原始图像
  • top, bottom, left, right: 相应方向上的边框宽度
  • borderType: 边界类型
  • value: 当 borderType 为 cv2.BORDER_CONSTANT 时使用的常数值

1.3 边界类型详解

  • cv2.BORDER_CONSTANT: 添加固定颜色的边框
  • cv2.BORDER_REFLECT: 镜面反射,如 gfedcba|abcdefgh|hgfedcba
  • cv2.BORDER_REFLECT_101/cv2.BORDER_DEFAULT: 改进的反射,如 gfedcb|abcdefgh|gfedcba
  • cv2.BORDER_REPLICATE: 复制边界像素,如 aaaaaa|abcdefgh|hhhhhhh
  • cv2.BORDER_WRAP: 环绕复制,如 cdefgh|abcdefgh|abcdefg

1.4 示例代码

import cv2
import numpy as np

# 读取图像
a = cv2.imread('img_1.jpg')
if a is None:
    print("无法读取图像,请检查文件路径")
    exit()

# 设置边界宽度
top, bottom, left, right = 50, 50, 50, 50

# 创建不同类型的边界
constant = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[255, 0, 0])  # 蓝色边框
reflect = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_REFLECT101)
replicate = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_REPLICATE)
wrap = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_WRAP)

# 显示结果
cv2.imshow('原始图像', a)
cv2.imshow('CONSTANT边界', constant)
cv2.imshow('REFLECT边界', reflect)
cv2.imshow('REFLECT101边界', reflect101)
cv2.imshow('REPLICATE边界', replicate)
cv2.imshow('WRAP边界', wrap)

# 等待按键,关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

二、图像加法运算

图像加法是基本的图像处理操作,可以用于图像融合、亮度调整等场景。OpenCV 提供了两种主要的加法方式:运算符+cv2.add()函数。

2.1 运算符+的特性

  • 当像素值之和小于 255 时,直接取和
  • 当像素值之和大于 255 时,结果为 (sum - 256),即模 256 运算
  • 适用于简单的像素值调整

2.2 cv2.add()函数的特性

  • 当像素值之和小于 255 时,直接取和
  • 当像素值之和大于 255 时,结果为 255(截断处理)
  • 更适合图像融合场景

2.3 示例代码

import cv2
import numpy as np

# 读取图像
a = cv2.imread('img_1.jpg')
b = cv2.imread('img_2.jpg')

if a is None or b is None:
    print("无法读取图像,请检查文件路径")
    exit()

# 简单的像素值调整
c1 = a + 10  # 所有像素值增加10
cv2.imshow('原始图像', a)
cv2.imshow('a+10', c1)
cv2.waitKey(0)

# 图像区域加法
# 确保两个图像大小相同
height, width = min(a.shape[0], b.shape[0]), min(a.shape[1], b.shape[1])
a_resized = cv2.resize(a, (width, height))
b_resized = cv2.resize(b, (width, height))

# 加法运算
c2 = a_resized + b_resized
cv2.imshow('a + b', c2)
cv2.waitKey(0)

# 使用cv2.add()函数
c3 = cv2.add(a_resized, b_resized)
cv2.imshow('cv2.add(a, b)', c3)
cv2.waitKey(0)

cv2.destroyAllWindows()

三、图像加权运算

加权运算是一种更灵活的图像融合方法,可以通过调整权重来控制不同图像在融合结果中的贡献度。

3.1 加权运算公式

dst = src1 × α + src2 × β + γ

其中:

  • α 和 β 是 src1 和 src2 的权重
  • γ 是亮度调整值

3.2 函数语法

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])

3.3 示例代码

import cv2
import numpy as np

# 读取图像
a = cv2.imread('img_1.jpg')
b = cv2.imread('img_2.jpg')

if a is None or b is None:
    print("无法读取图像,请检查文件路径")
    exit()

# 调整图像大小,确保它们具有相同的尺寸
height, width = 400, 400
a_resized = cv2.resize(a, (width, height))
b_resized = cv2.resize(b, (width, height))

# 加权融合
# 公式: dst = a*0.2 + b*0.8 + 10
blended = cv2.addWeighted(a_resized, 0.2, b_resized, 0.8, gamma=10)

# 显示结果
cv2.imshow('图像1', a_resized)
cv2.imshow('图像2', b_resized)
cv2.imshow('加权融合结果', blended)

# 尝试不同的权重组合
blended2 = cv2.addWeighted(a_resized, 0.5, b_resized, 0.5, gamma=0)  # 均等权重
blended3 = cv2.addWeighted(a_resized, 0.8, b_resized, 0.2, gamma=-20)  # 暗化效果

cv2.imshow('均等权重融合', blended2)
cv2.imshow('暗化融合', blended3)

cv2.waitKey(0)
cv2.destroyAllWindows()

四、阈值处理

阈值处理是将图像转换为二值图像的常用方法,通过设定一个阈值将像素分为两类:高于阈值和低于阈值。

4.1 函数语法

retval, dst = cv2.threshold(src, thresh, maxval, type)

4.2 参数说明

  • retval: 返回的阈值
  • dst: 阈值分割结果图像
  • src: 输入图像(通常为灰度图)
  • thresh: 设定的阈值
  • maxval: 最大值(用于 THRESH_BINARY 和 THRESH_BINARY_INV 类型)
  • type: 阈值类型

4.3 阈值类型详解

类型 像素值 > thresh 其他情况
cv2.THRESH_BINARY maxval 0
cv2.THRESH_BINARY_INV 0 maxval
cv2.THRESH_TRUNC thresh 当前灰度值
cv2.THRESH_TOZERO 当前灰度值 0
cv2.THRESH_TOZERO_INV 0 当前灰度值

4.4 示例代码

import cv2
import numpy as np

# 读取灰度图像
image = cv2.imread('img_1.jpg', 0)  # 0表示以灰度模式读取
if image is None:
    print("无法读取图像,请检查文件路径")
    exit()

# 设定阈值
threshold_value = 150
max_value = 255

# 应用不同的阈值类型
ret, binary = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY)
ret1, binaryinv = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY_INV)
ret2, trunc = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TRUNC)
ret3, tozero = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TOZERO)
ret4, tozeroinv = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TOZERO_INV)

# 显示结果
cv2.imshow('原灰度图', image)
cv2.imshow('THRESH_BINARY', binary)
cv2.imshow('THRESH_BINARY_INV', binaryinv)
cv2.imshow('THRESH_TRUNC', trunc)
cv2.imshow('THRESH_TOZERO', tozero)
cv2.imshow('THRESH_TOZERO_INV', tozeroinv)

# 等待按键,关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

五、图像平滑处理(模糊处理)

图像平滑处理用于消除图像中的噪声或细节,使图像看起来更为模糊。OpenCV 提供了多种平滑滤波方法。

5.1 常用滤波方法

  1. 均值滤波(cv2.blur): 使用邻域像素的平均值
  2. 方框滤波(cv2.boxFilter): 类似于均值滤波,但可以选择是否归一化
  3. 高斯滤波(cv2.GaussianBlur): 使用高斯核进行滤波,更适合处理高斯噪声
  4. 中值滤波(cv2.medianBlur): 使用邻域像素的中值,对椒盐噪声有很好的抑制效果

5.2 示例代码

import cv2
import numpy as np

def add_peppersalt_noise(image, n=10000):
    """添加椒盐噪声"""
    result = image.copy()
    h, w = image.shape[:2]  # 获取图片的高和宽
    
    # 生成n个椒盐噪声
    for i in range(n):
        x = np.random.randint(low=0, high=h)
        y = np.random.randint(low=0, high=w)
        
        # 随机生成黑色或白色噪声
        if np.random.randint(low=0, high=2) == 0:
            result[x, y] = 0  # 黑色噪声
        else:
            result[x, y] = 255  # 白色噪声
    
    return result

# 读取图像
image = cv2.imread('img_1.jpg')
if image is None:
    print("无法读取图像,请检查文件路径")
    exit()

# 显示原始图像
cv2.imshow('原始图像', image)
cv2.waitKey(0)

# 添加椒盐噪声
noise_image = add_peppersalt_noise(image)
cv2.imshow('添加椒盐噪声后的图像', noise_image)
cv2.waitKey(0)

# 1. 均值滤波
blur_3x3 = cv2.blur(noise_image, ksize=(3, 3))  # 3x3卷积核
blur_7x7 = cv2.blur(noise_image, ksize=(7, 7))  # 7x7卷积核
cv2.imshow('均值滤波 (3x3)', blur_3x3)
cv2.imshow('均值滤波 (7x7)', blur_7x7)
cv2.waitKey(0)

# 2. 方框滤波
box_norm = cv2.boxFilter(noise_image, -1, ksize=(3, 3), normalize=True)  # 归一化
box_no_norm = cv2.boxFilter(noise_image, -1, ksize=(3, 3), normalize=False)  # 不归一化
cv2.imshow('方框滤波 (归一化)', box_norm)
cv2.imshow('方框滤波 (不归一化)', box_no_norm)
cv2.waitKey(0)

# 3. 高斯滤波
gaussian_3x3 = cv2.GaussianBlur(noise_image, ksize=(3, 3), sigmaX=1)  # 3x3高斯核
gaussian_7x7 = cv2.GaussianBlur(noise_image, ksize=(7, 7), sigmaX=2)  # 7x7高斯核
cv2.imshow('高斯滤波 (3x3)', gaussian_3x3)
cv2.imshow('高斯滤波 (7x7)', gaussian_7x7)
cv2.waitKey(0)

# 4. 中值滤波
median_3x3 = cv2.medianBlur(noise_image, ksize=3)  # 3x3中值滤波
median_7x7 = cv2.medianBlur(noise_image, ksize=7)  # 7x7中值滤波
cv2.imshow('中值滤波 (3x3)', median_3x3)
cv2.imshow('中值滤波 (7x7)', median_7x7)
cv2.waitKey(0)

cv2.destroyAllWindows()

网站公告

今日签到

点亮在社区的每一天
去签到