数字图像处理课程实习——图像的线性变换与直方图变换

Posted 一名测绘导航大学生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数字图像处理课程实习——图像的线性变换与直方图变换相关的知识,希望对你有一定的参考价值。

         本人为测绘相关专业,此文为学习课程数字图像处理所写的实习作业部分内容。想着写了也就写了,不如发出来记录以下,说不定自己以后会用到的时候能来看看。当然大家能够从中学到或借鉴到什么就更好啦。

        本次实验的目标主要是为了深化对图像增强的目的及意义的理解,巩固所学理论知识,掌握直接灰 度变换的图像增强方法,掌握灰度直方图的概念及其计算方法,熟练掌握直方图均衡化的计算过程,学会分析图像直方图。

        本次实验主要完成了对图像进行灰度线性变换并显示,对图像进行直方图均衡化并显示,并将原图直方图、线性变换后的直方图、均衡化后图像的直方图显示出来并进行对比。

下为代码部分:
import cv2
import numpy as np
import matplotlib.pyplot as plt

#线性变换增强图像的函数
def linear_transform(img, low_in=0, high_in=1, low_out=0, high_out=1):
    #参数分别为输入图像,输入图像的归一化后的灰度级最低值与最高值,输出图像的归一化后的灰度级最低值与最高值
    #用assert函数来检验灰度级是否正常,不正常则报错
    assert high_in >= 0 and high_in <= 1 and low_in >= 0 and low_in <= 1
    assert high_out >= 0 and high_out <= 1 and low_out >= 0 and low_out <= 1
    #图像灰度级归一化
    img = img / 255.0
    #创造一个与输入图像大小相同的矩阵,且各元素均为0
    out = np.zeros_like(img)
    #对创新的新矩阵(即输出图像)元素一一赋值
    #用嵌套循环进行元素遍历
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            #将超出范围的灰度值回归到范围边界值
            if img[i, j] < low_in:
                out[i, j] = low_out
            elif img[i, j] > high_in:
                out[i, j] = high_out
            #将处在原图像正常灰度级范围内的像素赋为线性变换后的值
            else:
                 k = (high_out - low_out) / (high_in - low_in)
                 b = (high_in * low_out - low_in * high_out) / (high_in - low_in)
                 out[i, j] = img[i, j] * k + b
    #图像灰度值由归一化后还原回去
    out = out * 255.0
    #返回灰度线性变换的k,b,经灰度线性变换后的图像
    return k, b, out


def main():
    #打开一幅图像
    grayimg = cv2.imread('camera.png', cv2.IMREAD_GRAYSCALE)
    #创建8*8的画布
    plt.figure(figsize=(8, 8))
    #将2*2的原始图像放在第一号位置显示出来
    plt.subplot(2, 2, 1), plt.imshow(grayimg, cmap='gray'), plt.title('original img')
    # 直方图均衡化,得到均衡化后的图像
    H = cv2.equalizeHist(grayimg)
    #将2*2的均衡化后的图像放在第二号位置显示出来
    plt.subplot(2, 2, 2), plt.imshow(H, cmap='gray'), plt.title('after histeq')
    #线性变换 1(将[0-1]灰度映射到[1-0]灰度)并显示图像
    _, _, I1 = linear_transform(grayimg, 0, 1, 1, 0)
    plt.subplot(2, 2, 3), plt.imshow(I1, cmap='gray'), plt.title('after linear transform1')
    # 线性变换 2 (将[0.3-0.7]灰度映射到[0.1-0.9]灰度)并显示图像
    _, _, I2 = linear_transform(grayimg, 0.3, 0.7, 0.1, 0.9)
    plt.subplot(2, 2, 4), plt.imshow(I2, cmap='gray'), plt.title('after linear transform2')
    # 创建8*8的画布以显示各图像直方图
    plt.figure(num=2, figsize=(8, 8))
    #分别显示各图像的直方图(按顺序分别是:原图像的直方图、均衡化后的图像的直方图,线性变换1后的图像的直方图,线性变换2后的图像的直方图)
    plt.subplot(2, 2, 1), plt.hist(grayimg.flatten(), bins=256), plt.title('original hist')
    plt.subplot(2, 2, 2), plt.hist(H.flatten(), bins=256), plt.title('after histeq')
    plt.subplot(2, 2, 3), plt.hist(I1.flatten(), bins=256), plt.title('after linear transform1')
    plt.subplot(2, 2, 4), plt.hist(I2.flatten(), bins=256), plt.title('after linear transform2')

    #显示全部图像和直方图
    plt.show()

if __name__ == '__main__':
    main()

实验分析与日志

(1)只用plt.imshow()无法显示图像,需要添加:plt.show()。原理是plt.imshow()函数负责对图像进行处理,并显示其格式,而plt.show()则是将plt.imshow()处理后的函数显示出来。

(2)使用plt系列函数需要进行导入包操作:import matplotlib.pyplot as plt。matplotlib.pyplot是常用的绘图库,可用于绘制柱状图、饼状图等各种图表。

(3)在创建小图或子图时,注意更改当前位置的参数,否则极易出现多图或表的重叠情况。

此代码实现是在安装配置好opencv及matplotlib.pyplot包后进行的。故需先进行好环境配置。

以上是关于数字图像处理课程实习——图像的线性变换与直方图变换的主要内容,如果未能解决你的问题,请参考以下文章

图像灰度变换:直方图均衡和线性变换

分段线性变换与直方图修正

数字图像处理期末整理

数字图像处理期末整理

数字图像处理习题

数字图像处理的Matlab实现—灰度变换与空间滤波