Python----OpenCV(图像处理——边界填充、图像融合、图像阈值、深拷贝与浅拷贝)

发布于:2025-06-12 ⋅ 阅读:(30) ⋅ 点赞:(0)

Python----计算机视觉处理(Opencv:图像旋转:插值方法,边缘填充方法)

Python----计算机视觉处理(Opencv:二值化,阈值法,反阈值法,截断阈值法,OTSU阈值法)

一、边界填充

1.1、什么是边界填充

        边界填充是一种在图像边缘添加额外像素的操作。这些额外的像素用于处理图像卷积、平滑 或其他涉及边界的操作,以避免边缘效应。例如,在进行卷积操作时,如果不进行边界填 充,图像边缘的像素将会缺少周围的像素信息,从而导致结果图像边缘模糊或失真。

1.2、边界填充方法

原图

BORDER_CONSTANT 常数填充

        使用常数填充,通常是黑色(值为0)。

BORDER_REPLICATE 复制边界像素

        这种方式会将图像的边界像素复制到图像的边界外部,产生类似边缘延伸的效果。

BORDER_REFLECT 反射边界像素

        这种方式将图像的边界像素反射到外部,反射时不包括原边界像素。也就是说,边界的像素 会反转(镜像反射)到外部,但原本的边界像素不再重复。

BORDER_REFLECT_101反射边界像素

        这种方式类似于 BORDER_REFLECT ,但是它反射的范围会排除原图像的第一个和最后一个像素。

BORDER_WRAP

        环绕填充方式会将图像的边界像素“环绕”到另一侧。即,图像的左边会被右边的像素填充, 图像的上边会被下边的像素填充,像是在图像的四个边缘之间“连接”起来。

import cv2

# 读取图像
# cv2.imread() 函数用于从指定路径加载一张图片到内存中。
# './images/nezha.png' 是图片的文件路径。
img1 = cv2.imread('./images/nezha.png')

# 定义边界的厚度
# t, b, l, r 分别代表图像的 上 (top)、下 (bottom)、左 (left)、右 (right) 四个方向要添加的边界像素数量。
# 这里四个方向都设置为 50 像素。
t, b, l, r = (50, 50, 50, 50)

# 使用 cv2.copyMakeBorder 函数添加边界
# img1: 原始图像。
# t, b, l, r: 定义的边界厚度。
# cv2.BORDER_WRAP: 边界填充模式。
# BORDER_WRAP 模式通过重复图像本身来填充边界。它会将图像的另一侧像素“包裹”到边界上,
# 就像图像内容是周期性重复的一样。
img2 = cv2.copyMakeBorder(img1, t, b, l, r, cv2.BORDER_WRAP)

# 显示添加边界后的图像
# cv2.imshow() 函数用于在窗口中显示图像。
# 'images2' 是显示窗口的名称。
cv2.imshow('images2', img2)

# 等待按键
# cv2.waitKey(0) 表示程序将无限期等待用户的按键输入。
# 只有当用户按下任意键时,程序才会继续执行后续代码(例如关闭窗口)。
cv2.waitKey(0)

# 销毁所有OpenCV创建的窗口
# cv2.destroyAllWindows() 函数用于关闭所有由OpenCV创建的窗口。
cv2.destroyAllWindows()

1.3、copyMakeBorder函数

        cv2.copymakeBorder0 是 OpenCV 中用来给图像添加边界的函数,常用于对图像进行扩展处理支持不同的边界填充方式。你可以用它来在图像周围添加空白(常用于卷积操作时)或特定的像素填充。

cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value=None)
参数名 说明
src 输入图像,可以是灰度图像或彩色图像(numpy 数组格式)。
top 上边界的宽度(像素数)。
bottom 下边界的宽度(像素数)。
left 左边的宽度(像素数)。
right 右边的宽度(像素数)。
borderType 填充类型,决定了边界如何填充。常用选项包括:
cv2.BORDER_CONSTANT:常数填充。
cv2.BORDER_REPLICATE:复制边界像素填充。
cv2.BORDER_REFLECT:反射边界像素(反射模式,不包括原边界像素)。
cv2.BORDER_REFLECT_101:类似 BORDER_REFLECT,但对称反射会忽略第一个和最后一个像素。
cv2.BORDER_WRAP:环绕填充。
value 当 borderType=cv2.BORDER_CONSTANT 时,指定填充的颜色。默认为 0(黑色)。如果是彩色图像,可以设置为三元组(如 [0, 0, 255] 表示红色填充)。

