彩色图像处理可分为两个主要领域:全彩色处理和伪彩色处理。
全彩色图像处理通常要求图像用全彩色传感器获取,如彩色电视摄像机或彩色扫描仪。
伪彩色处理是对于一种特定的单色灰度或灰度范围赋予一种颜色。
为标准化目的定义了三原色,他们的波长是:蓝色=435.8nm,绿色=546.1nm,红色=700nm。原色相加可以产生二次色,以正确的亮度把三原色或把与二次色相对应的原色混合,即可产生白光。
用来描述彩色光源的三个基本量是辐射、光强和亮度。如果光是无色的,它的属性仅仅是亮度或者数值,我们就提出了一个定义——灰度级,灰度级仅提供了一个亮度的标量度量,它的范围从黑色到灰色最终到白色。灰度Y=0.299R+0.587G+0.114B
通常以区别不同颜色特性的是亮度、色调和饱和度。
亮度表达了无色的强度概念;
色调是光波混合中与主波长有关的属性,是观察者感知的主要颜色;
饱和度指相对的纯净度或一种颜色混合白光的数量。
色调与饱和度一起称为色度。
每一幅红、绿、蓝图像都是一幅8比特图像,每个像素的比特数称为像素深度。可以说每个RGB彩色像素有24比特的深度,全彩色图像的颜色总数为 (28)3=16777216
输入CMY数据或在内部进行RGB到CMY的转换
[ C M Y ] = [ 1 1 1 ] − [ R G B ] \begin{bmatrix} C \\ M \\ Y\\ \end{bmatrix}=\begin{bmatrix} 1 \\1 \\ 1\\ \end{bmatrix}-\begin{bmatrix} R \\ G \\ B\\ \end{bmatrix} ⎣⎡CMY⎦⎤=⎣⎡111⎦⎤−⎣⎡RGB⎦⎤
这种彩色模型主要用于产生硬拷贝输出,因此CMY到RGB的反向操作通常没有实际意义。
为了生成真正的黑色,加入了第四种颜色——黑色,于是提出了CMYK彩色模型。
HSI模型包括色调、饱和度、强度,它可在彩色图像中从携带的彩色信息(色调和饱和度)中消去强度分量的影响,是开发基于彩色描述的图像处理算法的理想工具。
一种颜色的饱和度(纯度)以强度轴的距离为函数而增大。事实上,强度轴上点的饱和度为零,事实证明沿着这条轴线的所有点都是灰度。
import cv2
import numpy as np
def rgbtohsi(rgb_lwpImg):
rows = int(rgb_lwpImg.shape[0])
cols = int(rgb_lwpImg.shape[1])
b, g, r = cv2.split(rgb_lwpImg)
# 归一化到[0,1]
b = b / 255.0
g = g / 255.0
r = r / 255.0
hsi_lwpImg = rgb_lwpImg.copy()
H, S, I = cv2.split(hsi_lwpImg)
for i in range(rows):
for j in range(cols):
num = 0.5 * ((r[i, j]-g[i, j])+(r[i, j]-b[i, j]))
den = np.sqrt((r[i, j]-g[i, j])**2+(r[i, j]-b[i, j])*(g[i, j]-b[i, j]))
theta = float(np.arccos(num/den))
if den == 0:
H = 0
elif b[i, j] <= g[i, j]:
H = theta
else:
H = 2*3.14169265 - theta
min_RGB = min(min(b[i, j], g[i, j]), r[i, j])
sum = b[i, j]+g[i, j]+r[i, j]
if sum == 0:
S = 0
else:
S = 1 - 3*min_RGB/sum
H = H/(2*3.14159265)
I = sum/3.0
# 输出HSI图像,扩充到255以方便显示,一般H分量在[0,2pi]之间,S和I在[0,1]之间
hsi_lwpImg[i, j, 0] = H*255
hsi_lwpImg[i, j, 1] = S*255
hsi_lwpImg[i, j, 2] = I*255
return hsi_lwpImg
if __name__ == '__main__':
rgb_lwpImg = cv2.imread("C:/Users/13121/Desktop/d.jpg")
hsi_lwpImg = rgbtohsi(rgb_lwpImg)
cv2.imshow('Original', rgb_lwpImg)
cv2.imshow('HSI', hsi_lwpImg)
key = cv2.waitKey(0) & 0xFF
if key == ord('q'):
cv2.destroyAllWindows()
灰度分层和彩色编码技术是伪色彩图像处理的最简单的例子之一。
对平面的每一侧赋以不同的颜色,平面上的任何灰度级的像素将编码成一种彩色,该平面下的任何像素将编码成另一种颜色,位于平面上的灰度级本身被任意赋以两种彩色之一。
import cv2
import imutils
import numpy as np
# 在某一范围(A, B)突出灰度,其他灰度值保持不变
image = cv2.imread('C:/Users/13121/Desktop/d.jpg')
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
r_left, r_right = 150, 230
r_min, r_max = 0, 255
level_img = np.zeros((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
for i in range(gray_img.shape[0]):
for j in range(gray_img.shape[1]):
if r_left <= gray_img[i, j] <= r_right:
level_img[i, j] = r_max
else:
level_img[i, j] = gray_img[i, j]
cv2.imshow('origin image', imutils.resize(image, 480))
cv2.imshow('level image', imutils.resize(level_img, 480))
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
如果所寻找的确切的灰度值或值域是已知的,则灰度分层在可视化方面是简单而有力的辅助手段,特别是涉及大量图像时更是如此。
伪色彩图像处理是指基于一种指定的规则对灰度值赋以颜色的处理,主要应用是人目视观察和解释单幅图像或序列图像中的灰度级事件。
import numpy as np
import cv2
import matplotlib.pyplot as graph
#图片的路径
imgname = "C:/Users/13121/Desktop/2.png"
img1=cv2.imread(imgname)
graph.subplot(121)
graph.xticks([])
graph.yticks([])
graph.imshow(img1)
image = cv2.imread(imgname, cv2.IMREAD_GRAYSCALE)
graph.subplot(122)
graph.xticks([])
graph.yticks([])
graph.imshow(image)
全彩色图像处理方法分为两大类。第一类是分别处理过的分量图像来形成一幅处理过的合成彩色图像;第二类是直接处理彩色像素。
为了使每种色彩分量处理和基于向量的处理等同,必须满足两个条件之一:第一,处理必须对向量和标量都可用;第二,对向量的每一分量的操作对于其他分量必须是独立的。
g ( x , y ) = T [ f ( x , y ) ] g(x,y)=T[f(x,y)] g(x,y)=T[f(x,y)]作为彩色变换的模型,这里 f ( x , y ) f(x,y) f(x,y)是彩色输入图像, g ( x , y ) g(x,y) g(x,y)是变换后或处理过的彩色输出图像, T T T是在 ( x , y ) (x,y) (x,y)的空间邻域上对 f f f的一个算子。
import numpy as np
import cv2
import matplotlib.pyplot as graph
image = cv2.imread("C:/Users/13121/Desktop/d.jpg")
#R、G、B分量的提取
(B,G,R) = cv2.split(image)# 通道分解提取R、G、B分量
BH = cv2.equalizeHist(B) # 对b分量进行均衡化
GH = cv2.blur(G, (5,5)) # 对b分量进行均值滤波化
RH = cv2.medianBlur(R,5)# 对b分量进行中值滤波化
titles = ['Original', 'Red','Green',"Blue"]
images = [image,BH,GH,RH]
for i in range(4):
graph.subplot(1,4,i+1)
graph.imshow(images[i], 'gray')
graph.title(titles[i])
graph.xticks([])
graph.yticks([])
graph.show()
补色:
补色对于增强嵌在彩色图像暗区的细节很有用——特别是区域在大小上不占优势时。
计算的补色使人想到通常照片的彩色底片,补色图像中的每种色调都用彩色环由原图像预测,且涉及补色计算的每个RGB分量变换仅是对应的输入彩色分量的一个函数。
邻域平均平滑可以在每个彩色平面的基础上执行,其结果与使用RGB彩色向量执行平均是相同的。
可以看出平滑处理使得图像变得模糊了。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 显示函数
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread('C:/Users/13121/Desktop/d.jpg')
blur = cv2.blur(img, (5, 5))
res = np.hstack((img, blur))
cv_show('res', res)
可以将低于(或高于)某一阈值的图像部分分割出来。具体内容会在第十章涉及到。
from skimage import io,img_as_ubyte
from skimage.color import rgb2gray
from skimage.morphology import opening,disk
import numpy as np
import matplotlib.pyplot as plt
# 读取彩色图像,并将图像类型设置为8位(0-255)
img = img_as_ubyte(io.imread('C:/Users/13121/Desktop/6.jpg'))
# 转换成灰度图像(类型自动转为0~1或-1~1),并将图像类型设置为8位
img_gray = img_as_ubyte(rgb2gray(img))
# 读取灰度图像的高h和宽w
h,w = img_gray.shape
# print(img_gray)
# 设置阈值
segm1 = (img_gray<80)
# print(segm1)
# 开运算
kernel = disk(10)
img_opening = opening(segm1,kernel)
# 将单通道阈值,转为RGB通道的阈值
segm = np.tile(img_opening.reshape(h,w,1),3)
# 复制一份彩色图像
img1 = img.copy()
# 掩膜操作
img1[segm] = 0
# 显示图像
plt.figure(figsize=(10,8),dpi=80)
plt.subplot(121)
plt.imshow(img)
plt.xlabel("原图像",fontproperties='SimHei')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(img1)
plt.xlabel("阈值分割结果",fontproperties='SimHei')
plt.xticks([])
plt.yticks([])
plt.show()
本章学习的彩色图像处理,首先学习的是彩色模型,在彩色模型中,我们常用到的是RGB颜色模型和HSI颜色模型。HSI模型在后续的图像处理方面用的会更多一点,它能够显示图像的色调、饱和度和强度,可以和图像分割结合在一起,对图像的相应阈值内的部分进行处理。其次学习的伪色彩图像处理,它能够将我们得到的灰度图转换为彩色图像,对于医学方面会有很大的作用,热度图也会有所涉及。