彩色模型也称为彩色空间或彩色系统,本质上,彩色模型是坐标系统和子空间的说明,位于系统的每种颜色都由单个点来表示。
在数字图像处理中,有四种主流的彩色模型:
该模型基于三维坐标系(归一化至[0,1]),如图所示:
三原色处于RGB轴角上,二次色深红、青、黄位于两轴组成平面的对角,黑色位于原点处,白色位于离原点最远的地方。RGB空间中,每个像素的比特数称为像素深度,RGB图像由三幅原色的分量构成,每幅具有8个像素深度,则整个RGB图像具有24比特的深度,可以表示 ( 2 8 ) 3 (2^8)^3 (28)3种颜色,彩色立方体如下图所示:
在10进制中,最亮的红色表示为255 G=B=0,16进制中,最亮的红色表示为FF0000。
img[:,:,i] 列表在空间域中,3通道表示 RGB;频率域中,2通道表示实部和虚部
我们知道,青、深红、黄是光的二次色,在人眼中看到的颜色不是物体本身的颜色,而是由光照射到物体上被吸收一部分后反射回来的颜色,例如用白光照射青色的颜料涂覆的表面,该表面不反射红光,所以青色的表面会吸收白光中的红光成分,我们可以得到于RGB的简单关系。(归一化处理)
#RGB2CMY
import cv2 as cv
R,G,B=cv.split(img)
R=R/255.0
G=G/255.0
B=B/255.0
C=1-R
M=1-G
Y=1-B
img001=cv.merge((C,M,Y))
plt.imshow(img001)
plt.show()
色调H(Hue):与光波的波长有关,它表示人的感官对不同颜色的感受,如红色、绿色、蓝色等,它也可表示一定范围的颜色,如暖色、冷色等。
饱和度S(Saturation):表示颜色的纯度,纯光谱色是完全饱和的,加入白光会稀释饱和度。饱和度越大,颜色看起来就会越鲜艳,反之亦然。
亮度I(Intensity):对应成像亮度和图像灰度,是颜色的明亮程度。
HSI颜色模型的双六棱锥表示,I是强度轴,色调H的角度范围为[0,2π],其中,纯红色的角度为0,纯绿色的角度为2π/3,纯蓝色的角度为4π/3。饱和度S是颜色空间任一点距I轴的距离。当然,若用圆表示RGB模型的投影,则HSI色度空间为双圆锥3D表示。
注意: 当强度I=0时,色调H、饱和度S无定义;当S=0时,色调H无定义
如下的图一目了然,垂直轴代表强度,圆边沿代表颜色,‘半径’属于[0,r],代表饱和度。
RGB-HSI:
def RGB2HSV(img):
r,g,b=cv.split(img)
r=r/255.0
g=g/255.0
b=b/255.0
x=img.shape[0]
y=img.shape[1]
h=np.zeros((x,y),np.float32)
s=np.zeros((x,y),np.float32)
v=np.zeros((x,y),np.float32)
for i in range(x):
for j in range(y):
big=max((r[i,j],g[i,j],b[i,j]))
small=min((r[i,j],g[i,j],b[i,j]))
v[i][j]=big
if big==0:
s[i][j]=0
else:
s[i][j]=(big-small)/big
if big==small:
h[i][j]=0
elif big==r[i][j] and g[i][j]>=b[i][j]:
h[i][j]=60*((g[i][j]-b[i][j])/(big-small))
elif big==r[i][j] and g[i][j]<b[i][j]:
h[i][j]=60*((g[i][j]-b[i][j])/(big-small))+360
elif big==g[i][j]:
h[i][j]=60*((b[i][j]-r[i][j])/(big-small))+120
elif big==b[i][j]:
h[i][j]=60*((r[i][j]-g[i][j])/(big-small))+240
out=cv.merge((h,s,v))
return out
img01=RGB2HSV(img)
show(img01)
import math
import cv2
def hsitorgb(hsi_img):
h = int(hsi_img.shape[0])
w = int(hsi_img.shape[1])
H, S, I = cv2.split(hsi_img)
H = H / 255.0
S = S / 255.0
I = I / 255.0
bgr_img = hsi_img.copy()
B, G, R = cv2.split(bgr_img)
for i in range(h):
for j in range(w):
if S[i, j] < 1e-6:
R = I[i, j]
G = I[i, j]
B = I[i, j]
else:
H[i, j] *= 360
if H[i, j] > 0 and H[i, j] <= 120:
B = I[i, j] * (1 - S[i, j])
R = I[i, j] * (1 + (S[i, j] * math.cos(H[i, j]*math.pi/180)) / math.cos((60 - H[i, j])*math.pi/180))
G = 3 * I[i, j] - (R + B)
elif H[i, j] > 120 and H[i, j] <= 240:
H[i, j] = H[i, j] - 120
R = I[i, j] * (1 - S[i, j])
G = I[i, j] * (1 + (S[i, j] * math.cos(H[i, j]*math.pi/180)) / math.cos((60 - H[i, j])*math.pi/180))
B = 3 * I[i, j] - (R + G)
elif H[i, j] > 240 and H[i, j] <= 360:
H[i, j] = H[i, j] - 240
G = I[i, j] * (1 - S[i, j])
B = I[i, j] * (1 + (S[i, j] * math.cos(H[i, j]*math.pi/180)) / math.cos((60 - H[i, j])*math.pi/180))
R = 3 * I[i, j] - (G + B)
out=cv2.merge((R,G,B))
return bgr_img
img05=hsitorgb(img01)
show(img05)
分类:单色图像(灰色黑白)、真彩色图像、伪彩色图像
伪彩色图像处理是根据一定的准则对灰度值赋以彩色的处理
为什么需要伪彩色图像处理?人类可以辨别上千种颜色和强度但是只能辨别二十几种灰度
怎么进行伪彩色图像处理?
强度分层技术
把一幅图像描述为三维函数(x,y,f(x,y))
分层技术:放置平行于(x,y)坐标面的平面
每一个平面在相交区域切割函数图像
定义:令【0,L-1】表示灰度级,使l0代表黑色(f(x,y)=0),lL-1代表白色(f(x,y)=L-1)。假设垂直于强度轴的的P个平面定义为量级l1,l2,l3,…,lp.0
f(x,y)=ck,f(x,y)∈Vk
ck是与强度间隔Vk第K级强度有关的颜色
Vk是由在l=k-1和l=k分隔平面定义的
在病变检测、焊接检测、降雨检测等领域应用广泛。
灰度图转换成伪彩色图像是对像素的灰度执行三个通道,即RGB的变换,再合成一幅彩色图像,提供两种方法。
colormap种类
# COLORMAP_AUTUMN = 0,
# COLORMAP_BONE = 1,
# COLORMAP_JET = 2,
# COLORMAP_WINTER = 3,
# COLORMAP_RAINBOW = 4,
# COLORMAP_OCEAN = 5,
# COLORMAP_SUMMER = 6,
# COLORMAP_SPRING = 7,
# COLORMAP_COOL = 8,
# COLORMAP_HSV = 9,
# COLORMAP_PINK = 10,
# COLORMAP_HOT = 11
cv.cvtColor(img,cv.COLOR_GRAY2RGB)
img=cv.imread('pic/tu',0)
img01=cv.applyColorMap(img,cv.COLORMAP_JET)
show(img01)
img02=cv.cvtColor(img,cv.COLOR_GRAY2RGB)
show(img02)
直接对彩色像素进行处理。因为全彩色图像至少有3个分量,彩色像素实际上是一个向量。直接处理就是同时对所有分量进行无差别的处理.这时彩色图像的 3个分量用向量形式表示,即对彩色图像上任一点的像素 c(x,y)进行处理:
对向量的每个分量的操作对于其他分量必须是独立的。
应用主要有直方图处理,平滑和锐化,我们这里做一下关于锐化的实验。(拉普拉斯矩阵)
使用卷积定义函数cv.filter2D(( InputArray src, OutputArray dst, int ddepth,
InputArray kernel, Point anchor=Point(-1,-1),
double delta=0, int borderType=BORDER_DEFAULT );
InputArray src: 输入图像
OutputArray dst: 输出图像,和输入图像具有相同的尺寸和通道数量
int ddepth: 目标图像深度,如果没写将生成与原图像深度相同的图像。(-1代表深度相同)
InputArray kernel: 卷积核(或者是相关核),一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的kernel,可以先使用split()函数将图像通道事先分开。注意卷积核定义np.array() 只能输入1至2个列表。
Point anchor: 内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点。
double delta: 在储存目标图像前可选的添加到像素的值,默认值为0
int borderType: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
kernel=np.array([[1,1,1],
[1,-7.5,1],
[1,1,1]])
img=cv.imread('pic/house500x500.jpg')
img002=cv.filter2D(img,-1,kernel)
show(np.hstack([img,img002]))
结果如图:达到锐化边缘的效果
三通道分别采用拉普拉斯算子滤波结果:用img[:,:,i]卷积即可。
本章讨论了不同颜色的模型,引入颜色多通道和单通道的概念,进行了模型转换和多通道处理的实验,可以很好地理解彩色图像的本质。