第1篇:图像处理的基本运算—从像素操作到几何变换

第1篇:图像处理的基本运算------从像素操作到几何变换

系列导语:本文是"有趣的图像处理"系列的开篇之作。我们将从最基础的像素操作开始,深入理解亮度、对比度、饱和度调整的原理,掌握自动颜色校正与二值化技术,并学习图像的基本几何变换(缩放、平移、旋转)


导语

当你用手机修图软件调整照片亮度、旋转图片、或者将彩色照片变成黑白时,你正在使用图像处理的基本运算

这些看似简单的操作背后,其实是一套精确的数学公式和算法逻辑。理解这些基础运算,是掌握所有高级滤镜和特效的必要前提

本文将从像素的本质出发,带你理解:

  • 图像是如何用矩阵表示的
  • 亮度、对比度、饱和度的数学模型
  • 自动颜色校正的算法原理
  • 二值化与阈值处理
  • 几何变换的矩阵表示(缩放、平移、旋转)

一、图像的本质------矩阵与像素

1.1 数字图像的数学表示

一幅数字图像,本质上就是一个二维矩阵

I = [ p 11 p 12 p 13 ⋯ p 1 w p 21 p 22 p 23 ⋯ p 2 w p 31 p 32 p 33 ⋯ p 3 w ⋮ ⋮ ⋮ ⋱ ⋮ p h 1 p h 2 p h 3 ⋯ p h w ] I = \begin{bmatrix} p_{11} & p_{12} & p_{13} & \cdots & p_{1w} \\ p_{21} & p_{22} & p_{23} & \cdots & p_{2w} \\ p_{31} & p_{32} & p_{33} & \cdots & p_{3w} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ p_{h1} & p_{h2} & p_{h3} & \cdots & p_{hw} \end{bmatrix} I= p11p21p31⋮ph1p12p22p32⋮ph2p13p23p33⋮ph3⋯⋯⋯⋱⋯p1wp2wp3w⋮phw

其中:

  • h h h 是图像高度(行数)
  • w w w 是图像宽度(列数)
  • p i j p_{ij} pij 是位置 ( i , j ) (i, j) (i,j) 处的像素值

1.2 像素值的含义

灰度图像

  • 每个像素用一个值表示: p i j ∈ [ 0 , 255 ] p_{ij} \in [0, 255] pij∈[0,255]
  • 0 0 0 表示纯黑, 255 255 255 表示纯白
  • 中间值表示不同程度的灰

彩色图像(RGB)

  • 每个像素用三个值表示: ( R , G , B ) (R, G, B) (R,G,B)
  • R R R:红色通道,取值范围 [ 0 , 255 ] [0, 255] [0,255]
  • G G G:绿色通道,取值范围 [ 0 , 255 ] [0, 255] [0,255]
  • B B B:蓝色通道,取值范围 [ 0 , 255 ] [0, 255] [0,255]

因此,一幅 h × w h \times w h×w 的彩色图像,实际上是一个 三维数组 : I ∈ R h × w × 3 I \in \mathbb{R}^{h \times w \times 3} I∈Rh×w×3

1.3 图像的坐标系

图像处理中常用两种坐标系:

笛卡尔坐标系

  • 原点 ( 0 , 0 ) (0, 0) (0,0) 在图像左上角
  • x x x 轴向右, y y y 轴向下
  • 像素 ( i , j ) (i, j) (i,j) 表示第 i i i 行、第 j j j 列

归一化坐标系

  • 将像素值映射到 [ 0 , 1 ] [0, 1] [0,1] 区间
  • 公式: x norm = x / 255 x_{\text{norm}} = x / 255 xnorm=x/255

二、像素级操作------点亮与调暗

2.1 亮度调整(Brightness Adjustment)

数学公式
I ′ [ i , j ] = I [ i , j ] + Δ I'[i,j] = I[i,j] + \Delta I′[i,j]=I[i,j]+Δ

其中:

  • I I I 是输入图像
  • I ′ I' I′ 是输出图像
  • Δ \Delta Δ 是亮度偏移量
    • Δ > 0 \Delta > 0 Δ>0:图像变亮
    • Δ < 0 \Delta < 0 Δ<0:图像变暗

