第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 = Ii,j + \Delta I′i,j=Ii,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′
-
将图像转为浮点型(防止溢出): 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 + Δ I'i,j = Ii,j + \Delta I′i,j=Ii,j+Δ
-
裁剪到有效范围: 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′
关键问题:为什么要裁剪(Clip)?
当 I i , j + Δ > 255 Ii,j + \Delta > 255 Ii,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 = Ii,j \times \text{factor} I′i,j=Ii,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 = Ii,j \times \text{factor} I′i,j=Ii,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}(Ii,j \times \text{factor} + \Delta, 0, 255) I′i,j=Clip(Ii,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 = (Ii,j - \text{min\_val}) \times \frac{255}{\text{max\_val} - \text{min\_val}} I′i,j=(Ii,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{Ri,j + Gi,j + Bi,j}{3} Grayi,j=3Ri,j+Gi,j+Bi,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 Ri,j + 0.587 \times Gi,j + 0.114 \times Bi,j Grayi,j=0.299×Ri,j+0.587×Gi,j+0.114×Bi,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 } Ii,j > \text{threshold} \\ 0, & \text{otherwise} \end{cases} I′i,j={255,0,if Ii,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} grayi,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) 时,需要三步:
- 平移到原点:
T(-cx, -cy) - 旋转:
R(θ) - 平移回去:
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(Ii,j) I′i,j=f(Ii,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 = IT(x,y) I′x,y=IT(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) 由旋转矩阵计算
关键问题:
-
正向映射 vs 逆向映射
- 正向:从源像素计算目标位置 → 可能产生空洞
- 逆向:从目标像素反算源位置 → 保证每个像素都有值(推荐)
-
插值
- 当反算的源位置不是整数时,需要插值
- 常用:最近邻、双线性、双三次
八、扩展阅读
8.1 相关算法
- 直方图均衡化:自动增强对比度的另一种方法
- Gamma校正:非线性亮度调整
- 白平衡:更高级的颜色校正
- 色调映射:HDR图像的压缩
8.2 性能优化技巧
向量化操作:
- 使用NumPy进行批量运算,避免Python循环
- 示例:
I' = np.clip(I + 50, 0, 255)
OpenCV内置函数:
cv2.normalize()比手动实现更快cv2.cvtColor()高度优化的颜色空间转换
10.3 参考文献
- Gonzalez, R. C., & Woods, R. E. (2018). Digital Image Processing (4th ed.). Pearson.
- OpenCV Documentation. https://docs.opencv.org/
- NumPy Documentation. https://numpy.org/doc/
结语
本文介绍了图像处理的基础运算:
- ✅ 亮度、对比度、饱和度:最基本的像素级操作
- ✅ 自动颜色校正:让图像"自动变好看"的算法
- ✅ 二值化与灰度化:图像分割与简化的基础
- ✅ 几何变换:缩放、平移、旋转的矩阵表示
这些看似简单的操作,是理解所有高级滤镜的基石 。在下一篇文章中,我们将深入探讨图像中的数学原理------矩阵运算、卷积与微分运算,解锁模糊、锐化、边缘检测等更强大的技术。
系列文章导航:
- 📖 当前位置:第1篇 - 基本运算
- ➡️ 下一篇:第2篇 - 图像中的数学原理
- 🔙 系列首页:总览篇
标签 :图像处理 像素操作 亮度调整 对比度 饱和度 二值化 几何变换 仿射变换 Python OpenCV
本文是"图像特效与滤镜技术"系列的第1篇。所有算法都基于Python+OpenCV+NumPy实现,完整代码开源在GitHub。