灰度图、彩色图像直方图均衡化(包含RGB和HSI互转)-《医学图像处理》小作业三-Python代码/Matlab代码

天津中医药大学-20级医学信息工程   教师:王翌   学生:邓集亲

学长我是用的python写的,matlab同样可以参考

实验三:直方图均衡化

作业要求:

  1. 参考“空间域图像增强”和“彩色图像处理”课的内容,对灰度和彩色图片进行直方图均衡化处理,输出均衡化后的图片。
  2. 分别在RGB颜色空间和HSI颜色空间下对彩色图片进行直方图均衡化操作,输出均衡化后的图片,观察并分析两个颜色空间下实验结果的差别。

例子:

例一:直方图均衡化:

例二:HSI颜色空间下的直方图均衡化:

实验图片:

灰度图片直方图均衡化:histeq1.jpg、histeq2.jpg、histeq3.jpg、histeq4.jpg。

彩色图片直方图均衡化:histeqColor.jpg。

再自选其它至少20张图片(包括灰度图片和彩色图片)。

  图像的灰度直方图描述了图像中灰度分布情况, 能够很直观的展示出图像中各个灰度级所占的多少。图像的灰度直方图是灰度级的函数, 描述的是图像中具有该灰度级的像素的个数: 其中, 横坐标是灰度级, 纵坐标是该灰度级出现的率。

  它描述每个灰度级具有的像素个数, 但不包含这些像素在图像中的位置信息。 图像直方图不关心像素所处的空间位置, 因此不受图像旋转和平移变化的影响, 可以作为图像的特征。任何一幅特定的图像都有唯一的直方图与之对应, 但不同的图像可以有相同的直方图。如果一幅图像有两个不相连的区域组成, 并且每个区域的直方图已知, 则整幅图像的直方图是该两个区域的直方图之和。

  直方图均衡化是一种增强图像对比度的方法,其主要思想是将一副图像的直方图分布通过累积分布函数变成近似均匀分布,从而增强图像的对比度。为了将原图像的亮度范围进行扩展, 需要一个映射函数, 将原图像的像素值均衡映射到新直方图中,即累积分布函数。

#导入库
import cv2
import numpy as np
import matplotlib.pyplot as plt
import collections

#直方图均衡化
def histogram_equalization(histogram_e, lut_e, image_e):
    sum_temp = 0
    cf = []
    for i in histogram_e:
        sum_temp += i
        cf.append(sum_temp)
    for i, v in enumerate(lut_e):
        lut_e[i] = int(255.0 * (cf[i] / sum_temp) + 0.5)
    equalization_result = lut_e[image_e]
    return equalization_result

# 计算灰度图的直方图
def draw_histogram(grayscale):
    gray_key = []
    gray_count = []
    gray_result = []
    histogram_gray = list(grayscale.ravel())  # 将多维数组转换成一维数组
    gray = dict(collections.Counter(histogram_gray))  # 统计图像中每个灰度级出现的次数
    gray = sorted(gray.items(), key=lambda item: item[0])  # 根据灰度级大小排序
    for element in gray:
        key = list(element)[0]
        count = list(element)[1]
        gray_key.append(key)
        gray_count.append(count)
    for i in range(0, 256):
        if i in gray_key:
            num = gray_key.index(i)
            gray_result.append(gray_count[num])
        else:
            gray_result.append(0)
    gray_result = np.array(gray_result)
    return gray_result

x = []
for i in range(0, 256):  # 横坐标
    x.append(i)

#读取图像

original = cv2.imread(r'D:\deng\smalljob\ImageSet\histeq1.jpg')
original_gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)   #将图像从RGB颜色空间转换到灰度颜色空间


histogram = draw_histogram(original_gray)  # 直方图转化

plt.bar(x, histogram)  # 绘制原图直方图
plt.savefig('D:/deng/before_histogram.png')
before_histogram=cv2.imread(r'D:\deng\before_histogram.png')

lut = np.zeros(256, dtype=original_gray.dtype)  # 创建空的查找表,返回image类型的用0填充的数组;
result = histogram_equalization(histogram, lut, original_gray)  # 均衡化处理