BrightnessAdjust 算法流程

输入 : 图像 I I I, 亮度偏移值 Δ \Delta Δ (默认50)

输出 : 调整后的图像 I ′ I' I′

  1. 将图像转为浮点型(防止溢出): I float = I . astype ( float32 ) I_{\text{float}} = I.\text{astype}(\text{float32}) Ifloat=I.astype(float32)

  2. 对每个像素 ( i , j ) (i, j) (i,j): I ′ [ i , j ] = I [ i , j ] + Δ I'[i,j] = I[i,j] + \Delta I′[i,j]=I[i,j]+Δ

  3. 裁剪到有效范围: I ′ = Clip ( I ′ , 0 , 255 ) I' = \text{Clip}(I', 0, 255) I′=Clip(I′,0,255)

  4. 转回无符号整数: I ′ = I ′ . astype ( uint8 ) I' = I'.\text{astype}(\text{uint8}) I′=I′.astype(uint8)

  5. 返回 I ′ I' I′

关键问题:为什么要裁剪(Clip)?

当 I [ i , j ] + Δ > 255 I[i,j] + \Delta > 255 I[i,j]+Δ>255 时,像素值会溢出。例如:

  • 原始值: 240 240 240
  • 增加亮度: 240 + 50 = 290 240 + 50 = 290 240+50=290
  • 溢出后(uint8): 290   m o d   256 = 34 290 \bmod 256 = 34 290mod256=34(意外变暗!)

因此,必须用 Clip \text{Clip} Clip 函数将值限制在 [ 0 , 255 ] [0, 255] [0,255]:
Clip ( x , 0 , 255 ) = min ⁡ ( max ⁡ ( x , 0 ) , 255 ) \text{Clip}(x, 0, 255) = \min(\max(x, 0), 255) Clip(x,0,255)=min(max(x,0),255)

2.2 对比度调整(Contrast Adjustment)

数学公式
I ′ [ i , j ] = I [ i , j ] × factor I'[i,j] = I[i,j] \times \text{factor} I′[i,j]=I[i,j]×factor

其中:

  • factor > 1 \text{factor} > 1 factor>1:增强对比度(亮的更亮,暗的更暗)
  • factor < 1 \text{factor} < 1 factor<1:降低对比度
  • factor = 1 \text{factor} = 1 factor=1:不变

算法流程

算法: ContrastAdjust

输入 : 图像 I I I, 对比度因子 factor \text{factor} factor (默认1.5)

输出 : 调整后的图像 I ′ I' I′

①. 将图像转为浮点型: I float = I . astype ( float32 ) I_{\text{float}} = I.\text{astype}(\text{float32}) Ifloat=I.astype(float32)

②. 对每个像素 ( i , j ) (i, j) (i,j): I ′ [ i , j ] = I [ i , j ] × factor I'[i,j] = I[i,j] \times \text{factor} I′[i,j]=I[i,j]×factor

③. 裁剪到有效范围: I ′ = Clip ( I ′ , 0 , 255 ) I' = \text{Clip}(I', 0, 255) I′=Clip(I′,0,255)

④. 转回无符号整数: I ′ = I ′ . astype ( uint8 ) I' = I'.\text{astype}(\text{uint8}) I′=I′.astype(uint8)

  • 返回 I ′ I' I′

对比度增强的本质

对比度调整实际上是拉伸或压缩像素值的分布:

  • factor = 1.5 \text{factor} = 1.5 factor=1.5 时,原值 100 → 150 100 \to 150 100→150, 200 → 300 200 \to 300 200→300(clip到255)
  • 亮区间的差异被放大 ,暗区间的差异也被放大

2.3 亮度与对比度的组合

在实际应用中,亮度与对比度通常同时调整

I ′ [ i , j ] = Clip ( I [ i , j ] × factor + Δ , 0 , 255 ) I'[i,j] = \text{Clip}(I[i,j] \times \text{factor} + \Delta, 0, 255) I′[i,j]=Clip(I[i,j]×factor+Δ,0,255)

三、饱和度调整------颜色的鲜艳程度

