OpenCV--图片操作

news2024/12/29 14:48:47

一.图片旋转

  • 图片旋转是图像处理中的一种基本操作,用于将图像按照指定的角度进行旋转。旋转操作在图像编辑、计算机视觉和图形学等领域中非常常见,通常用来调整图像的方向或在图像识别中进行数据增强。

旋转的基本原理

  • 图片旋转涉及到将每个像素从原始位置移动到新的位置,并根据旋转角度重新计算这些像素的坐标。由于旋转后的像素坐标通常不是整数,所以通常需要进行插值(如双线性插值)来计算旋转后像素的颜色值。

旋转操作的步骤

  1. 定义旋转角度

    • 选择需要旋转的角度(例如 90°, 45°,或其他任意角度)。顺时针旋转通常为正角度,逆时针旋转为负角度。
  2. 计算旋转矩阵

    • 根据旋转角度计算旋转矩阵,这个矩阵用于将原始图像中的像素位置映射到旋转后的位置。
  3. 应用旋转矩阵

    • 使用旋转矩阵将原图像中的每个像素位置转换到新的位置。
    • 对于旋转后的图像边缘部分,可能会出现空白区域(通常是黑色)。
  4. 插值处理

    • 由于旋转可能导致像素坐标不是整数,使用插值方法(如双线性插值)计算旋转后像素的颜色值,以获得平滑的旋转结果。

示例代码(Python OpenCV)

import cv2
import numpy as np

# 读取图像
image = cv2.imread('image.jpg')

# 获取图像尺寸
(h, w) = image.shape[:2]

# 指定旋转角度(逆时针旋转45度)
angle = 45

