概述
读取图像,使用
HSV
text{HSV}
HSV表示色彩的图像的色相反转。
Author: Tian YJ
原图如下:
关于HSV
HSV text{HSV} HSV即使用色相(Hue)、饱和度(Saturation)、明度(Value)来表示色彩的一种方式。
-
色相:将颜色使用 0 ∘ 0^{circ} 0∘到 36 0 ∘ 360^{circ} 360∘表示,就是平常所说的颜色名称,如红色、蓝色。色相与数值按下表对应:
红 黄 绿 青色 蓝色 品红 红 0 ∘ 0^{circ} 0∘ 6 0 ∘ 60^{circ} 60∘ 12 0 ∘ 120^{circ} 120∘ 18 0 ∘ 180^{circ} 180∘ 24 0 ∘ 240^{circ} 240∘ 30 0 ∘ 300^{circ} 300∘ 36 0 ∘ 360^{circ} 360∘ -
饱和度:是指色彩的纯度,饱和度越低则颜色越黯淡( 0 ≤ S < 1 0leq S < 1 0≤S<1);
-
明度:即颜色的明暗程度。数值越高越接近白色,数值越低越接近黑色( 0 ≤ V < 1 0leq V < 1 0≤V<1);
从 RGB text{RGB} RGB色彩表示转换到 HSV text{HSV} HSV色彩表示通过以下方式计算:
RGB
text{RGB}
RGB的取值范围为
[
0
,
1
]
[0, 1]
[0,1],令:
Max
=
max
(
R
,
G
,
B
)
Min
=
min
(
R
,
G
,
B
)
text{Max}=max(R,G,B)\ text{Min}=min(R,G,B)
Max=max(R,G,B)Min=min(R,G,B)
色相:
H
=
{
0
(
if Min
=
Max
)
60
G
−
R
Max
−
Min
+
60
(
if Min
=
B
)
60
B
−
G
Max
−
Min
+
180
(
if Min
=
R
)
60
R
−
B
Max
−
Min
+
300
(
if Min
=
G
)
H=begin{cases} 0&(text{if} text{Min}=text{Max})\ 60 frac{G-R}{text{Max}-text{Min}}+60&(text{if} text{Min}=B)\ 60 frac{B-G}{text{Max}-text{Min}}+180&(text{if} text{Min}=R)\ 60 frac{R-B}{text{Max}-text{Min}}+300&(text{if} text{Min}=G) end{cases}
H=⎩⎪⎪⎪⎨⎪⎪⎪⎧060 Max−MinG−R+6060 Max−MinB−G+18060 Max−MinR−B+300(if Min=Max)(if Min=B)(if Min=R)(if Min=G)
饱和度:
S
=
Max
−
Min
S=text{Max}-text{Min}
S=Max−Min
明度:
V
=
Max
V=text{Max}
V=Max
从
HSV
text{HSV}
HSV色彩表示转换到
RGB
text{RGB}
RGB色彩表示通过以下方式计算:
C
=
S
H
′
=
H
60
X
=
C
(
1
−
∣
H
′
m
o
d
2
−
1
∣
)
(
R
,
G
,
B
)
=
(
V
−
C
)
(
1
,
1
,
1
)
+
{
(
C
,
X
,
0
)
(
if
0
≤
H
′
<
1
)
(
X
,
C
,
0
)
(
if
1
≤
H
′
<
2
)
(
0
,
C
,
X
)
(
if
2
≤
H
′
<
3
)
(
0
,
X
,
C
)
(
if
3
≤
H
′
<
4
)
(
X
,
0
,
C
)
(
if
4
≤
H
′
<
5
)
(
C
,
0
,
X
)
(
if
5
≤
H
′
<
6
)
C = S\ H' = frac{H}{60}\ X = C (1 - |H' mod 2 - 1|)\ (R,G,B)=(V-C) (1,1,1)+begin{cases} (C, X, 0)& (text{if}quad 0 leq H' < 1)\ (X, C, 0)& (text{if}quad 1 leq H' < 2)\ (0, C, X)& (text{if}quad 2 leq H' < 3)\ (0, X, C)& (text{if}quad 3 leq H' < 4)\ (X, 0, C)& (text{if}quad 4 leq H' < 5)\ (C, 0, X)& (text{if}quad 5 leq H' < 6) end{cases}
C=SH′=60HX=C (1−∣H′mod2−1∣)(R,G,B)=(V−C) (1,1,1)+⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧(C,X,0)(X,C,0)(0,C,X)(0,X,C)(X,0,C)(C,0,X)(if0≤H′<1)(if1≤H′<2)(if2≤H′<3)(if3≤H′<4)(if4≤H′<5)(if5≤H′<6)
这里将实现将色相反转(色相值加
180
180
180),然后再用
RGB
text{RGB}
RGB色彩空间表示图片。
代码实现
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 7 22:12:41 2020
@author: Tian YJ
"""
import cv2
import numpy as np
# RGB --> HSV
def RGB2HSV(img_):
img = img_.copy() / 255 # 进行归一化
hsv = np.zeros_like(img, dtype = np.float32) # HSV初始化
# 求取每一像素在不同通道的最大值Max与最小值Min
Max = np.max(img, axis=2).copy()
Min = np.min(img, axis=2).copy()
# 找出最小值位于哪一通道
Min_arg = np.argmin(img, axis=2)
### 求色相H
hsv[...,0][np.where(Max==Min)] = 0
# 当Min位于B通道时
index = np.where(Min_arg == 0)
hsv[...,0][index] = 60*(img[...,1][index]-img[...,2][index])/(Max[index]-Min[index])+60
# 当Min位于G通道时
index = np.where(Min_arg == 1)
hsv[...,0][index] = 60*(img[...,2][index]-img[...,0][index])/(Max[index]-Min[index])+300
# 当Min位于R通道时
index = np.where(Min_arg == 2)
hsv[...,0][index] = 60*(img[...,0][index]-img[...,1][index])/(Max[index]-Min[index])+180
### 求饱和度S
hsv[...,1] = Max.copy() - Min.copy()
### 求明度V
hsv[...,2] = Max.copy()
return hsv
# HSV --> RGB
def HSV2RGB(img_, hsv):
img = img_.copy() / 255
# 求取每一像素在不同通道的最大值Max与最小值Min
Max = np.max(img, axis=2).copy()
Min = np.min(img, axis=2).copy()
out = np.zeros_like(img, dtype=np.float32)
# 求取HSV分量
H = hsv[...,0]
S = hsv[...,1]
V = hsv[...,2]
# 按公式进行转换
C = S
H_ = H/60
X = C * (1 - np.abs( H_ % 2 - 1))
# 设置中间零矩阵
Z = np.zeros_like(H)
# 公式中是按RGB排列,这里倒过来按BGR排列
temp = [[Z,X,C], [Z,C,X], [X,C,Z], [C,X,Z], [C,Z,X],[X,Z,C]]
for i in range(6):
index = np.where((i<H_ ) & (H_<i+1))
# B通道
out[...,0][index] = (V-C)[index]*1 + temp[i][0][index]
# G通道
out[...,1][index] = (V-C)[index]*1 + temp[i][1][index]
# R通道
out[...,2][index] = (V-C)[index]*1 + temp[i][2][index]
# 防止越界
out = np.clip(out, 0, 1)
# 从归一化后的数值转回真实数值
out = (out*255).astype(np.uint8)
return out
# 读取图片
path = 'C:/Users/86187/Desktop/image/'
file_in = path + 'cake.jpg'
file_out = path + 'HSV_RGB.jpg'
img = cv2.imread(file_in)
# 调用函数RGB-->HSV
hsv = RGB2HSV(img)
# 进行色相反转即将色相值加180
hsv[..., 0] = (hsv[..., 0] + 180) % 360
# 调用函数HSV-->RGB
out = HSV2RGB(img, hsv)
# 保存图片
cv2.imwrite(file_out, out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果展示
原图 | 色相反转 |
---|---|
最后
以上就是故意蚂蚁为你收集整理的挑战图像处理100问(5)——HSV变换及色相反转的全部内容,希望文章能够帮你解决挑战图像处理100问(5)——HSV变换及色相反转所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复