3.1 为什么要在HSV空间调整饱和度?

RGB空间不适合直接调整颜色鲜艳程度,因为:

  • R、G、B三个通道相互耦合
  • 改变一个通道会影响颜色的色相(Hue)

HSV颜色空间将颜色分解为:

  • H(Hue,色相):颜色的种类(红、绿、蓝等)
  • S(Saturation,饱和度):颜色的纯度
  • V(Value,明度):颜色的亮度

在HSV空间中,只需调整S通道即可改变颜色鲜艳程度,不会影响色相。

3.2 饱和度调整算法

SaturationAdjust 算法流程

输入 : 图像 I I I (RGB), 饱和度因子 factor \text{factor} factor (默认1.5)

输出 : 调整后的图像 I ′ I' I′

①. 将RGB转换为HSV: I hsv = RGB2HSV ( I ) I_{\text{hsv}} = \text{RGB2HSV}(I) Ihsv=RGB2HSV(I)

②. 提取S通道: S = I hsv [ : , : , 1 ] S = I_{\text{hsv}}[:,:,1] S=Ihsv[:,:,1]

③. 调整饱和度:

S ′ = Clip ( S × factor , 0 , 255 ) S' = \text{Clip}(S \times \text{factor}, 0, 255) S′=Clip(S×factor,0,255)

I hsv [ : , : , 1 ] = S ′ I_{\text{hsv}}[:,:,1] = S' Ihsv[:,:,1]=S′

④. 将HSV转换回RGB: I ′ = HSV2RGB ( I hsv ) I' = \text{HSV2RGB}(I_{\text{hsv}}) I′=HSV2RGB(Ihsv)

  • 返回 I ′ I' I′

参数说明

  • factor > 1 \text{factor} > 1 factor>1:颜色更鲜艳
  • factor < 1 \text{factor} < 1 factor<1:颜色更淡雅
  • factor = 0 \text{factor} = 0 factor=0:完全去色(变成灰度图)

四、自动颜色校正------让图像"自动变好看"

4.1 自动颜色校正(Auto Color)

核心思想:让每个通道的平均值趋向中值(128),从而平衡颜色。

数学公式

对每个通道 c ∈ { B , G , R } : avg c = mean ( I [ : , : , c ] ) # 计算通道平均值 factor c = 128 / avg c # 计算校正因子 I ′ [ : , : , c ] = Clip ( I [ : , : , c ] × factor c , 0 , 255 ) \begin{aligned} &\text{对每个通道 } c \in \{B, G, R\}: \\ &\quad \text{avg}_c = \text{mean}(I[:,:,c]) \qquad \text{\# 计算通道平均值} \\ &\quad \text{factor}_c = 128 / \text{avg}_c \qquad \text{\# 计算校正因子} \\ &\quad I'[:,:,c] = \text{Clip}(I[:,:,c] \times \text{factor}_c, 0, 255) \end{aligned} 对每个通道 c∈{B,G,R}:avgc=mean(I[:,:,c])# 计算通道平均值factorc=128/avgc# 计算校正因子I′[:,:,c]=Clip(I[:,:,c]×factorc,0,255)

AutoColorCorrection 算法流程

输入 : 彩色图像 I I I ( H × W × 3 H \times W \times 3 H×W×3)

输出 : 颜色校正后的图像 I ′ I' I′

①. 复制图像: I ′ = I . copy ( ) I' = I.\text{copy}() I′=I.copy()

②. 对每个通道 c ∈ { 0 , 1 , 2 } c \in \{0, 1, 2\} c∈{0,1,2}: # B, G, R

计算通道平均值: avg c = mean ( I ′ [ : , : , c ] ) \text{avg}_c = \text{mean}(I'[:,:,c]) avgc=mean(I′[:,:,c])

计算校正因子

if avg c > 0 \text{avg}_c > 0 avgc>0: factor c = 128 / avg c \text{factor}_c = 128 / \text{avg}_c factorc=128/avgc

else: factor c = 1 \text{factor}_c = 1 factorc=1 # 防止除以零

应用校正: I ′ [ : , : , c ] = Clip ( I ′ [ : , : , c ] × factor c , 0 , 255 ) I'[:,:,c] = \text{Clip}(I'[:,:,c] \times \text{factor}_c, 0, 255) I′[:,:,c]=Clip(I′[:,:,c]×factorc,0,255)