histogram_equ = draw_histogram(result)  # 直方图转化
plt.bar(x, histogram_equ)  # 绘制处理后图像直方图
plt.savefig('D:/deng/after_histogram.png')
after_histogram=cv2.imread(r'D:\deng\after_histogram.png')

#展示结果
plt.subplot(221),plt.imshow(original,cmap='gray')
plt.title('original')
plt.axis('off')


plt.subplot(222),plt.imshow(before_histogram,cmap='gray')
plt.title('before_histogram')
plt.axis('off')


plt.subplot(223),plt.imshow(result,cmap='gray')
plt.title('result')
plt.axis('off')


plt.subplot(224),plt.imshow(after_histogram,cmap='gray')
plt.title('after_histogram')
plt.axis('off')
plt.show()

运行结果

  以上是处理灰度图,以下是处理彩色图像(RGB颜色模式下)

#导入库
import cv2
import numpy as np
import matplotlib.pyplot as plt
import collections

#直方图均衡化
def histogram_equalization(histogram_e, lut_e, image_e):
    sum_temp = 0
    cf = []
    for i in histogram_e:
        sum_temp += i
        cf.append(sum_temp)
    for i, v in enumerate(lut_e):
        lut_e[i] = int(255.0 * (cf[i] / sum_temp) + 0.5)
    equalization_result = lut_e[image_e]
    return equalization_result

# 计算灰度图的直方图
def draw_histogram(grayscale):
    # 对图像进行通道拆分
    hsi_i = grayscale[:, :, 2]
    color_key = []
    color_count = []
    color_result = []
    histogram_color = list(hsi_i.ravel())  # 将多维数组转换成一维数组
    color = dict(collections.Counter(histogram_color))  # 统计图像中每个亮度级出现的次数
    color = sorted(color.items(), key=lambda item: item[0])  # 根据亮度级大小排序
    for element in color:
        key = list(element)[0]
        count = list(element)[1]
        color_key.append(key)
        color_count.append(count)
    for i in range(0, 256):
        if i in color_key:
            num = color_key.index(i)
            color_result.append(color_count[num])
        else:
            color_result.append(0)
    color_result = np.array(color_result)
    return color_result

x = []
for i in range(0, 256):  # 横坐标
    x.append(i)

# 原图及其直方图
origin = cv2.imread(r'D:\deng\smalljob\ImageSet\histeqColor.jpg')
original = cv2.cvtColor(origin,cv2.COLOR_BGR2RGB)

histogram_original = draw_histogram(original)
plt.bar(x, histogram_original)  # 绘制原图直方图
plt.savefig('D:/deng/before_histogram.png')
before_histogram=cv2.imread(r'D:\deng\before_histogram.png')


lut = np.zeros(256, dtype=original.dtype)  # 创建空的查找表
rgb_histogram = histogram_equalization(histogram_original, lut, original)  # 均衡化处理


histogram_rgb_equalization = draw_histogram(rgb_histogram)
plt.bar(x, histogram_rgb_equalization)  # 绘制原图直方图
plt.savefig('D:/deng/rgb_after_histogram.png')
rgb_after_histogram=cv2.imread(r'D:\deng\rgb_after_histogram.png')

#展示结果
plt.subplot(221),plt.imshow(original,cmap='gray')
plt.title('original')
plt.axis('off')


plt.subplot(222),plt.imshow(before_histogram,cmap='gray')
plt.title('before_histogram')
plt.axis('off')


plt.subplot(223),plt.imshow(rgb_histogram,cmap='gray')
plt.title('rgb_histogram')
plt.axis('off')


plt.subplot(224),plt.imshow(rgb_after_histogram,cmap='gray')
plt.title('rgb_after_histogram')
plt.axis('off')

plt.show()

运行结果

 以下是在HSI颜色模式下进行均衡化处理,即先将RGB图像转为HSI图像,再在此基础上进行均衡化,最后将图像转回RGB图像

#导入库
import cv2
import numpy as np
import matplotlib.pyplot as plt
import collections
from numpy import cos, arccos, sqrt, power, pi

