CV

DIP灰度变换

python实现,教材源自冈萨雷斯第三版,本节内容为灰度变换与空间滤波。

Posted by LJJ on May 16, 2019

灰度变换

灰度变换函数

r,s分别代表处理前后的像素值。包括图像反转、对数变换、幂律变换、分段线性变换函数。

这里要注意对数变换和幂律变换的常数取值,下图分别为对数变换、幂律变换常数变化曲线图。

a.PNG

b.PNG

  • task3_01:对原始数字乳房X射线照片进行图像反转,观察其效果。

代码实现:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r"D:\JupyterStore\zdip\t3_01.tif")

plt.figure("1")
plt.imshow(img)

# 灰度反转 s=L-1-r 图像灰度级范围为[0,L-1]
for i in range(0,img.shape[0]):
    for j in range(0,img.shape[1]):
        img[i][j] = 255 - img[i][j]
        
plt.figure("2")
plt.imshow(img)

实现效果:

a.PNG

b.PNG

实现现象:可以看到,反转后的图片在纹理上更加清晰,这样做的原因是原图灰度分布偏黑色,不怎么好区分,而将图片反转后,色彩也发生了变化,原本黑色的部位变亮了,这样方便对图像内部细节的进一步研究。

  • task3_02:

    使用强度变换的图像增强。该任务的重点是尝试强度转换以增强图像,使用以下相应方法对图片进行增强。

    1. 对数的对数变换(3.2-2)
    2. 幂律变换(3.2-3)

tips:公式如下

  1. 1.PNG

  2. 2.PNG

代码实现:

import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread(r"D:\JupyterStore\zdip\t3_02.tif")

plt.figure("1")
plt.imshow(img)

# 对数变换 这里常数c取了47
img_log = 47*np.log(img + 1)
img_log = np.uint8(img_log + 0.5)
        
plt.figure("2")
plt.imshow(img_log)

# 幂次变换 常数取了 32/0.4
img_gama = 32*np.power(img,0.4)
img_gama = np.uint8(img_gama + 0.5)
plt.figure("3")
plt.imshow(img_gama)

实现效果:依次为原图、对数变换图、幂次变换图

1.PNG

2.PNG

现象观察:可以看到对数和幂次变换的处理效果都不错,这里注意的是常数c和y的取值,不同的值是会产生不同的效果,所选取的值是在多次测试后,人为选定比较好的数据点。

直方图处理

图像灰度直方图类似我们之前task2_01做过的统计。每一灰度级数所占的像素个数n,n/r*c就是归一化后的直方图,其中r,c分别为高宽。rc相乘即为像素总个数。

直方图均衡处理,有:

22.PNG

直方图规定化,有:

1.PNG

其中两个公式分别是:

2.PNG

3.PNG

  • task3_03:编写用于计算图像直方图的程序,实施第直方图均衡技术并对图片进行直方图均衡化。

tips:

  1. 样图采用比较大,1.44MB,处理时间可能久一点。
  2. 从原图到均衡处理后图片的映射需要注意其处理方式。

代码实现:

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
pylab.rcParams['figure.figsize'] = (10.0,6.0)

def histogram_test(img):
    h = img.shape[0]
    w = img.shape[1]
    newImg = np.zeros((h,w,3),np.uint8)
    
    
    sd = np.zeros(256) # 原始图像归一化直方图
    hd = np.zeros(256) #均衡化后图像归一化直方图
    imap = np.zeros(256) # 映射表
    
    for i in range(h):
        for j in range(w):
            sd[img[i][j]] += 1
            
    sd = sd / (h*w)
    
    plt.figure('1')
    plt.subplot(1,2,1)
    plt.imshow(img)
    plt.subplot(1,2,2)
    plt.plot(sd)
    plt.show()
    
    #这里构造的是一个累加,i[0,256],j[0,i]
    for i in range(256):
        for j in range(i + 1):
            imap[i] += sd[j]
        imap[i] = round(imap[i] * 255) # 这里的255代表公式中的L-1
        
    # 进行映射    
    for i in range(h):
        for j in range(w):
            newImg[i][j] = imap[img[i][j]]
            
    for i in range(h):
        for j in range(w):
            hd[newImg[i][j]] += 1
            
    hd = hd / (h*w)
    
    plt.figure('2')
    plt.subplot(1,2,1)
    plt.imshow(newImg)
    plt.subplot(1,2,2)
    plt.plot(hd)
    plt.show()

if __name__ == '__main__':
    img =  cv2.imread(r"D:\JupyterStore\zdip\t3_04.jpeg")
    histogram_test(img)
    

实现效果:

1.PNG

2.PNG

效果观察:可以看到均衡化后的图像直方图较原图像直方图更为均匀,但这幅全景图均衡化的效果并不是很好,图像色彩失真。