③. 返回 I ′ I' I′

效果示例

  • 原始图像偏蓝(B通道平均值200)
  • 校正因子: 128 / 200 = 0.64 128 / 200 = 0.64 128/200=0.64
  • B通道所有像素值缩小64%,颜色更平衡

4.2 自动对比度(Auto Contrast)

核心思想 :将像素值线性映射到完整范围 [0, 255]

数学公式
I ′ [ i , j ] = ( I [ i , j ] − min_val ) × 255 max_val − min_val I'[i,j] = (I[i,j] - \text{min\_val}) \times \frac{255}{\text{max\_val} - \text{min\_val}} I′[i,j]=(I[i,j]−min_val)×max_val−min_val255

其中:

  • min_val = min ⁡ ( I ) \text{min\_val} = \min(I) min_val=min(I):图像最小像素值
  • max_val = max ⁡ ( I ) \text{max\_val} = \max(I) max_val=max(I):图像最大像素值

AutoContrast 算法流程

输入 : 图像 I I I

输出 : 对比度增强后的图像 I ′ I' I′

①. 计算全局最小和最大值:

min_val = min ⁡ ( I ) \text{min\_val} = \min(I) min_val=min(I) max_val = max ⁡ ( I ) \text{max\_val} = \max(I) max_val=max(I)

②. 如果 max_val > min_val : \text{max\_val} > \text{min\_val}: max_val>min_val: # 线性映射到 [ 0 , 255 ] [0, 255] [0,255]

I ′ = ( I − min_val ) × 255 / ( max_val − min_val ) I' = (I - \text{min\_val}) \times 255 / (\text{max\_val} - \text{min\_val}) I′=(I−min_val)×255/(max_val−min_val)

③. 否则: # 图像已经是均匀的,无需调整

I ′ = I I' = I I′=I

④. 返回 I ′ I' I′

实际实现 :使用OpenCV的 cv2.normalize() 函数:

复制代码
I' = cv2.normalize(I, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)

4.3 自动色阶(Auto Level)

核心思想 :与自动对比度类似,但对每个通道分别进行线性拉伸

数学公式

对每个通道 c : min c = min ⁡ ( I [ : , : , c ] ) max c = max ⁡ ( I [ : , : , c ] ) if max c > min c : I ′ [ : , : , c ] = ( I [ : , : , c ] − min c ) × 255 max c − min c \begin{aligned} &\text{对每个通道 } c: \\ &\quad \text{min}_c = \min(I[:,:,c]) \\ &\quad \text{max}_c = \max(I[:,:,c]) \\ &\quad \text{if } \text{max}_c > \text{min}_c: \\ &\qquad I'[:,:,c] = (I[:,:,c] - \text{min}_c) \times \frac{255}{\text{max}_c - \text{min}_c} \end{aligned} 对每个通道 c:minc=min(I[:,:,c])maxc=max(I[:,:,c])if maxc>minc:I′[:,:,c]=(I[:,:,c]−minc)×maxc−minc255

AutoLevel 算法流程

输入: 彩色图像 I (H×W×3)

输出: 色阶调整后的图像 I'

①. 复制图像: I ′ = I . c o p y ( ) I' = I.copy() I′=I.copy()

②. 对每个通道 c ∈ {0, 1, 2}:

min ⁡ c = min ⁡ ( I ′ [ : , : , c ] ) \min_c = \min(I'[:,:,c]) minc=min(I′[:,:,c])

max ⁡ c = max ⁡ ( I ′ [ : , : , c ] ) \max_c = \max(I'[:,:,c]) maxc=max(I′[:,:,c])

if max_c > min_c:

I ′ [ : , : , c ] = ( I ′ [ : , : , c ] − m i n c ) × 255 / ( m a x c − m i n c ) I'[:,:,c] = (I'[:,:,c] - min_c) × 255 / (max_c - min_c) I′[:,:,c]=(I′[:,:,c]−minc)×255/(maxc−minc)

I ′ [ : , : , c ] = C l i p ( I ′ [ : , : , c ] , 0 , 255 ) I'[:,:,c] = Clip(I'[:,:,c], 0, 255) I′[:,:,c]=Clip(I′[:,:,c],0,255)