def histogram_equalization(histogram_e, lut_e, image_e):
    sum_temp = 0
    cf = []
    for i in histogram_e:
        sum_temp += i
        cf.append(sum_temp)
    for i, v in enumerate(lut_e):
        lut_e[i] = int(255.0 * (cf[i] / sum_temp) + 0.5)
    equalization_result = lut_e[image_e]
    return equalization_result

# 计算灰度图的直方图
def draw_histogram(grayscale):
    # 对图像进行通道拆分
    hsi_i = grayscale[:, :, 2]
    color_key = []
    color_count = []
    color_result = []
    histogram_color = list(hsi_i.ravel())  # 将多维数组转换成一维数组
    color = dict(collections.Counter(histogram_color))  # 统计图像中每个亮度级出现的次数
    color = sorted(color.items(), key=lambda item: item[0])  # 根据亮度级大小排序
    for element in color:
        key = list(element)[0]
        count = list(element)[1]
        color_key.append(key)
        color_count.append(count)
    for i in range(0, 256):
        if i in color_key:
            num = color_key.index(i)
            color_result.append(color_count[num])
        else:
            color_result.append(0)
    color_result = np.array(color_result)
    return color_result

#  HSI转RGB
def hsi_rgb(hsi):
    if hsi.dtype.type == np.uint8:
        hsi = (hsi).astype('float64') / 255.0
    for k in range(hsi.shape[0]):
        for j in range(hsi.shape[1]):
            h, s, i = hsi[k, j, 0], hsi[k, j, 1], hsi[k, j, 2]
            r, g, b = 0, 0, 0
            if 0 <= h < 2/3*pi:
                b = i * (1 - s)
                r = i * (1 + s * cos(h) / cos(pi/3-h))
                g = 3 * i - (b + r)
            elif 2/3*pi <= h < 4/3*pi:
                r = i * (1 - s)
                g = i * (1 + s * cos(h-2/3*pi) / cos(pi - h))
                b = 3 * i - (r + g)
            elif 4/3*pi <= h <= 5/3*pi:
                g = i * (1 - s)
                b = i * (1 + s * cos(h - 4/3*pi) / cos(5/3*pi - h))
                r = 3 * i - (g + b)
            hsi[k, j, 0], hsi[k, j, 1], hsi[k, j, 2] = r, g, b
    return (hsi * 255).astype('uint8')

#  RGB转HSI
def rgb_hsi(rgb):
    # 如果没有归一化处理,则需要进行归一化处理(传入的是[0,255]范围值)
    if rgb.dtype.type == np.uint8:
        rgb = rgb.astype('float64')/255.0
    for i in range(rgb.shape[0]):
        for j in range(rgb.shape[1]):
            r, g, b = rgb[i, j, 0], rgb[i, j, 1], rgb[i, j, 2]
            # 计算h
            num = 0.5 * ((r-g)+(r-b))
            den = sqrt(power(r-g, 2)+(r-b)*(g-b))
            theta = arccos(num/den) if den != 0 else 0
            rgb[i, j, 0] = theta if b <= g else (2*pi-theta)
            # 计算s
            rgb[i, j, 1] = (1 - 3 * min([r, g, b]) / (r+g+b)) if r+g+b != 0 else 0
            # 计算i
            rgb[i, j, 2] = 1 / 3 * (r+g+b)
    return (rgb * 255).astype('uint8')
    
x = []
for i in range(0, 256):  # 横坐标
    x.append(i)

# 原图及其直方图
origin = cv2.imread(r'D:\deng\smalljob\ImageSet\mi.jpg')
original = cv2.cvtColor(origin,cv2.COLOR_BGR2RGB)

histogram_original = draw_histogram(original)
plt.bar(x, histogram_original)  # 绘制原图直方图
plt.savefig('D:/deng/before_histogram.png')
before_histogram=cv2.imread(r'D:\deng\before_histogram.png')

# rgb转hsi
hsi_original = cv2.cvtColor(original, cv2.COLOR_RGB2HSV_FULL)
#hsi_original = rgb_hsi(original)

