实验二 图像直方图及灰度变换(Python实现)

实验二 图像直方图及灰度变换(Python实现),第1张


一、实验目的与要求 1.掌握图像灰度直方图的概念及其计算方法,编写灰度直方图统计程序。


2.通过对图像直方图的分析,学习应用直方图法解决图像二值化等具体问题。


3.熟悉直方图均衡化的计算过程及其应用。


4.掌握图像灰度变换技术,通过调整图像对比度和亮度等参数,改善视觉效果。



二、实验内容

  1. 编写一个图像灰度直方图统计函数 my_imhist,选择一幅图像利用 my_imhist 显示其直方图,将结果与 MATLAB 图像处理工具箱中提供的灰度直方图函数 imhist 的处理结果进行比较,并在同一窗口中显示出来。


  2. 利用以上编写的函数 my_imhist 或 imhist,估算图像 iris.tif 中瞳孔 的半径(以像素为单位)。


  3. 按照教材 70 页上的公式(4.1.6)

    编程实现图像的分段线性灰度变换
  4. 编写一个灰度图像的直方图均衡化函数(不可使用库函数)。


    (可使用的灰度等级数量不变即可),并对下图例题进行测试,给出测试结果。



三、实验图像(可使用其他自选图像)







 


四、实验源程序及结果截图


首先,在Python脚本文件中导入以下库:
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv

如果cv2提示不存在则需要安装


1、编写一个图像灰度直方图统计函数 my_imhist,选择一幅图像利用 my_imhist 显示其直方图,将结果与 MATLAB 图像处理工具箱中提供的灰度直方图函数 imhist 的处理结果进行比较,并在同一窗口中显示出来。


def my_imhist(img):
    """
    根据图像绘制直方图
    """
    h, w = img.shape  # 获取图像的高与宽
    hist = [0] * 256  # 首先各灰度频数都置为0
    for i in range(h):
        for j in range(w):
            hist[img[i, j]] += 1
    return hist


src = cv.imread("eye.png", 0)  # 以灰度图像读入
img = src.copy()

plt.subplot(211)
plt.bar(range(256), my_imhist(img), width=1)
plt.title("自己绘制的直方图")
plt.subplot(212)
plt.hist(img.ravel(), 255, [0, 255])
plt.title("python库绘制的直方图")
plt.tight_layout()
plt.show()

2、利用以上编写的函数 my_imhist 或 imhist,估算图像 iris.tif 中瞳孔的半径(以像素为单位)。


src = cv.imread("eye.png", 0)  # 以灰度图像读入
img = src.copy()
# 找出最小像素值
myArray = np.array(my_imhist(img))
min_pixel = my_imhist(img)[np.argmax(myArray > 0)]  # 找到列表中第一个非0 的数
# 根据像素数量算出半径
h, w = img.shape
count = 0
for i in range(h * w):
    if img.ravel()[i] - min_pixel < 20:
        count += 1
print("瞳孔半径为:", np.sqrt(count / np.pi), "个像素值")

(my_imhist函数参照第一题)

3、按照教材 68 页上的公式(4.1.6)

编程实现图像的分段线性灰度变换

src = cv.imread("child.png", 0)
img = src.copy()
a, b, c, d, max_g = 100, 160, 30, 170, 220
h, w = img.shape
max_f = max(img.ravel())
for i in range(h):
    for j in range(w):
        if 0 <= img[i, j] < a:
            img[i, j] = c / a * img[i, j]
        if a <= img[i, j] < b:
            img[i, j] = ((d - c) / (b - a)) * (img[i, j] - a) + c
        if b <= img[i, j] < max_f:
            img[i, j] = ((max_g - d) / (max_f - b)) * (img[i, j] - b) + d
plt.subplot(121)
plt.title("原图")
plt.imshow(src, cmap=plt.cm.gray)
plt.subplot(122)
plt.title("灰度变换后图像")
plt.imshow(img, cmap=plt.cm.gray)
plt.show()

4、编写一个灰度图像的直方图均衡化函数(不可使用库函数)。


(可使用的灰度等级数量不变即可),并对下图例题进行测试,给出测试结果。


my_data = np.loadtxt("data.txt")
print(np.array(my_data))
bins = 8

n = my_data.shape[0]
r_k = list(range(0, bins))
n_k = [0] * bins
p_r = []
s_k_计 = []
s_k_并 = [0] * bins
new = [[0 for col in range(n)] for row in range(n)]

for i in range(n * n):
    n_k[int(my_data.ravel()[i])] += 1
for i in range(bins):
    p_r.append(round(n_k[i] / (n * n), 4))
for i in range(bins):
    s_k_计.append(round(sum(p_r[:(i + 1)]), 4))

temp = []
for i in range(bins):
    temp.append(round(i / n, 4))
for i in range(len(s_k_计)):
    minSub = 1
    for j in range(len(s_k_计)):
        sub = abs(s_k_计[i] - temp[j])
        if sub < minSub:
            minSub = sub
            s_k_并[i] = j

for i in range(n):
    for j in range(n):
        new[i][j] = s_k_并[int(my_data[i][j])]
print('均衡化后的矩阵:\n', np.array(new))

                             

注:data.txt文件按照此格式输入即可,或者直接将矩阵写进代码



注:

1.官方绘制的直方图也可以直接使用 cv2 中的函数 calHist() ,详见文章:
python+OpenCv笔记(十二):直方图(灰度直方图、掩膜的应用、直方图均衡化、自适应直方图均衡化)https://blog.csdn.net/qq_45832961/article/details/122374068结果图为:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/570135.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存