③. 返回 I ′ I' I′

自动颜色 vs 自动对比度 vs 自动色阶

方法 原理 效果
自动颜色 通道均值归一化 平衡颜色
自动对比度 全局Min-Max映射 增强整体对比度
自动色阶 逐通道Min-Max映射 增强每通道对比度

五、灰度化与二值化

5.1 灰度化(Black & White)

方法一:平均值法

Gray [ i , j ] = R [ i , j ] + G [ i , j ] + B [ i , j ] 3 \text{Gray}[i,j] = \frac{R[i,j] + G[i,j] + B[i,j]}{3} Gray[i,j]=3R[i,j]+G[i,j]+B[i,j]

方法二:加权平均法(推荐)

人眼对不同颜色的敏感度不同:对绿色最敏感,对蓝色最不敏感。因此采用加权平均:

Gray [ i , j ] = 0.299 × R [ i , j ] + 0.587 × G [ i , j ] + 0.114 × B [ i , j ] \text{Gray}[i,j] = 0.299 \times R[i,j] + 0.587 \times G[i,j] + 0.114 \times B[i,j] Gray[i,j]=0.299×R[i,j]+0.587×G[i,j]+0.114×B[i,j]

RGB2Gray 算法流程

输入 : 彩色图像 I I I ( H × W × 3 H \times W \times 3 H×W×3)

输出 : 灰度图像 Gray \text{Gray} Gray ( H × W H \times W H×W)

①. 提取三个通道: # OpenCV使用BGR顺序

R = I [ : , : , 2 ] R = I[:,:,2] R=I[:,:,2]

G = I [ : , : , 1 ] G = I[:,:,1] G=I[:,:,1]

B = I [ : , : , 0 ] B = I[:,:,0] B=I[:,:,0]

②. 加权平均:

Gray = 0.299 × R + 0.587 × G + 0.114 × B \text{Gray} = 0.299 \times R + 0.587 \times G + 0.114 \times B Gray=0.299×R+0.587×G+0.114×B

③. 转换为整数:

Gray = Clip ( Gray , 0 , 255 ) . astype ( uint8 ) \text{Gray} = \text{Clip}(\text{Gray}, 0, 255).\text{astype}(\text{uint8}) Gray=Clip(Gray,0,255).astype(uint8)

  • 返回 Gray \text{Gray} Gray

OpenCV实现

复制代码
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

内部使用的权重系数:0.299, 0.587, 0.114

5.2 二值化(Binarization)

核心思想:根据阈值将像素分为两类------黑或白。

数学公式
I ′ [ i , j ] = { 255 , if I [ i , j ] > threshold 0 , otherwise I'[i,j] = \begin{cases} 255, & \text{if } I[i,j] > \text{threshold} \\ 0, & \text{otherwise} \end{cases} I′[i,j]={255,0,if I[i,j]>thresholdotherwise

Binarize算法流程

输入 : 图像 I I I, 阈值 threshold \text{threshold} threshold (默认128)

输出 : 二值图像 I ′ I' I′

①. 将图像转为灰度: gray = RGB2Gray ( I ) \text{gray} = \text{RGB2Gray}(I) gray=RGB2Gray(I)

②. 对每个像素 ( i , j ) (i, j) (i,j):

if gray [ i , j ] > threshold \text{gray}[i,j] > \text{threshold} gray[i,j]>threshold: I ′ [ i , j ] = 255 I'[i,j] = 255 I′[i,j]=255 # 白色

else: I ′ [ i , j ] = 0 I'[i,j] = 0 I′[i,j]=0 # 黑色

③. 返回 I ′ I' I′

OpenCV实现

复制代码
_, result = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY)

阈值选择

  • 固定阈值:手动指定(如128)
  • 自适应阈值:根据局部区域自动计算(Otsu方法)

六、几何变换基础------缩放、平移、旋转

6.1 仿射变换的矩阵表示

