04 数字图像技术——图像特征提取之实验结果与分析
03 数字图像技术——频域滤波实验结果与分析
02 数字图像技术——颜色空间转换与颜色空间分割实验结果与分析
01 数字图像基本操作——图像采样、量化、算术运算、点运算实验结果及分析
1.了解颜色空间转换与颜色空间分割在数字图像处理中的初步应用。
2.体会颜色空间转换与颜色空间分割的过程和处理前后图像的变化。
1.拆分并显示图像RGB空间的三个通道。
2.RGB空间转换为HSI空间。
3.图像的强度分层。
4.灰度值到彩色变换并画出映射函数。
5.颜色空间分割
电脑、编程语言(Matlab或Python)、图像数据和存储器。
(一)三基色原理
图像是由人的视觉系统接收物体透射或者反射的光学信息,然后在大脑中形成的印象和认识,它其实只是客观存在的多维物体在人脑中的“成像”。
客观存在是不变的,而人的感觉是与周围环境有关的 ,所以人感觉是会变的。
人眼视网膜上存在大量能在适当亮度下分辨颜色的锥状细胞,它们分别对应红、绿、蓝三种颜色,即分别对红光、绿光、蓝光敏感。因此,红(R)、绿(G)、蓝(B)这三种颜色被称为三基色。
在三维直角坐标系中,用相互垂直的三个坐标轴代表R、G、B三个分量,并将R、G、B分别限定在[0,1],则该单位正方体就代表颜色空间,其中的一个点就代表一种颜色。如下图所示,其中,r、g、b、c、m和y分别代表红色(red)、绿色(green)、蓝色(blue)、青色(cyan)、品红(magenta)和黄色(yellow)。
数字图像的本质是一个多维矩阵,如彩色图像是一个三维矩阵,灰度图像和黑白图像由二维矩阵表示。彩色图像一般可分为红、绿、蓝3个颜色通道,每个颜色通道对应一个完整的二维矩阵。可以对这3个二维矩阵进行操作,达到操作图像通道的目的。
国际照明委员会(CIE)于1931年制订了特定波长的三基色标准(RGB)。任一彩色C可表示为:
(二)颜色模型
色度图(国际亮度委员会International Committee on Illumination, CIE)表明定义颜色至少需要3个参数。用3元组(x, y, z)表达一个颜色和在3维空间定义一个点相似,称为颜色空间。
常见颜色空间:
RGB: 显示器、打印机、摄像机
HSI(HSV):人眼识别
CMY:彩色印刷
YUV (YCbCr) :电视信号
1.RGB模型
在三维直角坐标系中,用相互垂直的三个坐标轴代表R、G、B三个分量,并将R、G、B分别限定在[0,1],则该单位正方体就代表颜色空间,其中的一个点就代表一种颜色。如下图所示,其中,r、g、b、c、m和y分别代表红色(red)、绿色(green)、蓝色(blue)、青色(cyan)、品红(magenta)和黄色(yellow)。
与亮度有关:某一色调参入白光,色调不变但饱和度降低
与参入其它颜色的光有关:饱和度与色调都会改变。
HSI模型利用颜色的三个属性色调、饱和度和亮度组成一个表示颜色的圆柱体。
用角度表示,通常0°表示红色,120°表示绿, 240°表示蓝;
3.RGB模型与HSI模型的关系
与RGB从物理和光学角度描述颜色不同, HSI则是根据视觉的主观感觉对颜色进行描述 ;
人眼不能直接感觉红、绿、蓝三色的比例,只能通过感知颜色的亮度、色调和饱和度来区分物体;
在HSI模型中,表征像素彩色信息的两个参数是色度(hue)和饱和度(saturation)。
转换公式
色调和饱和度为图像的固有属性,在图像处理中只对亮度分量进行修改和优化,可以避免由于直接对RGB分量进行处理时产生的图像失真。
4.伪彩色处理
伪彩色处理是把灰度图像的各个不同灰度按照线性或非线性的映射函数变换成不同的彩色,也可以将原来不是图像的数据表示成灰度图像,再转换成彩色图像达到增强的目的。
最简单的实现从灰度到彩色的变换方法可以把灰度图像的灰度级从0(黑)到Mi(白)分成N 个区间,i=1,2,L, N 。给每个区间Ii指定一种色彩Ci。该方法直观简单,缺点是变换出的彩色有限。
从灰度到彩色的一种更具代表性的变换方式是根据色度学的原理,将原图像 f(x,y)的灰度分段经过红、绿、蓝三种不同的变换,变成三基色分量R(x,y) 、G(x,y)、B(x,y),然后用它们去控制彩色显示器的红、绿、蓝电子枪,以产生相应的彩色信号,彩色的含量由变换函数的形状决定。
5.颜色空间分割
图像分割是把图像分成各具特性的区域并提取出感兴趣区域的技术和过程。
基于彩色的图像分割是在颜色空间中进行图像分割,首先观察原始彩色图像的各个分量图像,利用分量图像中感兴趣区域的特征对感兴趣区域进行提取,并弱化背景区域。
HSI颜色空间是面向颜色处理的,用色调H饱和度S描述色彩,用亮度I描述光的强度。HSI模型有两个特点:I 分量与图像的彩色信息无关,H 分量和S 分量与人感受颜色的方式是紧密相连的。
RGB颜色空间中的分割算法是最直接的,得到的分割效果较好。
3.图像的强度分层,步骤流程图如下:
1. 实现拆分并显示图像RGB空间的三个通道的代码。
from skimage import data, io
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
# 读入图像
image=io.imread('cat.jpg')
# 分别取出红、绿、蓝三个颜色通道
image_r = image[:, :, 0]
image_g = image[:, :, 1]
image_b = image[:, :, 2]
# 分别显示3个通道
plt.subplot(2, 2, 1)
io.imshow(image)
plt.title('原始图片')
plt.subplot(2, 2, 2)
io.imshow(image_r)
plt.title('R通道的图片')
plt.subplot(2, 2, 3)
io.imshow(image_g)
plt.title('G通道的图片')
plt.subplot(2, 2, 4)
io.imshow(image_b)
plt.title('B通道的图片')
plt.show()
使用skimage拆分并显示图像RGB空间的三个通道,实验结果如图7所示:
2.实现RGB空间转换为HSI空间的代码。
from skimage import data, io
from matplotlib import pyplot as plt
import math
import numpy as np
import sys
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
# 定义RGB图像转换为HSI图像的函数
def RGB_to_HSI(r, g, b):
r = r / 255
g = g / 255
b = b / 255
num = 0.5 * ((r - g) + (r - b))
den = ((r - g) * (r - g) + (r - b) * (g - b)) ** 0.5
if b <= g:
if den == 0:
den = sys.float_info.min
h = math.acos(num / den)
elif b > g:
if den == 0:
den = sys.float_info.min
h = (2 * math.pi) - math.acos(num / den)
s = 1 - (3 * min(r, g, b) / (r + g + b))
i = (r + g + b) / 3
return int(h), int(s * 100), int(i * 255)
image = io.imread('girl.jpg')
#image = data.coffee()
hsi_image = np.zeros(image.shape, dtype='uint8')
for ii in range(image.shape[0]):
for jj in range(image.shape[1]):
r, g, b = image[ii, jj, :]
h, s, i = RGB_to_HSI(r, g, b)
hsi_image[ii, jj, :] = (h, s, i)
# 显示RGB原图像
plt.subplot(2, 4, 1)
plt.imshow(image)
#plt.axis('off')
plt.title('RGB原图像')
# 显示RGB原图像R分量
plt.subplot(2, 4, 2)
plt.imshow(image[:, :, 0],cmap='gray')
#plt.axis('off')
plt.title('RGB-R分量')
# 显示RGB原图像G分量
plt.subplot(2, 4, 3)
plt.imshow(image[:, :, 1],cmap='gray')
plt.axis('off')
plt.title('RGB-G分量')
# 显示RGB原图像B分量
plt.subplot(2, 4, 4)
plt.imshow(image[:, :, 2],cmap='gray')
plt.axis('off')
plt.title('RGB-B分量')
# 显示HSI原图像
plt.subplot(2, 4, 5)
plt.imshow(hsi_image)
plt.axis('off')
plt.title('HSI图像')
# 显示HSI图像H分量
plt.subplot(2, 4, 6)
plt.imshow(hsi_image[:, :, 0],cmap='gray')
plt.axis('off')
plt.title('HSI-H分量')
# 显示HSI图像S分量
plt.subplot(2, 4, 7)
plt.imshow(hsi_image[:, :, 1],cmap='gray')
plt.axis('off')
plt.title('HSI-S分量')
# 显示HSI图像I分量
plt.subplot(2, 4, 8)
plt.imshow(hsi_image[:, :, 2],cmap='gray')
plt.axis('off')
plt.title('HSI-I分量')
plt.show()
实现RGB空间转换为HSI空间,实验结果如图8所示:
结果分析:为了更好的描述物体颜色,因此需要将原始彩色图像转为HSI颜色模式,而HSI的颜色空间是需要从RGB颜色空间转换成的。因此需要先拆分出RGB图像的三个通道,再根据公式分别计算HSI图像H分量、S分量、I分量。
3. 实现图像的强度分层的代码。
##图像强度分层
from skimage import io,color
from matplotlib import pyplot as plt
import numpy as np
import time
def gray_bin(image_matrix):
initial_conv = np.where((image_matrix < 0.4), 0, 128)
final_conv = np.where((image_matrix >= 0.8), 255, initial_conv)
return final_conv
if __name__ == "__main__":
img = io.imread("cat.jpg")
gray_img = color.rgb2gray(img)
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
plt.subplot(1, 2, 1)
plt.imshow(gray_img, cmap="gray")
plt.title("灰度图像")
rows, cols = gray_img.shape
labels = gray_bin(gray_img)
start_time = time.time()
for i in range(rows):
for j in range(cols):
if(gray_img[i, j] < 0.4):
labels[i, j] = 0
elif(gray_img[i, j] < 0.8):
labels[i, j] = 128
else:
labels[i, j] = 255
end_time = time.time()
print('totally cost :', end_time - start_time)
psd_img = color.label2rgb(labels)
plt.subplot(1, 2, 2)
plt.imshow(psd_img)
plt.title("强度分层图片")
plt.show()
4. 实现灰度值到彩色变换并画出映射函数的代码。
from skimage import data, color,io
from matplotlib import pyplot as plt
import numpy as np
# 定义灰度级到彩色变换
L = 256
def GetR(gray):
if gray < L / 2:
return 0
elif gray > L / 4 * 3:
return L
else:
return 4 * gray - 2 * L
def GetG(gray):
if gray < L / 4:
return 4 * gray
elif gray > L / 4 * 3:
return 4 * L - 4 * gray
else:
return L
def GetB(gray):
if gray < L / 4:
return L
elif gray > L / 2:
return 0
else:
return 2 * L - 4 * gray
if __name__ == "__main__":
img = io.imread("cat.jpg")
grayimg = color.rgb2gray(img) * 255 # 将彩色图像转化为灰度图像
colorimg = np.zeros(img.shape, dtype='uint8')
for ii in range(img.shape[0]):
for jj in range(img.shape[1]):
a = grayimg[ii, jj]
a0 = GetR(a)
a1 = GetG(a)
a2 = GetB(a)
r, g, b = a0, a1, a2
colorimg[ii, jj, :] = (r, g, b)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(1, 2, 1)
plt.axis('off')
plt.imshow(grayimg, cmap='gray')
plt.title('灰度图像')
plt.subplot(1, 2, 2)
plt.axis('off')
plt.imshow(colorimg)
plt.title('伪彩色图像')
plt.savefig('Intensity2Color.tif')
plt.show()
#画出各映射函数
# 设置字体格式
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.size'] = 15
plt.rcParams['axes.unicode_minus'] = False
x = [0, 64, 127, 191, 255]
# 绘制灰度图像到R通道的映射关系
R = []
for i in x:
R.append(GetR(i))
plt.subplot(2, 2, 1)
plt.plot(x, R, 'r', label='红色变换')
plt.legend(loc='best')
# 绘制灰度图像到R通道的映射关系
G = []
for i in x:
G.append(GetG(i))
plt.subplot(2, 2, 2)
plt.plot(x, G, 'g', label='绿色变换')
plt.legend(loc='best')
# 绘制灰度图像到B通道的映射关系
B = []
for i in x:
B.append(GetB(i))
plt.subplot(2, 2, 3)
plt.plot(x, B, 'b', marker='o', markersize='5', label='蓝色变换')
plt.legend(loc='best')
# 绘制灰度图像到RGB的映射关系
plt.subplot(2, 2, 4)
plt.plot(x, R, 'r')
plt.plot(x, G, 'g')
plt.plot(x, B, 'b', marker='o', markersize='5')
plt.show()
5. 实现颜色空间分割的代码。
(1)HSI图像颜色空间分割:
from skimage import data, color, io
from matplotlib import pyplot as plt
import numpy as np
import math
import sys
def RGB_to_HSI(r, g, b):
r = r / 255
g = g / 255
b = b / 255
num = 0.5 * ((r - g) + (r - b))
den = ((r - g) * (r - g) + (r - b) * (g - b)) ** 0.5
if b <= g:
if den == 0:
den = sys.float_info.min
h = math.acos(num / den)
elif b > g:
if den == 0:
den = sys.float_info.min
h = (2 * math.pi) - math.acos(num / den)
s = 1 - (3 * min(r, g, b) / (r + g + b))
i = (r + g + b) / 3
return int(h), int(s * 100), int(i * 255)
if __name__ == "__main__":
image = io.imread("girl.jpg")
hsi_image = np.zeros(image.shape, dtype='uint8')
for ii in range(image.shape[0]):
for jj in range(image.shape[1]):
r, g, b = image[ii, jj, :]
h, s, i = RGB_to_HSI(r, g, b)
hsi_image[ii, jj, :] = (h, s, i)
H = hsi_image[:, :, 0]
S = hsi_image[:, :, 1]
I = hsi_image[:, :, 2]
S_template = S > 0.3 * S.max()
F = np.multiply(H, S_template)
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
plt.subplot(2, 3, 1)
plt.axis('off')
plt.imshow(image) # 显示原始RGB图像
plt.title("原始RGB图像")
plt.subplot(2, 3, 2)
plt.axis('off')
plt.imshow(H, cmap="gray") # 显示H分量图像
plt.title("H分量")
plt.subplot(2, 3, 3)
plt.axis('off')
plt.imshow(S, cmap="gray") # 显示S分量图像
plt.title("S分量")
plt.subplot(2, 3, 4)
plt.axis('off')
plt.imshow(I,cmap="gray") # 显示I分量图像
plt.title("I分量")
plt.subplot(2, 3, 5)
plt.axis('off')
plt.imshow(S_template,cmap="gray") # 显示二值饱和图像
plt.title("二值饱和图像")
plt.subplot(2, 3, 6)
plt.axis('off')
plt.imshow(F) # 显示分割结果
plt.title("分割结果")
plt.show()
实现HSI图像颜色空间分割,实验结果如图12所示:
from skimage import data, color, io
from matplotlib import pyplot as plt
import numpy as np
import math
# 中文乱码和坐标轴负号的处理
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
image = io.imread("cat.jpg")
r = image[:, :, 0]
g = image[:, :, 1]
b = image[:, :, 2]
# RGB颜色空间中的分割
# 选择样本区域
r_template = r[128:255, 85:169]
# 计算该区域的彩色点的平均向量a的红色分量
r_template_u = # 计算样本点红色分量的标准差
r_template_d = 0.0
for i in range(r_template.shape[0]):
for j in range(r_template.shape[1]):
r_template_d = r_template_d + (r_template[i, j] - r_template_u) * (r_template[i, j] - r_template_u)
r_template_d = math.sqrt(r_template_d / r_template.shape[0] / r_template.shape[1])
# 寻找符合条件的点,r_cut为红色分割图像
r_cut = np.zeros(r.shape, dtype='uint8')
for i in range(r.shape[0]):
for j in range(r.shape[1]):
if r[i, j] >= (r_template_u - 1.25 * r_template_d) and r[i, j] <= (r_template_u + 1.25 * r_template_d):
r_cut[i, j] = 1
# image_cut为根据红色分割后的RGB图像
image_cut = np.zeros(image.shape, dtype='uint8')
for i in range(r.shape[0]):
for j in range(r.shape[1]):
if r_cut[i, j] == 1:
image_cut[i, j, :] = image[i, j, :]
plt.subplot(2, 3, 1)
plt.axis('off')
plt.imshow(image) # 显示原始图像
plt.title("原始RGB图像")
plt.subplot(2, 3, 2)
plt.axis('off')
plt.imshow(r,cmap='gray') # 显示R图像
plt.title("R图像")
plt.subplot(2, 3, 3)
plt.axis('off')
plt.imshow(g,cmap='gray') # 显示G图像
plt.title("G图像")
plt.subplot(2, 3, 4)
plt.axis('off')
plt.imshow(b,cmap='gray') # 显示B图像
plt.title("B图像")
plt.subplot(2, 3, 5)
plt.axis('off')
plt.imshow(r_cut,cmap='gray') # 显示红色分割图像
plt.title("红色分割图像")
plt.subplot(2, 3, 6)
plt.axis('off')
plt.imshow(image_cut) # 显示分割后的RGB图像
plt.title("分割后的RGB图像")
plt.show()