伪彩色图像处理


2022-03-09

由于人类可以辨别上千种颜色和强度,却只能辨别几十种灰度,因此进行伪彩色图像处理可以增强人眼对细节的分辨能力,帮助人们更好地观察和分析图像。

伪彩色图像处理主要包括强度分层技术和灰度值到彩色变换技术,这也是我想和大家分享的内容。

先来看看我做的思维导图:

 提醒uu们要注意:灰度图像与彩色图像不是一一对应的关系,它们相互有很多转换方法。

1、强度分层

强度分层也称为灰度分层或灰度分割。将灰度图像按照灰度值范围划分为不同的层级,然后给每个层级赋予不同的颜色,从而增强不同层级的对比度。强度分层技术将灰度图像转换为伪彩色图像,且伪彩色图像的颜色种类数目与强度分层的数目一致。

思考:若图不一样,划分方式是否也不一样?

一种简单强度分层技术的示例代码如下:

【分段显示,方便读者理解以及上机debug】

from skimage import data,color
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
#中文显示函数
def set_Chinese():
    import matplotlib
    matplotlib.rcParams['font.sans-serif']=['SimHei']
    matplotlib.rcParams['axes.unicode_minus']=False
img = data.coffee()
set_Chinese()
grayimg = color.rgb2gray(img)  #将彩色图像转换为灰度图像
fig = plt.figure()
ax1 = fig.add_subplot(331)
ax1.axis('off')
ax1.imshow(grayimg,cmap = 'gray')  #显示灰度图像
rows,cols = grayimg.shape
labels = np.zeros([rows,cols])
ax1.set_title('(a)灰度图像')

for i in range(rows):
    for j in range(cols):
        if (grayimg[i,j] < 0.4):
            labels[i,j] = 0
        elif (grayimg[i,j] < 0.8):
            labels[i,j] = 1
        else:
            labels[i,j] = 2

psdimg = color.label2rgb(labels) #不同的灰度区间采用不同的颜色
ax2 = fig.add_subplot(311)
ax2.axis('off')
ax2.imshow(psdimg)  #显示强度分成图像
ax2.set_title('(b)强度分层图像')

运行结果:

思考:

技术细节上,怎么设置labels来调颜色?

DEFAULT_COLORS=('red','blue','yellow','magenta','green','indigo','darkorange','cyan','pink',yellowgreen')


2.灰度值到彩色变换 

灰度值到彩色变换首先是对任何像素的灰度值进行3个独立的变换,然后将3个变换结果分别作为伪彩色图像的红、绿、蓝通道的亮度值。与强度分层技术相比,灰度值到彩色变换技术更通用。

灰度图像按一种映射关系转换为伪彩色图像的代码如下:

from skimage import data,color
from matplotlib import pyplot as plt
import numpy as np
#中文显示函数
def set_Chinese():
    import matplotlib
    matplotlib.rcParams['font.sans-serif']=['SimHei']
    matplotlib.rcParams['axes.unicode_minus']=False
#定义灰度值到彩色变换
L = 255
def GetR(gray):
    if gray < L / 2:
        return 0
    elif gray > L / 4 * 3:
        return 1
    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
img = data.coffee()
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]):
        r,g,b = GetR(grayimg[ii,jj]), GetG(grayimg[ii,jj]), GetB(grayimg[ii,jj])
        colorimg[ii,jj,:]=(r,g,b)
#显示结果
set_Chinese()
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax1.imshow(grayimg,cmap='gray')  #显示灰度图像
ax1.axis('off')
ax1.set_title('(a)灰度图像')
ax2.imshow(colorimg)   #显示伪彩色图像
ax2.axis('off')
ax2.set_title('(b)伪彩色图像')

 思考:

1、三种变换(红色变换、绿色变换、蓝色变换)函数中,区间长度不是均匀的,那么怎样的对应关系是最好的呢?

2、可以找到一种转换方法,使得伪彩色图像与原图颜色一致吗?

  2.1 要先知道原图的彩色分布

  2.2 探索需要用到什么编程技巧?

    tip1: 求rgb2gray函数的反函数。先发掘出rgb2gray函数做的事情,然后想办法反转过来。


路漫漫其修远兮,吾将上下而求索