仿射变换是一类保持直线平行性的变换,包括:缩放、平移、旋转、倾斜。

齐次坐标系统 :为了用矩阵乘法表示平移,我们引入齐次坐标 (Homogeneous Coordinates),将二维点 (x, y) 表示为三维向量 (x, y, 1)

仿射变换矩阵

\\begin{bmatrix} x' \\ y' \\ 1 \\end{bmatrix} \\begin{bmatrix} a \& b \& c \\ d \& e \& f \\ 0 \& 0 \& 1 \\end{bmatrix} \\times \\begin{bmatrix} x \\ y \\ 1 \\end{bmatrix}

展开后:
x ′ = a × x + b × y + c y ′ = d × x + e × y + f \begin{aligned} x' &= a \times x + b \times y + c \\ y' &= d \times x + e \times y + f \end{aligned} x′y′=a×x+b×y+c=d×x+e×y+f

其中:

  • ( a , b , d , e ) (a, b, d, e) (a,b,d,e) 控制:缩放、旋转、倾斜
  • ( c , f ) (c, f) (c,f) 控制:平移

6.2 缩放(Scaling)

数学公式
x ′ = s x × x y ′ = s y × y \begin{aligned} x' &= s_x \times x \\ y' &= s_y \times y \end{aligned} x′y′=sx×x=sy×y
变换矩阵

