在图像处理中,彩色的运用受两个主要因素推动。第一是彩色是一个强有力的描绘子,它常常可以简化场景提取和识别目标;第二是,人可以识别几千种彩色色调和色彩,但是相比较之下只可以辨别几十种灰度色调。第二个因素在人工图像分析中特别重要。
彩色图像处理可以分为两个主要模型:全彩处理和伪彩色处理。
彩色模型也被称之为彩色空间,其目的是在某些标准下用通常可以接受下的方式方便对彩色加以说明。所以本质上,彩色模型就是坐标系统和子空间的说明,其中位于系统中的每种颜色都由单个点表示。
在RGB模型中,每种颜色出现在红、绿、蓝的原色光谱分量中。该模型基于笛卡儿坐标系。所考虑的彩色子空间下图的立方体,图中RGB原色值位于3个角上;二次色青色、深红色和黄色位于另外3个角上,黑色位于原点处,白色位于离原点最远的角上。在该模型中,灰度(RGB值相等的点)沿着连接这两点的直线从黑色延伸到白色。在这一模型中的不同颜色是位于立方体上的或立方体内部的点,且由自原点延伸的向量来定义。
CMY是青、洋红和黄三种颜色的简写,是相减混色模式,用这种方法产生的颜色之所以称为相减色,乃是因为它减少了为视觉系统识别颜色所需要的反射光。CMY和RGB其实是互补的颜色类型。
但是因为CMY所组合的颜色不是纯黑,所以为了产生真正的黑色,我们一般在模型里面加入CMYK的k即代表黑色。
可以从CMY到CMYK 进行变换。
def rgb_cmy(img):
img_norm = normalize(img).astype(np.float32)
img_cmy = 1 - img_norm
return img_cmy
def rgb_cmyk(img):
height, width, channel = img.shape
img_cmy = 1 - normalize(img).astype(np.float32)
img_c = np.zeros((height, width), dtype=np.float32)
img_m = np.zeros((height, width), dtype=np.float32)
img_y = np.zeros((height, width), dtype=np.float32)
img_k = np.zeros((height, width), dtype=np.float32)
for h in range(height):
for w in range(width):
temp = img[h, w]
k = min(temp[0], temp[1], temp[2])
c, m, y = img_cmy[h, w]
if k == 1:
img_c[h, w] = 0
img_m[h, w] = 0
img_y[h, w] = 0
img_k[h, w] = 1
else:
img_c[h, w] = (c - k) / (1 - k)
img_m[h, w] = (m - k) / (1 - k)
img_y[h, w] = (y - k) / (1 - k)
img_k[h, w] = k
img_cmyk = np.dstack((img_c, img_m, img_y, img_k))
img_dst = normalize(img_cmyk)
return img_dst
img_ori = cv2.imread('E:\\picture\\test.png')
img_ori_norm = normalize(img_ori).astype(np.float32)
img_rgb = img_ori_norm[:, :, ::-1]
plt.figure(figsize=(20, 5))
img_cmy = rgb_cmy(img_rgb)
img_cmyk = rgb_cmyk(img_rgb)
plt.subplot(131), plt.imshow(img_rgb, ), plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(132), plt.imshow(img_cmy, ), plt.title('CMY'), plt.xticks([]), plt.yticks([])
plt.subplot(133), plt.imshow(img_cmyk, ), plt.title('CMYK'), plt.xticks([]), plt.yticks([])
plt.tight_layout()
plt.show()
HSI是指一个数字图像的模型,它反映了人的视觉系统感知彩色的方式,以色调、饱和度和亮度三种基本特征量来感知颜色。
RGB和CMY模型无法很好的适应实际上人类解释的颜色,当人观察一个彩色物体时,一般使用色调、饱和度、亮度来描述它,色调是一个纯色的颜色属性,而饱和度是一种纯色被白光稀释的程度的度量。亮度则是一种主观描述,无法被实际度量。从RGB空间到HSI空间的转换,即分别求出HSI参数
从RGB到HSI指数的转换代码如下
img = cv2.imread('E:\\picture\\tupian.png')
img_hsi = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
plt.figure(figsize=(20, 5))
plt.subplot(121), plt.imshow(img, ), plt.title('Original')
plt.subplot(122), plt.imshow(img_hsi, ), plt.title('HSI')
plt.tight_layout()
plt.show()
伪彩色图像处理也叫假彩色图像处理,根据一定的准则对灰度值赋以彩色的处理。
灰度级分层通常用于突出感兴趣的特定灰度范围内的亮度。灰度级分层有两大基本方法。
第一可以是将自己感兴趣的范围赋值,然而其他的不变;第二是可以将自己感兴趣的范围赋值,其他的变为另外一个值。
实现代码如下
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def grayscale_layer(input_image, spotlight_range_min, spotlight_range_max, means):
'''
灰度级分层
:param input_image: 原图像
:param spotlight_range_min: 所突出的灰度级范围最小值
:param spotlight_range_max: 所突出的灰度级范围最大值
:param means: 分层方式(1,2)
:return: 灰度级分层后的图像
'''
input_image_cp = np.copy(input_image) # 输入图像的副本
if means == 1: # 方式一(突出指定范围内255,并且变暗非范围内0)
input_image_cp = np.where((input_image_cp >= spotlight_range_min) & (input_image_cp <= spotlight_range_max), 255, 0)
elif means == 2: # 方式二(仅突出指定范围内255)
input_image_cp[np.where((input_image_cp >= spotlight_range_min) & (input_image_cp <= spotlight_range_max))] = 255
else:
print("please enter the number of means from 1 to 2")
return
output_image = input_image_cp
return output_image.astypetype(np.uint8)
img = cv2.imread(' ')
img = img[:, :, [2, 1, 0]]
plt.figure(dpi = 180)
plt.subplot(131)
plt.imshow(img)
plt.title("原图")
plt.subplot(132)
plt.imshow(output_1)
plt.title("output_1")
plt.subplot(133)
plt.imshow(output_2)
plt.title("output_2")
plt.tight_layout()
plt.show()
相比于前面讨论的简单分层技术,其他类型的变换更加通用,更能拓宽伪彩色增强结果的范围。一种更有吸引力的做法是对任何输入像素的灰度执行三个独立的变换,然后将三个变换结果送入彩色电视监视器的红、绿、蓝通道。这种方法是产生一幅合成图像。如下图所示。
可以有如下代码所实现。
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
img = cv2.imread('', 0)
img = img[:, :, [2, 1, 0]]
im_color = cv2.applyColorMap(img, cv2.COLORMAP_JET)
plt.figure(dpi = 100)
plt.subplot(121)
plt.imshow(img, cmap = "gray")
plt.title("灰度图")
plt.subplot(122)
plt.imshow(im_color)
plt.title("伪彩色图像")
plt.tight_layout()
plt.show()
分割是把一幅图像分成多个区域进行处理。出于连续性的原因,我们会简单介绍彩色分割。
虽然HSI空间的工作更加直观,但是分割这个领域,用RGB彩色向量得到的结果会更加好。这个方法会更加直接。假如我们的目的是在一幅RGB图像中分割某个指定颜色区域的物体。得到的希望分割颜色会用平均估计。
本次目标是将一副图像从rgb颜色空间转换到hsv颜色空间,颜色去除白色背景部分具体就调用了cv2的两个函数,一个是rgb转hsv的函数,另一个是利用cv2.inRange函数设阈值,去除背景部分。
实现代码如下
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def color_seperate(image):
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) #对目标图像进行色彩空间转换
#设定蓝色下限
lower_hsv = np.array([20, 20, 20])
#设定蓝色上限
upper_hsv = np.array([255, 255, 255])
mask = cv2.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv)
dst = cv2.bitwise_and(image, image, mask=mask)
return dst
img = cv2.imread(' ')
out = color_seperate(img)
plt.figure(dpi = 100)
plt.subplot(121)
plt.imshow(img)
plt.title("原图")
plt.subplot(122)
plt.imshow(out)
plt.title("output")
plt.tight_layout()
plt.show()
在图像识别中,需要有边缘鲜明的图像,即图像锐化。图像锐化的目的是为了突出图像的边缘信息,加强图像的轮廓特征,以便于人眼的观察和机器识别。图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。