# 计算图像中心
center = (w // 2, h // 2)

# 计算旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, 1.0)

# 进行仿射变换(旋转图像)
rotated_image = cv2.warpAffine(image, M, (w, h))

# 显示原图和旋转后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Rotated Image', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果和视觉效果

  • 旋转角度的影响:不同的旋转角度会将图像旋转到不同的位置。一般的旋转角度包括 90°、180°、270°,以及任意角度。
  • 空白区域:旋转后的图像可能会出现黑色的空白区域,这些区域代表了在旋转过程中无法填充的像素。
  • 插值效果:插值方法影响旋转后图像的平滑度,常用的插值方法有最近邻插值、双线性插值和双三次插值。

应用场景

  • 图像对齐:对拍摄角度不正确的图片进行旋转,以对齐到正确的方向。
  • 数据增强:在深度学习中,通过旋转图像来增加训练数据的多样性。
  • 图像编辑:调整图像的方向或对图像进行创意性旋转。

在 OpenCV 中,getRotationMatrix2DwarpAffine 是两个用于图像旋转和仿射变换的函数。下面是这两个函数的详细说明和参数解释:

1. cv2.getRotationMatrix2D

getRotationMatrix2D 函数用于生成二维旋转矩阵,它在进行图像旋转时非常有用。

函数原型:
cv2.getRotationMatrix2D(center, angle, scale)
参数说明:
  • center: 旋转中心点(x, y),指定旋转的中心位置。通常是图像的中心点。
    • 类型: (x, y) 元组
  • angle: 旋转角度,逆时针方向为正值。例如,90 表示图像逆时针旋转 90 度。
    • 类型: float
  • scale: 缩放因子,指定旋转后图像的缩放比例。值为 1.0 表示图像大小保持不变,值大于 1.0 表示放大,值小于 1.0 表示缩小。
    • 类型: float
返回值:
  • M: 旋转矩阵,3x2 的矩阵,用于 warpAffine 函数进行仿射变换。
    • 类型: numpy.ndarray,形状为 (2, 3)
示例代码:
import cv2

# 获取图像尺寸
(h, w) = image.shape[:2]

# 计算图像中心
center = (w // 2, h // 2)

# 生成旋转矩阵
M = cv2.getRotationMatrix2D(center, 45, 1.0)

2. cv2.warpAffine

warpAffine 函数用于对图像应用仿射变换,包括旋转、缩放、平移等操作。

函数原型:
cv2.warpAffine(src, M, dsize, flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0))
参数说明:
  • src: 输入图像,即需要进行变换的图像。
    • 类型: numpy.ndarray
  • M: 仿射变换矩阵,通常由 getRotationMatrix2D 函数生成的矩阵。
    • 类型: numpy.ndarray,形状为 (2, 3)
  • dsize: 输出图像的大小 (width, height)。这应该是变换后的图像的尺寸。
    • 类型: (width, height) 元组
  • flags: 插值方法,用于计算输出图像像素值。常见的值包括:
    • cv2.INTER_NEAREST:最近邻插值
    • cv2.INTER_LINEAR:双线性插值(默认值)
    • cv2.INTER_CUBIC:双三次插值
    • cv2.INTER_LANCZOS4:Lanczos 插值
    • 类型: int
  • borderMode: 边界模式,定义了当输入图像被变换到图像外部时的处理方式。常见的值包括:
    • cv2.BORDER_CONSTANT:使用常数值填充边界(由 borderValue 指定)
    • cv2.BORDER_REPLICATE:复制边界像素
    • cv2.BORDER_REFLECT:反射边界像素
    • cv2.BORDER_WRAP:包裹边界像素
    • 类型: int
  • borderValue: 边界填充的颜色值,仅在 borderModecv2.BORDER_CONSTANT 时有效。可以是灰度值或 RGB 值(对于彩色图像)。
    • 类型: (R, G, B) 元组 或 int
返回值:
  • dst: 变换后的图像。
    • 类型: numpy.ndarray
示例代码:
import cv2

# 读取图像
image = cv2.imread('image.jpg')

# 获取图像尺寸
(h, w) = image.shape[:2]

# 计算图像中心
center = (w // 2, h // 2)

# 生成旋转矩阵
M = cv2.getRotationMatrix2D(center, 45, 1.0)

# 应用旋转变换
rotated_image = cv2.warpAffine(image, M, (w, h))

# 显示结果
cv2.imshow('Rotated Image', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • getRotationMatrix2D 用于生成旋转矩阵,它的参数包括旋转中心、角度和缩放因子。
  • warpAffine 用于应用仿射变换,包括旋转、缩放等,它的参数包括输入图像、变换矩阵、输出图像尺寸以及插值和边界处理方式。

这两个函数通常结合使用,首先使用 getRotationMatrix2D 生成旋转矩阵,然后用 warpAffine 将这个矩阵应用到图像上,完成旋转操作。

二.插值方法

  • 插值方法在图像处理、数据分析、数值计算等领域广泛应用,其核心思想是在已知数据点之间估算出未知数据点的值。

1. *cv2.INTER_NEAREST:最近邻插值

    • 原理:最近邻插值方法通过选择距离目标像素最近的原始像素的值来进行插值。这是最简单且计算最快的方法。
    • 优点:计算速度快,适用于对计算资源要求严格的场景。
    • 缺点:插值结果可能会出现锯齿状边缘,图像质量较差。
    • 适用场景:通常用于需要快速处理且对图像质量要求不高的情况,例如实时图像处理或低分辨率图像。

    为了更好地理解最近邻插值的计算原理,以下是一个详细的计算示例,展示如何通过最近邻插值法从原图像计算目标图像的像素值。

示例场景

假设我们有一个 2x2 像素的原始图像,如下所示:

A (0,0) | B (0,1)
--------|--------
C (1,0) | D (1,1)

每个字母代表一个像素,像素的坐标 (x, y) 标示在旁边。像素值如下(假设是灰度图像):

A = 100, B = 150
C = 200, D = 250

现在,我们想将这个 2x2 图像放大为 4x4 图像。

目标图像的坐标计算

假设目标图像的大小是原始图像的两倍(4x4),因此目标图像的每个像素点 (x, y) 对应原图像上的点 (x'/2, y'/2),其中 x'y' 是目标图像的像素坐标,且 x'y' 的取值范围是 [0, 3]

最近邻插值步骤

  1. 计算目标像素的对应位置
    对于目标图像中的任意一个像素 (x', y'),我们首先计算它对应的原图像位置 (x, y)
    [
    x = \frac{x’}{2}, \quad y = \frac{y’}{2}
    ]

  2. 找到最近的原始像素
    (x, y) 四舍五入到最近的整数坐标 (x_\text{nearest}, y_\text{nearest}),得到最近的原图像像素坐标。

  3. 分配像素值
    将原图像中 (x_\text{nearest}, y_\text{nearest}) 对应的像素值分配给目标图像中的像素 (x', y')

具体计算过程

让我们计算一些具体的像素:

目标像素 (0, 0)
  • 对应的原始坐标:
    [
    x = \frac{0}{2} = 0.0, \quad y = \frac{0}{2} = 0.0
    ]
  • 四舍五入后:
    [
    x_\text{nearest} = 0, \quad y_\text{nearest} = 0
    ]
  • 分配像素值:
    目标图像 (0, 0) 的像素值等于原图像 (0, 0) 的像素值,即 A = 100
目标像素 (1, 2)
  • 对应的原始坐标:
    [
    x = \frac{1}{2} = 0.5, \quad y = \frac{2}{2} = 1.0
    ]
  • 四舍五入后:
    [
    x_\text{nearest} = 1, \quad y_\text{nearest} = 1
    ]
  • 分配像素值:
    目标图像 (1, 2) 的像素值等于原图像 (1, 1) 的像素值,即 D = 250
目标像素 (3, 3)
  • 对应的原始坐标:
    [
    x = \frac{3}{2} = 1.5, \quad y = \frac{3}{2} = 1.5
    ]
  • 四舍五入后:
    [
    x_\text{nearest} = 2, \quad y_\text{nearest} = 2
    ]
    但注意到 xy 的最大值为 1(因为原始图像的大小是 2x2),所以这里 x_\text{nearest}y_\text{nearest} 都被限制为 1
  • 分配像素值:
    目标图像 (3, 3) 的像素值等于原图像 (1, 1) 的像素值,即 D = 250

结果

最终的 4x4 目标图像的像素值可能如下:

100 | 100 | 150 | 150
----|-----|-----|-----
100 | 100 | 150 | 150
----|-----|-----|-----
200 | 200 | 250 | 250
----|-----|-----|-----
200 | 200 | 250 | 250

每个新像素的值都来源于最近的原始像素值。可以看到,这种插值方式在图像放大时会产生明显的“块状效应”或“阶梯效应”,因为同一个原始像素的值被复制到多个目标像素上。这是最近邻插值的典型特征。

2. cv2.INTER_LINEAR:双线性插值(默认值)

  • 原理:双线性插值考虑了目标像素周围的四个最近像素,使用这些像素的加权平均值来估算目标像素的值。权重由目标像素与这些四个像素的距离决定。
  • 优点:比最近邻插值平滑得多,效果较好,计算复杂度也适中。
  • 缺点:在放大图像时,可能会出现一定的模糊效果。
  • 适用场景:适用于需要较高质量的图像缩放或旋转操作。
    双线性插值(Bilinear Interpolation)是一种常用的插值方法,尤其在图像处理中的缩放、旋转等操作中。双线性插值考虑了目标点周围四个已知像素点的值,并对这些值进行加权平均,以计算目标像素的值。这使得插值结果比最近邻插值更平滑。

原理概述

假设我们有一个原始图像,目标是计算一个目标图像中的像素值,而这个像素的坐标在原始图像的像素网格之间。双线性插值会使用目标像素附近的四个已知像素点的值,通过线性插值两次来计算出目标像素的值。

双线性插值的数学公式

设目标像素 (x, y) 的位置落在原始图像的四个像素点 (x1, y1)(x1+1, y1)(x1, y1+1)(x1+1, y1+1) 之间。这四个像素点的值分别为 Q11Q21Q12Q22,目标像素值 P 通过以下公式计算:

  1. 首先在 x 方向上进行线性插值
    [
    R1 = Q11 \times (x2 - x) + Q21 \times (x - x1)
    ]
    [
    R2 = Q12 \times (x2 - x) + Q22 \times (x - x1)
    ]
    其中:

    • R1(x, y1) 位置的插值结果
    • R2(x, y2) 位置的插值结果
  2. 然后在 y 方向上进行线性插值
    [
    P = R1 \times (y2 - y) + R2 \times (y - y1)
    ]

具体计算过程举例

假设我们有一个 2x2 像素的图像,像素值如下:

Q11 = 100, Q21 = 150
Q12 = 200, Q22 = 250

现在,我们想计算目标图像中像素 (0.5, 0.5) 的值。该目标点的位置位于原始图像的 4 个像素点 (0,0)(1,0)(0,1)(1,1) 之间。

计算步骤

  1. 找到周围的四个已知像素点

    • Q11 = 100 对应位置 (x1, y1) = (0, 0)
    • Q21 = 150 对应位置 (x2, y1) = (1, 0)
    • Q12 = 200 对应位置 (x1, y2) = (0, 1)
    • Q22 = 250 对应位置 (x2, y2) = (1, 1)
  2. 在 x 方向进行插值

    • 对于 (x, y1)
      [
      R1 = 100 \times (1 - 0.5) + 150 \times (0.5 - 0) = 100 \times 0.5 + 150 \times 0.5 = 50 + 75 = 125
      ]
    • 对于 (x, y2)
      [
      R2 = 200 \times (1 - 0.5) + 250 \times (0.5 - 0) = 200 \times 0.5 + 250 \times 0.5 = 100 + 125 = 225
      ]
  3. 在 y 方向进行插值

    • 最后一步,将 (R1, R2) 在 y 方向上插值,得到目标像素值 P
      [
      P = 125 \times (1 - 0.5) + 225 \times (0.5 - 0) = 125 \times 0.5 + 225 \times 0.5 = 62.5 + 112.5 = 175
      ]

最终结果

通过上述计算,目标图像中 (0.5, 0.5) 的像素值 P175。这个值是通过考虑原始图像中相邻的四个像素值及其与目标像素位置的相对距离加权得到的,因此结果会比最近邻插值更加平滑。

3. cv2.INTER_CUBIC:双三次插值

  • 原理:双三次插值考虑目标像素周围 16 个像素点(4x4 矩阵),通过三次多项式函数进行插值。这种方法在插值过程中进行更多的平滑处理。
  • 优点:提供比双线性插值更平滑的结果,尤其是在大幅度放大时。
  • 缺点:计算复杂度较高,速度较慢。
  • 适用场景:适用于需要高质量放大图像的情况,尤其是细节要求较高的图像处理任务。

4. cv2.INTER_LANCZOS4:Lanczos 插值

  • 原理:Lanczos 插值是一种基于 sinc 函数的插值方法,考虑目标像素周围 8x8 的像素点。它使用 Lanczos 函数(窗口函数)进行插值计算,能够提供高质量的插值效果。
  • 优点:提供非常平滑且高质量的图像缩放效果,尤其在高倍放大时效果明显。
  • 缺点:计算复杂度高,速度较慢。
  • 适用场景:适用于高质量图像处理任务,如专业图像编辑或打印前的图像处理。

5. cv2.INTER_AREA:像素区域插值法

  • 原理:像素区域插值法通过计算区域内像素的平均值来进行插值,主要用于缩小图像时的插值。
  • 优点:在图像缩小时,可以有效地减少伪影和模糊,通常会生成较为平滑的结果。
  • 缺点:对于图像放大可能效果不佳,可能会导致图像模糊。
  • 适用场景:适用于图像缩小或减少分辨率时,能够有效控制图像质量的损失。

示例代码(Python OpenCV)

import cv2

# 读取图像
image = cv2.imread('image.jpg')

# 获取图像尺寸
(h, w) = image.shape[:2]

# 缩小图像示例
scaled_image_area = cv2.resize(image, (w // 2, h // 2), interpolation=cv2.INTER_AREA)# #cv2.INTER_AREA:像素区域插值法 **

#INTER_NEAREST:最近邻插值

# 放大图像示例
scaled_image_linear = cv2.resize(image, (w * 2, h * 2), interpolation=cv2.INTER_LINEAR)#INTER_LINEAR:双线性插值(默认值)对图片进行缩放
scaled_image_cubic = cv2.resize(image, (w * 2, h * 2), interpolation=cv2.INTER_CUBIC)#INTER_CUBIC:双三次插值 **
scaled_image_lanczos = cv2.resize(image, (w * 2, h * 2), interpolation=cv2.INTER_LANCZOS4)# #cv2.INTER_LANCZOS4:Lanczos插值 **

# 显示结果
cv2.imshow('Scaled Image - Area', scaled_image_area)
cv2.imshow('Scaled Image - Linear', scaled_image_linear)
cv2.imshow('Scaled Image - Cubic', scaled_image_cubic)
cv2.imshow('Scaled Image - Lanczos', scaled_image_lanczos)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • cv2.INTER_AREA:适合图像缩小时使用,能有效减少图像缩小时的混叠效应。
  • cv2.INTER_NEAREST:速度快但质量较差,适合简单应用。
  • cv2.INTER_LINEAR:平衡速度和质量,适用于一般情况的缩放操作。
  • cv2.INTER_CUBIC:提供较高图像质量,适合图像放大。
  • cv2.INTER_LANCZOS4:最高图像质量,适合需要高保真度的图像处理。

三.边缘填充方式

  • 边缘填充(Edge Padding)是图像处理中常用的一种技术,用于在图像处理操作(如卷积、滤波、缩放等)时处理边缘区域。因为许多图像处理算法需要处理图像的局部区域,边缘填充能够有效地解决边缘像素不足的问题。下面介绍一些常见的边缘填充方式:

1. 常量填充(Constant Padding)

  • 原理:用固定的常量值填充图像的边缘区域。
  • 优点:简单直观,易于实现。
  • 缺点:可能会在填充区域产生明显的边界。
  • 适用场景:当边缘处理对图像内容无特别要求时,如某些预处理步骤。

示例
填充值 c 的常量填充:

c  c  c  c
c  *A  B*  c
c  *C  D*  c
c  c  c  c

2. 复制填充(Replication Padding)

  • 原理:用图像边缘的像素值填充边缘区域。即边缘外部的像素值等于边缘的最近像素值。
  • 优点:能够保持图像边缘的连续性,避免产生明显的边界。
  • 缺点:可能会在图像角落产生不自然的过渡。
  • 适用场景:边缘较为重要的图像处理任务,如边缘检测、卷积操作等。

示例
边缘像素值为 ABCD 的复制填充:

 A   A  B   B
 A  *A  B*  B
 C  *C  D*  D
 C   C  D   D

3. 对称填充(Symmetric Padding)----边界反射(BORDER_REFLECT)

  • 原理:通过对称地复制边缘像素来填充边缘区域。填充区域是原图像的镜像。
  • 优点:平滑地延续了图像边缘的内容,不会出现明显的过渡。
  • 缺点:可能会引入不必要的边缘特征。
  • 适用场景:需要平滑过渡的图像处理任务,如滤波、卷积等。

示例
对称填充图像边缘:

D  C  B  A   A  B  C  D
D  C  B  A  *A  B  C  D*
D  C  B  A   A  B  C  D
D  C  B  A   A  B  C  D

4. **反射填充(Reflection Padding)**边界反射101(BORDER_REFLECT)

  • 原理:图像边缘区域通过图像内容的反射来填充,图像内容在边缘外部是原图像的反射。
  • 优点:较好地延续了图像内容,适合处理连续数据。
  • 缺点:在填充区域可能产生人工效果。
  • 适用场景:图像处理需要平滑过渡的情况,如图像修复、边缘处理等。

示例
反射填充图像边缘:
在这里插入图片描述

D  C  B  A  B  C  D
D  C  B  A  B  C  D
D  C  B  A  B  C  D
D  C  B  A  B  C  D

5 边界包裹(BORDER_WRAP)
在这里插入图片描述

四.图片缩放

1.cv2.resize() 函数

在OpenCV中,cv2.resize() 函数用于调整图像的大小。它有几个关键参数,可以用来控制图像缩放的方式。

resized_image = cv2.resize(src, dsize, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)

参数详解

  1. src(输入图像)

    • 类型numpy.ndarray
    • 说明:待调整大小的输入图像。这是一个多维数组,通常是通过 OpenCV 读取的图像。
  2. dsize(输出图像的尺寸)

    • 类型tuple (width, height)
    • 说明:指定输出图像的大小,格式为 (宽度, 高度)。如果设置为 (0, 0),则必须指定 fxfy,用于缩放因子。
    • 注意
      • 如果同时指定了 dsizefx, fy,那么图像会被调整为 dsize 指定的大小,而忽略 fxfy
      • dsizefx, fy 不能都为 0
  3. fx(宽度方向的缩放因子)

    • 类型float
    • 说明:沿水平方向的缩放因子。默认值为 0,表示未指定。如果 dsize(0, 0),则使用此缩放因子计算输出图像的宽度。
  4. fy(高度方向的缩放因子)

    • 类型float
    • 说明:沿垂直方向的缩放因子。默认值为 0,表示未指定。如果 dsize(0, 0),则使用此缩放因子计算输出图像的高度。
  5. interpolation(插值方法)

    • 类型int
    • 说明:指定插值方法,决定在调整图像大小时如何计算新像素的值。常见的插值方法有:
      • cv2.INTER_NEAREST:最近邻插值
      • cv2.INTER_LINEAR:双线性插值(默认)
      • cv2.INTER_CUBIC:双三次插值
      • cv2.INTER_LANCZOS4:Lanczos 插值
      • cv2.INTER_AREA:像素区域插值
    • 选择插值方法的提示
      • cv2.INTER_NEAREST 是最简单的,计算最快,但质量最差。
      • cv2.INTER_LINEAR 是平衡质量和速度的常用选择,特别适合缩小图像。
      • cv2.INTER_CUBICcv2.INTER_LANCZOS4 更适合放大图像,提供较高质量。
      • cv2.INTER_AREA 是缩小图像时的最佳选择,可以减少伪影。

举例说明

  • 根据指定尺寸缩放图像

    resized_image = cv2.resize(image, (400, 300))  # 将图像缩放为400x300像素
    
  • 根据比例缩放图像

    resized_image = cv2.resize(image, (0, 0), fx=0.5, fy=0.5)  # 将图像缩放为原尺寸的一半
    
  • 使用不同的插值方法

import cv2

if __name__ == "__main__":
    path = "./pythonProject/src/face.png"
    image_np = cv2.imread(path)
    resize_image = cv2.resize(image_np, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_LINEAR)  #INTER_LINEAR:双线性插值(默认值)对图片进行缩放
    resize_image1 = cv2.resize(image_np, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_NEAREST) #INTER_NEAREST:最近邻插值
    resize_image2 = cv2.resize(image_np, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_CUBIC)  #INTER_CUBIC:双三次插值 **
    resize_image3 = cv2.resize(image_np, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)#cv2.INTER_LANCZOS4:Lanczos插值 **
    resize_image4 = cv2.resize(image_np, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_AREA)#cv2.INTER_AREA:像素区域插值法 **
    cv2.imshow("image_np",image_np)
    cv2.imshow("0", resize_image)
    cv2.imshow("1", resize_image1)
    cv2.imshow("2", resize_image2)
    cv2.imshow("3", resize_image3)
    cv2.imshow("4", resize_image4)

    cv2.waitKey(0)

五.图片镜像旋转

  • 在图像处理领域,flip() 是一个常用于对图像进行镜像旋转的操作。具体实现和参数可能会因编程语言和图像处理库的不同而有所差异,但常见的图像处理库如 OpenCV 和 PIL(Pillow)都支持这种操作。

OpenCV 的 flip() 函数

函数原型:

cv2.flip(src, flipCode)

参数说明:

  1. src:输入图像(可以是任何图像数据,例如一个 NumPy 数组)。
  2. flipCode
    • 0:沿着 x 轴(水平)翻转。
    • 1:沿着 y 轴(垂直)翻转。
    • -1:同时沿着 x 轴和 y 轴翻转。

示例代码:

import cv2

# 读取图像
image = cv2.imread('example.jpg')

# 水平翻转
flipped_horizontal = cv2.flip(image, 1)

# 垂直翻转
flipped_vertical = cv2.flip(image, 0)

# 同时水平和垂直翻转
flipped_both = cv2.flip(image, -1)

# 显示翻转后的图像
cv2.imshow('Flipped Image', flipped_both)
cv2.waitKey(0)
cv2.destroyAllWindows()

Pillow(PIL)库的镜像翻转

Pillow 库提供了镜像翻转的功能,但它的实现方式略有不同,主要通过图像的 transpose() 方法来完成。

函数原型:

image.transpose(method)

常用的 method 参数值:

  • Image.FLIP_LEFT_RIGHT:水平翻转。
  • Image.FLIP_TOP_BOTTOM:垂直翻转。

示例代码:

from PIL import Image

# 读取图像
image = Image.open('example.jpg')

# 水平翻转
flipped_horizontal = image.transpose(Image.FLIP_LEFT_RIGHT)

# 垂直翻转
flipped_vertical = image.transpose(Image.FLIP_TOP_BOTTOM)

# 保存翻转后的图像
flipped_horizontal.save('flipped_horizontal.jpg')
flipped_vertical.save('flipped_vertical.jpg')

五.图像噪点消除

  • 图像噪点消除是图像处理中的常见任务,目的是减少或去除图像中的噪声,从而提高图像的质量。常用的噪声类型包括高斯噪声、椒盐噪声、泊松噪声等。以下是一些常见的噪点消除方法,适用于不同类型的噪声。

1. 平均滤波

原理:通过计算一个像素及其邻域像素的平均值来平滑图像。

blur() 是一个用于对图像进行平滑处理的函数,常见于图像处理库如 OpenCV。在图像处理中,“平滑”或“模糊”处理可以帮助减少噪点和细节,使图像看起来更加均匀。blur() 函数通常执行的是一种均值滤波操作。

OpenCV 的 blur() 函数

函数原型:

cv2.blur(src, ksize, dst=None, anchor=(-1, -1), borderType=cv2.BORDER_DEFAULT)

参数说明:

  1. src:输入图像。可以是灰度图像或彩色图像,通常是一个 NumPy 数组。

  2. ksize:卷积核的大小。它是一个包含两个整数的元组 (w, h),表示卷积核的宽度和高度。这个核将在图像上滑动,计算每个像素及其邻域的平均值。例如,(5, 5) 表示使用 5x5 的卷积核进行处理。

  3. dst:输出图像。通常情况下,这个参数可以忽略,OpenCV 会自动创建一个与输入图像相同大小的输出图像。如果指定了 dst,则处理后的结果将存储在这个图像中。

  4. anchor:锚点位置。这个参数用于确定卷积核的锚点位置。默认值 (-1, -1) 表示卷积核的中心作为锚点。实际应用中,通常不需要修改这个值。

  5. borderType:边界处理方式。用于确定如何处理卷积核边界外的像素。常用的值包括:

    • cv2.BORDER_CONSTANT:边界外的像素使用常数值填充(默认为零)。
    • cv2.BORDER_REFLECT:边界外的像素使用反射填充。
    • cv2.BORDER_WRAP:边界外的像素使用包装填充。
    • cv2.BORDER_REPLICATE:边界外的像素使用复制填充。
    • cv2.BORDER_DEFAULT:使用默认的边界处理方式。

示例代码

下面是一个使用 OpenCV 的 blur() 函数对图像进行平滑处理的示例代码:

import cv2

# 读取图像
image = cv2.imread('example.jpg')

# 定义卷积核的大小
ksize = (5, 5)

# 应用均值滤波
blurred_image = cv2.blur(image, ksize)

# 显示结果
cv2.imshow('Blurred Image', blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键点

  • 卷积核大小 (ksize):较大的卷积核会导致更强的模糊效果,但也可能会使图像的细节丢失。因此,需要根据实际情况选择合适的卷积核大小。
  • 边界处理 (borderType):对于不同的边界处理方式,可能会对图像边缘产生不同的效果,选择合适的边界处理方式可以帮助改善结果。

2. 高斯滤波 (Gaussian Blur)

原理
高斯滤波通过高斯函数对图像进行模糊处理,有助于减少图像噪声,并且比平均滤波能更好地保留图像的边缘信息。

OpenCV 函数原型

cv2.GaussianBlur(src, ksize, sigmaX, sigmaY=0, borderType=cv2.BORDER_DEFAULT)

参数说明

  1. src:输入图像。
  2. ksize:卷积核的大小。必须是奇数(如 (5, 5)(3, 3))。大核会产生更多的模糊效果。
  3. sigmaX:高斯核在 x 方向的标准差。如果 sigmaY 为 0,则 sigmaX 也会被用作 sigmaY
  4. sigmaY:高斯核在 y 方向的标准差。如果不指定,默认为 0,此时 sigmaX 会被用作 sigmaY
  5. borderType:边界处理方式,常用值包括 cv2.BORDER_DEFAULTcv2.BORDER_REFLECT 等。

示例代码

import cv2

# 读取图像
image = cv2.imread('example.jpg')

# 定义卷积核大小和标准差
ksize = (5, 5)
sigmaX = 1.5

# 应用高斯滤波
gaussian_blurred = cv2.GaussianBlur(image, ksize, sigmaX)

# 显示图像
cv2.imshow('Gaussian Blurred Image', gaussian_blurred)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 中值滤波 (Median Blur)

原理
中值滤波将每个像素的值替换为其邻域像素值的中位数。这对于去除椒盐噪声特别有效。

OpenCV 函数原型

cv2.medianBlur(src, ksize)

参数说明

  1. src:输入图像。
  2. ksize:卷积核的大小,必须是奇数(如 3, 5, 7)。指定邻域的大小,用于计算中位数。

示例代码

import cv2

# 读取图像
image = cv2.imread('example.jpg')

# 定义卷积核大小
ksize = 5

# 应用中值滤波
median_blurred = cv2.medianBlur(image, ksize)

# 显示图像
cv2.imshow('Median Blurred Image', median_blurred)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 双边滤波 (Bilateral Filter)

原理
双边滤波是一种非线性滤波器,能够在平滑图像的同时保留边缘。它结合了空间距离和像素值的差异来决定每个像素的权重。

OpenCV 函数原型

cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, borderType=cv2.BORDER_DEFAULT)

参数说明

  1. src:输入图像。
  2. d:每个像素邻域的直径(例如 9)。用于控制滤波器的大小。
  3. sigmaColor:颜色空间的标准差。决定像素值差异对滤波器的影响程度。值越大,影响范围越大。
  4. sigmaSpace:坐标空间的标准差。决定像素位置差异对滤波器的影响程度。值越大,影响范围越大。
  5. borderType:边界处理方式,常用值包括 cv2.BORDER_DEFAULTcv2.BORDER_REFLECT 等。

示例代码

import cv2

# 读取图像
image = cv2.imread('example.jpg')

# 定义滤波器参数
d = 9
sigmaColor = 75
sigmaSpace = 75

# 应用双边滤波
bilateral_blurred = cv2.bilateralFilter(image, d, sigmaColor, sigmaSpace)

# 显示图像
cv2.imshow('Bilateral Blurred Image', bilateral_blurred)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. 方框滤波 (Box Filter)

原理
方框滤波,也称为均值滤波,通过计算每个像素及其邻域像素的平均值来平滑图像。它的模糊效果简单但较强。

OpenCV 函数原型

cv2.boxFilter(src, ddepth, ksize, dst=None, anchor=(-1, -1), normalize=True, borderType=cv2.BORDER_DEFAULT)

参数说明

  1. src:输入图像。
  2. ddepth:输出图像的深度。如果为 -1,输出图像的深度与输入图像相同。
  3. ksize:卷积核的大小,通常是 (w, h) 格式。大核会产生更强的模糊效果。
  4. dst:输出图像。默认为 None,OpenCV 会自动创建一个输出图像。
  5. anchor:锚点位置。通常不需要调整,默认为 (-1, -1),表示核的中心。
  6. normalize:是否对卷积核进行归一化,默认为 True
  7. borderType:边界处理方式,常用值包括 cv2.BORDER_DEFAULTcv2.BORDER_REFLECT 等。

示例代码

import cv2

# 读取图像
image = cv2.imread('example.jpg')

# 定义卷积核大小
ksize = (5, 5)

# 应用方框滤波
box_filtered = cv2.boxFilter(image, -1, ksize)

# 显示图像
cv2.imshow('Box Filtered Image', box_filtered)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 平均滤波–blur():适用于减少图像噪声和实现简单的模糊效果。
  • 高斯滤波–GaussianBlur():适用于去除高斯噪声,保留边缘信息。
  • 中值滤波-medianBlur():适用于去除椒盐噪声,保留边缘信息。
  • 双边滤波–bilateralFilter():能够在平滑图像的同时有效地保留边缘。
  • 方框滤波–boxFilter():简单的均值滤波,模糊效果强,但不保留边缘细节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(贪心) LeetCode 376. 摆动序列

原题链接 一. 题目描述 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如, [1, 7, 4, 9, 2,…

电脑技巧:电脑系统盘文件清理指南

目录 一、可以安全删除的文件 1.1. 临时文件 1.2. 系统缓存文件 1.3. 回收站 1.4. 安装包缓存 1.5. 系统还原点 1.6. 已下载的更新文件 1.7. 浏览器缓存 1.8. Thumbs.db 文件 1.9. Windows日志文件 1.10. Windows.old 文件夹 二、系统文件清理注意点 三、系统文件…

推荐一款Python开源移动应用安全测试分析工具!!!

今天给大家推荐一个安全测试相关的开源项目:nccgroup/house 1、介绍 它是一个由 NCC Group 开发的,一个基于Frida和Python编写的动态运行时移动应用分析工具包,提供了基于 Frida 的 Web GUI 界面,旨在简化动态函数挂钩的过程&am…

Linux---04---Vim编辑器

一、vi/vim编辑器介绍 vi 是 visual interface 的简称,是Linux系统提供的一个文本编辑工具,可以对文件内容进行编辑,类似于Windows中的记事本。 vim 是 vi 的加强版本,兼容 vi 的所有指令,不仅能编辑文本&#xff0c…

Using locally deployed llm with langchain‘s openai llm wrapper

题意:使用本地部署的LLM与Langchain的OpenAI LLM封装器 问题背景: I have deployed llm model locally which follows openai api schema. As its endpoint follows openai schema, I dont want to write separate inference client. 我已经本地部署了…

Mybatis框架介绍

Mybatis入门 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Jav…

IT管控体系建设(集团企业),附网传埃森哲案例

(一)集团IT企业IT管控组织结构设计 1.集团分管领导 职能:最高级别的管理,负责对整个集团的信息化管控进行监督和决策。 2.CIO/管理部主任 职能:负责整体的IT战略和方向,直接向集团分管领导汇报。负责协…

一分钟了解:Java 冒泡排序算法

1. 冒泡排序算法介绍 冒泡排序是最简单的排序算法,如果相邻元素的顺序错误,则通过反复交换相邻元素来工作。Java 中的冒泡排序不是对数组进行排序的最佳方法,但却是最基本的实现之一。在本文中,我们将学习如何用 Java 编写冒泡排…

「Pytorch」解析 nn.Embedding 词嵌入 及反推输入

在Pytorch里面有三种编码方式,Embedding 就是其中之一,不同于 one_hot 需要用同长度的张量存 Embedding将单词映射为稠密向量,并且指定 embedding_dim维度。通过 Embedding层 转换的数据并不是经过词典映射的,而是原始数据。Embed…

VirtualBox扩容VDI虚拟磁盘

环境 虚拟机软件:VirtualBox虚拟机:Ubuntu 18.04.1 第一步:调整虚磁盘大小 方法1:使用VirtualBox管理器直接修改 关闭虚拟机,点击VirtualBox管理器菜单管理>虚拟介质管理,重新设大小 方法2&#x…

【Linux基础】对Linux权限的理解与管理

目录 🚀前言一,有关用户二,Linux权限管理1. 文件访问者的分类(人)2. 文件类型和访问权限(事物属性)2.1 文件类型2.2 文件/目录的基本权限 三,文件权限值的表示方法3.1 字符表示方法3.2 八进制数值表示方法 四,文件访问…

服务器是什么?怎么选择适合自己的服务器?

在这个数字化的世界中,我们每天都在与各种网站打交道,浏览新闻、购物、看视频等。你是否曾经好奇过,这些网站是如何运行的?它们又是如何实现随时随地可访问的呢? 在这背后,有一个神秘的角色在默默地支撑着…

数据结构与算法 - 贪心算法

一、贪心例子 贪心算法或贪婪算法的核心思想是: 1. 将寻找最优解的问题分为若干个步骤 2. 每一步骤都采用贪心原则,选取当前最优解 3. 因为没有考虑所有可能,局部最优的堆叠不一定让最终解最优 贪心算法是一种在每一步选择中都采取在当前…

letcode 分类练习 树的遍历

letcode 分类练习 树的遍历 树的构建递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 层序遍历层序遍历可以解决的问题107. 二叉树的层序遍历 II199. 二叉树的右视图637. 二叉树的层平均值429. N 叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的…

掌机系统MuOS游戏名称中文乱码解决主题

最近买了安伯尼克的rg35xxh掌机来玩儿,然后刷了muos,系统很小巧,1g的运行内存,系统运行的时候只占用了不到100m,而且界面也很美观,就是有一个问题——中文名称会乱码,都变成了方框,从…

如何给IP地址开启https—IP证书

先IP地址申请的前提:80端口有打开,或者可以短暂的打开10分钟左右等验证完IP管理权再关掉。 一:访问JoySSL官网,注册账号并填写注册码230922,选择IP地址证书并下单加入购物车,下单之后就会跳转到证书申请界…

Linux--应用层协议HTTP协议(http服务器构建)

目录 1.HTTP 协议 2.认识 URL 3.urlencode 和 urldecode(编码) urlencode(URL编码) urldecode(URL解码) 4.HTTP 协议请求与响应格式 4.1HTTP 常见方法(三种) 5.HTTP 的状态码…

C++:命名空间与输入输出

目录 前言 一、命名空间 1.1 namespace的价值 1.2 namespace的定义 1.3 命名空间的使用 二、C输入&输出 前言 C是一种面向对象的计算机程序设计语言,‌它扩展了C语言的功能,‌并引入了面向对象编程的概念,‌如类、‌继承和多态等&a…

【笔记】从零开始做一个精灵龙女-画贴图阶段(下)

补充四点,第一,前期画体积用一号或十三号笔刷,压力60,硬度80,体积大一点 2号笔刷比较适合画过渡和软一点的东东 第二, 游戏里面角色原画海报都是发光很亮很透。但是在bp不能画那么亮,因为你进…