s x 0 0 0 s y 0 0 0 1 \] \\begin{bmatrix} s_x \& 0 \& 0 \\\\ 0 \& s_y \& 0 \\\\ 0 \& 0 \& 1 \\end{bmatrix} sx000sy0001 其中: * s x \> 1 s_x \> 1 sx\>1:水平放大 * s x \< 1 s_x \< 1 sx\<1:水平缩小 * s y \> 1 s_y \> 1 sy\>1:垂直放大 * s y \< 1 s_y \< 1 sy\<1:垂直缩小 #### 6.3 平移(Translation) **数学公式** : x ′ = x + t x y ′ = y + t y \\begin{aligned} x' \&= x + t_x \\\\ y' \&= y + t_y \\end{aligned} x′y′=x+tx=y+ty **变换矩阵** : \[ 1 0 t x 0 1 t y 0 0 1 \] \\begin{bmatrix} 1 \& 0 \& t_x \\\\ 0 \& 1 \& t_y \\\\ 0 \& 0 \& 1 \\end{bmatrix} 100010txty1 其中: * t x \> 0 t_x \> 0 tx\>0:向右平移 * t y \> 0 t_y \> 0 ty\>0:向下平移 #### 6.4 旋转(Rotation) **数学公式** (绕原点逆时针旋转 θ \\theta θ 角度): x ′ = x × cos ⁡ ( θ ) − y × sin ⁡ ( θ ) y ′ = x × sin ⁡ ( θ ) + y × cos ⁡ ( θ ) \\begin{aligned} x' \&= x \\times \\cos(\\theta) - y \\times \\sin(\\theta) \\\\ y' \&= x \\times \\sin(\\theta) + y \\times \\cos(\\theta) \\end{aligned} x′y′=x×cos(θ)−y×sin(θ)=x×sin(θ)+y×cos(θ) **变换矩阵** : \[ cos ⁡ ( θ ) − sin ⁡ ( θ ) 0 sin ⁡ ( θ ) cos ⁡ ( θ ) 0 0 0 1 \] \\begin{bmatrix} \\cos(\\theta) \& -\\sin(\\theta) \& 0 \\\\ \\sin(\\theta) \& \\cos(\\theta) \& 0 \\\\ 0 \& 0 \& 1 \\end{bmatrix} cos(θ)sin(θ)0−sin(θ)cos(θ)0001 **绕任意点旋转**(如图像中心): 旋转中心 `(cx, cy)` 时,需要三步: 1. 平移到原点:`T(-cx, -cy)` 2. 旋转:`R(θ)` 3. 平移回去:`T(cx, cy)` **组合变换矩阵**: M = T ( c x , c y ) × R ( θ ) × T ( − c x , − c y ) M = T(cx, cy) \\times R(\\theta) \\times T(-cx, -cy) M=T(cx,cy)×R(θ)×T(−cx,−cy) 展开后: \[ cos ⁡ ( θ ) − sin ⁡ ( θ ) c x × ( 1 − cos ⁡ ( θ ) ) + c y × sin ⁡ ( θ ) sin ⁡ ( θ ) cos ⁡ ( θ ) c y × ( 1 − cos ⁡ ( θ ) ) − c x × sin ⁡ ( θ ) 0 0 1 \] \\begin{bmatrix} \\cos(\\theta) \& -\\sin(\\theta) \& cx \\times (1-\\cos(\\theta)) + cy \\times \\sin(\\theta) \\\\ \\sin(\\theta) \& \\cos(\\theta) \& cy \\times (1-\\cos(\\theta)) - cx \\times \\sin(\\theta) \\\\ 0 \& 0 \& 1 \\end{bmatrix} cos(θ)sin(θ)0−sin(θ)cos(θ)0cx×(1−cos(θ))+cy×sin(θ)cy×(1−cos(θ))−cx×sin(θ)1 #### 6.5 旋转变换算法流程 **算法**: RotateImage **输入** : 图像 I I I, 旋转角度 angle \\text{angle} angle (度), 旋转中心 ( c x , c y ) (cx, cy) (cx,cy) **输出** : 旋转后的图像 I ′ I' I′ ①. 将角度转为弧度: θ = angle × π / 180 \\theta = \\text{angle} \\times \\pi / 180 θ=angle×π/180 ②. 计算旋转矩阵: cos ⁡ θ = cos ⁡ ( θ ) \\cos_\\theta = \\cos(\\theta) cosθ=cos(θ) sin ⁡ θ = sin ⁡ ( θ ) \\sin_\\theta = \\sin(\\theta) sinθ=sin(θ) $$M = \\begin{bmatrix} \\cos_\\theta \& -\\sin_\\theta \& cx \\times (1-\\cos_\\theta) + cy \\times \\sin_\\theta \\ \\sin_\\theta \& \\cos_\\theta \& cy \\times (1-\\cos_\\theta) - cx \\times \\sin_\\theta \\end{bmatrix}$$ ③. 应用仿射变换: I ′ = WarpAffine ( I , M ) I' = \\text{WarpAffine}(I, M) I′=WarpAffine(I,M) 使用双线性插值采样 ④. 返回 I ′ I' I′ **OpenCV实现**: # 获取旋转矩阵 M = cv2.getRotationMatrix2D(center=(cx, cy), angle=angle, scale=1.0) # 应用仿射变换 I' = cv2.warpAffine(I, M, (width, height)) #### 6.6 倾斜变换(Skew/Shear) ### **水平倾斜** 的数学公式: x ′ = x + tan ⁡ ( θ ) × y y ′ = y \\begin{aligned} x' \&= x + \\tan(\\theta) \\times y \\\\ y' \&= y \\end{aligned} x′y′=x+tan(θ)×y=y **变换矩阵** : \[ 1 tan ⁡ ( θ ) 0 0 1 0 0 0 1 \] \\begin{bmatrix} 1 \& \\tan(\\theta) \& 0 \\\\ 0 \& 1 \& 0 \\\\ 0 \& 0 \& 1 \\end{bmatrix} 100tan(θ)10001 ### 七、算法实现的核心思想 #### 7.1 像素级操作(Point Operations) **特点**:输出像素仅依赖于输入像素自身的值 I ′ \[ i , j \] = f ( I \[ i , j \] ) I'\[i,j\] = f(I\[i,j\]) I′\[i,j\]=f(I\[i,j\]) **本文涉及的操作**: * 亮度调整: f ( x ) = x + Δ f(x) = x + \\Delta f(x)=x+Δ * 对比度调整: f ( x ) = x × factor f(x) = x \\times \\text{factor} f(x)=x×factor * 饱和度调整:在HSV空间对S通道缩放 * 自动颜色:每通道乘以校正因子 * 二值化:阈值判断 **优势**: * 计算简单,可并行化 * 不需要访问邻域像素 #### 7.2 坐标变换(Geometric Transformations) **特点**:改变像素的空间位置 I ′ \[ x , y \] = I \[ T ( x , y ) \] I'\[x,y\] = I\[T(x,y)\] I′\[x,y\]=I\[T(x,y)