# hsi在亮度分量上均衡化
histogram_hsi_original = draw_histogram(hsi_original)
plt.bar(x, histogram_hsi_original)  # 绘制直方图
plt.savefig('D:/deng/hsi_before_histogram.png')
hsi_before_histogram=cv2.imread(r'D:\deng\hsi_before_histogram.png')

lut = np.zeros(256, dtype=hsi_original.dtype)  # 创建空的查找表
hsi_histogram = histogram_equalization(histogram_hsi_original, lut, hsi_original)  # 均衡化处理

# hsi转rgb
result=cv2.cvtColor(hsi_histogram,cv2.COLOR_HSV2RGB_FULL)
#result = hsi_rgb(hsi_histogram)

histogram_hsi_equalization = draw_histogram(result)
plt.bar(x, histogram_hsi_equalization)  # 绘制原图直方图
plt.savefig('D:/deng/hsi_after_histogram.png')
hsi_after_histogram=cv2.imread(r'D:\deng\hsi_after_histogram.png')

#展示结果
plt.subplot(321),plt.imshow(original,cmap='gray')
plt.title('original')
plt.axis('off')


plt.subplot(322),plt.imshow(before_histogram,cmap='gray')
plt.title('before_histogram')
plt.axis('off')


plt.subplot(323),plt.imshow(hsi_original,cmap='gray')
plt.title('hsi_original')
plt.axis('off')


plt.subplot(324),plt.imshow(hsi_before_histogram,cmap='gray')
plt.title('hsi_before_histogram')
plt.axis('off')


plt.subplot(325),plt.imshow(result,cmap='gray')
plt.title('hsi_histogram')
plt.axis('off')


plt.subplot(326),plt.imshow(hsi_after_histogram,cmap='gray')
plt.title('hsi_after_histogram')
plt.axis('off')

plt.show()

运行结果(图像出现绿色是因为在转换过程中出现了信息失真)

 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Python中进行彩色图像直方图均衡化,可以采用以下步骤: 1. 将彩色图像转换为HSI(Hue, Saturation, Intensity)模型。可以使用OpenCV库中的cvtColor()函数将RGB图像转换为HSI图像。HSI模型中的亮度通道(Intensity)对应图像的灰度信息。 2. 对亮度通道进行直方图均衡化。可以使用OpenCV库中的equalizeHist()函数对亮度通道进行直方图均衡化操作。 3. 将处理后的亮度通道与原始的色调(Hue)和饱和度(Saturation)通道组合,得到均衡化后的HSI图像。 4. 将均衡化后的HSI图像转换回RGB模型。可以使用OpenCV库中的cvtColor()函数将HSI图像转换为RGB图像。 下面是一个简单的示例代码: ```python import cv2 # 读取彩色图像 image = cv2.imread('image.jpg') # 将图像转换为HSI模型 hsi_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 提取亮度通道 intensity_channel = hsi_image[:,:,2] # 对亮度通道进行直方图均衡化 equalized_intensity = cv2.equalizeHist(intensity_channel) # 将均衡化后的亮度通道与原始的色调和饱和度通道组合 hsi_image[:,:,2] = equalized_intensity # 将均衡化后的HSI图像转换回RGB模型 equalized_image = cv2.cvtColor(hsi_image, cv2.COLOR_HSV2BGR) # 显示结果 cv2.imshow('Original Image', image) cv2.imshow('Equalized Image', equalized_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的示例代码中,我们首先读取了彩色图像,然后将其转换为HSI模型。接下来,我们提取了亮度通道,对其进行直方图均衡化,然后将处理后的亮度通道与原始的色调和饱和度通道组合,最后将均衡化后的HSI图像转换回RGB模型。最后,我们显示了原始图像和均衡化后的图像。 请注意,上述代码仅为示例,你可以根据自己的需求进行适当的修改和优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [(Python数字图像处理彩色图像处理---色调和彩色校正以及直方图均衡化](https://blog.csdn.net/qq_44926189/article/details/121178739)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [灰度图像和彩色图像直方图均衡化python实现)](https://blog.csdn.net/zhao9428686/article/details/105394328)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值