二、图像融合

        图像融合是将多张图像合成一张图像的过程,以便获取更丰富的信息或更高的图像质量。在 不同的应用中,图像融合的目的可能不同,如增强图像细节、减小噪声、提高图像分辨率 等。

常见的图像融合方法:

        像素级融合:直接对两个或多个图像的像素值进行加权平均。

        多分辨率融合:例如,使用小波变换(Wavelet Transform)将图像在不同分辨率下进行融合,能保留更多的图像细节。

        特征级融合:提取图像的特征(如边缘、纹理等)后进行融合,而非直接处理像素。

import cv2

# 读取第一张图像
# cv2.imread() 函数用于从指定路径加载一张图片到内存中。
# 'apple.png' 是第一张图片的路径。
img1 = cv2.imread('./images/apple.png')

# 读取第二张图像
# 'parrot.png' 是第二张图片的路径。
img2 = cv2.imread('./images/parrot.png')

# 打印第一张图像的尺寸(高度、宽度、通道数)
# img.shape 返回一个元组,例如 (height, width, channels)。
print(img1.shape)

# 打印第二张图像的尺寸
print(img2.shape)

# 调整第一张图像的大小
# cv2.resize() 函数用于改变图像的尺寸。
# (261, 272) 是目标宽度和高度的元组 (width, height)。
# 图像融合要求参与融合的图像尺寸必须相同,因此这里将两张图都调整为相同大小。
img1 = cv2.resize(img1, (261, 272))

# 调整第二张图像的大小
img2 = cv2.resize(img2, (261, 272))

# 执行图像加权融合
# cv2.addWeighted() 函数用于实现两张图像的线性混合(也称为图像融合或透明度混合)。
# 公式为:dst = α * src1 + β * src2 + γ
# img1: 第一张输入图像。
# 0.5: 第一张图像的权重(α)。
# img2: 第二张输入图像。
# 0.5: 第二张图像的权重(β)。
# 0: 伽马值(γ),一个加到结果上的标量。这里设置为0,表示不额外增加亮度。
# 由于两张图像的权重都是0.5,这意味着它们将以50%的透明度相互叠加,形成一个半透明的效果。
img3 = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)

# 显示第一张原始图像(调整大小后)
# 'images1' 是窗口的名称。
cv2.imshow('images1', img1)

# 显示第二张原始图像(调整大小后)
# 'images2' 是窗口的名称。
cv2.imshow('images2', img2)

# 显示融合后的图像
# 'images3' 是窗口的名称。
cv2.imshow('images3', img3)

# 等待按键
# cv2.waitKey(0) 表示程序将无限期等待用户的按键输入。
# 只有当用户按下任意键时,程序才会继续执行后续代码(例如关闭窗口)。
cv2.waitKey(0)

# 销毁所有OpenCV创建的窗口
# cv2.destroyAllWindows() 函数用于关闭所有由OpenCV创建的窗口。
cv2.destroyAllWindows()

addWeighted函数

        addweighted 是 OpenCV 中用于图像加权融合的一个函数,广泛用于像素级图像融合。它通过对两张图像进行加权求和,产生一张新的图像。这对于实现图像的融合、过渡效果、或者图像增强等任务非常有用。

cv2.addWeighted(src1, alpha, src2, beta, gamma)
参数名 说明
src1 第一张输入图像。
alpha 第一张图像的权重,控制第一张图像对最终融合图像的贡献度。
src2 第二张输入图像。
beta 第二张图像的权重,控制第二张图像对最终融合图像的贡献度。
gamma 可选的偏移量,通常用于图像亮度的调整(例如对融合图像进行亮度增加或减少)。默认值为 0。