本文涉及的操作

  • 缩放: T ( x , y ) = ( s x × x , s y × y ) T(x,y) = (s_x \times x, s_y \times y) T(x,y)=(sx×x,sy×y)
  • 平移: T ( x , y ) = ( x + t x , y + t y ) T(x,y) = (x + t_x, y + t_y) T(x,y)=(x+tx,y+ty)
  • 旋转: T ( x , y ) T(x,y) T(x,y) 由旋转矩阵计算

关键问题

  1. 正向映射 vs 逆向映射

    • 正向:从源像素计算目标位置 → 可能产生空洞
    • 逆向:从目标像素反算源位置 → 保证每个像素都有值(推荐)
  2. 插值

    • 当反算的源位置不是整数时,需要插值
    • 常用:最近邻、双线性、双三次

八、扩展阅读

8.1 相关算法

  • 直方图均衡化:自动增强对比度的另一种方法
  • Gamma校正:非线性亮度调整
  • 白平衡:更高级的颜色校正
  • 色调映射:HDR图像的压缩

8.2 性能优化技巧

向量化操作

  • 使用NumPy进行批量运算,避免Python循环
  • 示例:I' = np.clip(I + 50, 0, 255)

OpenCV内置函数

  • cv2.normalize() 比手动实现更快
  • cv2.cvtColor() 高度优化的颜色空间转换

10.3 参考文献

  1. Gonzalez, R. C., & Woods, R. E. (2018). Digital Image Processing (4th ed.). Pearson.
  2. OpenCV Documentation. https://docs.opencv.org/
  3. NumPy Documentation. https://numpy.org/doc/

结语

本文介绍了图像处理的基础运算:

  • 亮度、对比度、饱和度:最基本的像素级操作
  • 自动颜色校正:让图像"自动变好看"的算法
  • 二值化与灰度化:图像分割与简化的基础
  • 几何变换:缩放、平移、旋转的矩阵表示

这些看似简单的操作,是理解所有高级滤镜的基石 。在下一篇文章中,我们将深入探讨图像中的数学原理------矩阵运算、卷积与微分运算,解锁模糊、锐化、边缘检测等更强大的技术。


系列文章导航

标签图像处理 像素操作 亮度调整 对比度 饱和度 二值化 几何变换 仿射变换 Python OpenCV


本文是"图像特效与滤镜技术"系列的第1篇。所有算法都基于Python+OpenCV+NumPy实现,完整代码开源在GitHub。

相关推荐
test_sikao2 小时前
MogFace人脸检测模型-WebUIAI应用:对接美颜SDK前的人脸坐标精准提取
图像处理·人脸检测·ai应用
ComputerInBook20 小时前
数字图像处理(4版)——第 8 章——图像压缩与水印(下)(Rafael C.Gonzalez&Richard E. Woods)
图像处理·计算机视觉·图像压缩·图像水印
weixin_408099671 天前
身份证OCR识别如何做到99.9%准确率?揭秘石榴智能六大核心技术(矫正/完整度/翻拍检测/头像提取)
图像处理·人工智能·ocr·api接口·身份证识别·石榴智能
yuan199971 天前
PCA源码与可见光-红外图像融合MATLAB实现
图像处理·计算机视觉·matlab
sali-tec1 天前
C# 基于OpenCv的视觉工作流-章60-点点距离
图像处理·人工智能·opencv·算法·计算机视觉
sali-tec2 天前
C# 基于OpenCv的视觉工作流-章59-九点标定
图像处理·人工智能·opencv·计算机视觉
大学生小郑2 天前
CMOS 传感器堆叠结构
图像处理·学习·音视频·视频
sali-tec3 天前
C# 基于OpenCv的视觉工作流-章58-相机标定
图像处理·人工智能·数码相机·opencv·算法·计算机视觉
sali-tec4 天前
C# 基于OpenCv的视觉工作流-章57-人脸识别
图像处理·人工智能·opencv·算法·计算机视觉