三、图像阈值

        在OpenCV中,图像阈值操作是一个常见的图像处理技术,可以将图像的像素值根据设定的 阈值进行分类,通常是将图像分为前景和背景。

ret, dst = cv2.threshold(src, thresh, maxval, type)
参数名 说明
ret True 或 False,表示是否成功读取图片。
dst 输出的二值化图像。
src 输入图像(仅支持单通道,通常为灰度图)。
thresh 阈值(0-255 之间的值,如 127)。
maxval 当像素值超过(或低于)阈值时赋予的值(具体行为由 type 决定)。
type 二值化操作类型,共 5 种(见下方详细对比)。
阈值类型(type 大于阈值像素的处理 小于或等于阈值像素的处理 结果图像描述
cv2.THRESH_BINARY 设为 maxval(如 255) 设为 0 亮区白色,暗区黑色
cv2.THRESH_BINARY_INV 设为 0 设为 maxval(如 255) 亮区黑色,暗区白色
cv2.THRESH_TRUNC 截断为 thresh 值 保持原值 亮区被截断至阈值,暗区不变
cv2.THRESH_TOZERO 保持原值 设为 0 亮区不变,暗区黑色
cv2.THRESH_TOZERO_INV 设为 0 保持原值 亮区黑色,暗区不变
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread("../images/ROI.png")

# 转换为灰度图
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

ret,thresh1 = cv2.threshold(gray_img,127,255,cv2.THRESH_BINARY )
ret,thresh2 = cv2.threshold(gray_img,127,255,cv2.THRESH_BINARY_INV  )
ret,thresh3 = cv2.threshold(gray_img,127,255,cv2.THRESH_TRUNC  )
ret,thresh4 = cv2.threshold(gray_img,127,255,cv2.THRESH_TOZERO  )
ret,thresh5 = cv2.threshold(gray_img,127,255,cv2.THRESH_TOZERO_INV  )


titles = ["Original Image","BINARY","BINARY_INV","TRUNC","TOZERO","TOZERO_INV"]
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
# 遍历在6张图片上 matplotilb
for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()

cv2.waitKey(5000)
cv2.destroyAllWindows()

四、结构体Mat

4.1、Mat 的基本概念

        Mat 是 OpenCV 中用于存储图像数据和矩阵数据的主要数据结构。它代表着一个 n 维的密 集数值型数组,被设计用来存储实数或复数元素,并且可以存储单通道或多通道的数据。 与传统的 IplImage 结构体相比,Mat 具有自动内存管理的优势,能有效避免内存泄漏,使 用起来更加方便和安全。

4.2、Mat 的组成部分

        OpenCV 的 Mat 数据结构可以分为以下几个主要部分:

字段名 说明
dims 图像的维度(如 2D 图像的 dims=2)。
rows 图像的行数(高度)。
cols 图像的列数(宽度)。
depth 像素的位深(存储格式),例如 CV_8U(8位无符号整数)、CV_32F(32位浮点数)等。
channels 图像的通道数(如 RGB/BGR 图像为 3,灰度图为 1)。
size 矩阵的大小(格式为 (rows, cols))。
type 数据类型与通道的组合(如 CV_8UC3 表示 8位无符号整数 + 3通道)。
data 实际存储的像素数据(通常是内存指针或数组)。
import cv2
img = cv2.imread("../images/ROI.png")

print("rows",img.shape[0]) #高度rows 578
print("cols",img.shape[1]) #宽度cols 398
print("channels",img.shape[2]) #通道数channels 3
print("cols",img.dtype) #数据类型cols uint8

五、深拷贝与浅拷贝

        在 Python 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种不同的对象复制 方式,主要区别在于是否复制了对象中的嵌套对象。

深拷贝 浅拷贝
img.copy() 正常复制
import cv2
# 加载图片
img = cv2.imread("../images/ROI.png")

# 浅拷贝
img2 = img
# 深拷贝
img3 = img.copy()

# 修改img2
img[10:100,10:100] = [0, 0, 255]


cv2.imshow('img', img)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)


cv2.waitKey(0)
cv2.destroyAllWindows()


网站公告

今日签到

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