计算机视觉与模式识别实验1-1 图像的直方图平衡

news2025/1/20 20:09:34

文章目录

    • 🧡🧡实验流程🧡🧡
      • 1.读入图像‘rice.png’,在一个窗口中显示灰度级n=64,128和256的图像直方图。
      • 2.调解图像灰度范围,观察变换后的图像及其直方图的变化。
      • 3.分别对图像‘pout.tif’和‘tire.tif’进行直方图均衡化处理,比较处理前后图像及直方图分布的变化。
      • 4.读取一幅彩色图像,对RGB图像的每个通道进行直方图均衡化,对均衡化后进行重新合并成彩色图像,展示不同阶段的图像效果。另将RGB图像转换为HSV图像(rgb2hsv函数),分别对三分量的图像行直方图均衡化,最后合并成新的彩色图像,分析不同阶段的图像效果。
      • 5.自行设计程序实现图像的直方图均衡
    • 🧡🧡所有代码🧡🧡

🧡🧡实验流程🧡🧡

1.读入图像‘rice.png’,在一个窗口中显示灰度级n=64,128和256的图像直方图。

在这里插入图片描述
在这里插入图片描述

2.调解图像灰度范围,观察变换后的图像及其直方图的变化。

在这里插入图片描述

3.分别对图像‘pout.tif’和‘tire.tif’进行直方图均衡化处理,比较处理前后图像及直方图分布的变化。

在这里插入图片描述
在这里插入图片描述

4.读取一幅彩色图像,对RGB图像的每个通道进行直方图均衡化,对均衡化后进行重新合并成彩色图像,展示不同阶段的图像效果。另将RGB图像转换为HSV图像(rgb2hsv函数),分别对三分量的图像行直方图均衡化,最后合并成新的彩色图像,分析不同阶段的图像效果。

如下图,对RGB三个颜色通道进行直方图均衡化后,图像的对比度得到了改善,灰度级的分布更加均匀。
在这里插入图片描述
在这里插入图片描述
如下图,HSV模型是基于人类感知的颜色模型,HSV分别表示色相(Hue)、饱和度(Saturation)和明度(Value),对其均衡化后,增强了图像的对比度和色彩鲜艳度,使得图像更加清晰、生动
在这里插入图片描述
在这里插入图片描述

5.自行设计程序实现图像的直方图均衡

主要思路:
1.统计原始图像的直方图
2.计算直方图累积分布
3.用累积分布函数作变换函数进行图像灰度变换
在这里插入图片描述

🧡🧡所有代码🧡🧡

主要采用opencv库,这里的代码是用jupyter写的。

"""
    1-1、1-2 直方图显示、直方图灰度调节
"""
image = cv2.imread('img/test1_rice.png', cv2.IMREAD_GRAYSCALE)

plt.figure(figsize=(15, 12))

# 显示原始图像和直方图
plt.subplot(3, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image', fontsize=18)
plt.axis('off')

for i, n in enumerate([64, 128, 256]):
    plt.subplot(3, 3, i + 4)
    plt.hist(image.ravel(), bins=n, range=[0, 256], color='b', alpha=0.5)
    plt.title('Histogram (n={})'.format(n), fontsize=18)
    plt.xlabel('Pixel Value', fontsize=16)
    plt.ylabel('Frequency', fontsize=16)

# 使用imadjust函数进行灰度调节
adjusted_image = cv2.convertScaleAbs(image, alpha=1.5, beta=20)

# 显示调节后的图像和直方图
plt.subplot(3, 3, 7)
plt.imshow(adjusted_image, cmap='gray')
plt.title('Adjusted Image', fontsize=18)
plt.axis('off')

plt.subplot(3, 3, 8)
plt.hist(adjusted_image.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Adjusted Histogram', fontsize=18)
plt.xlabel('Pixel Value', fontsize=16)
plt.ylabel('Frequency', fontsize=16)

plt.tight_layout()
plt.show()
"""
    1-3 直方图均衡化
"""

image_pout = cv2.imread('img/test1_pout.png', cv2.IMREAD_GRAYSCALE)
image_tire = cv2.imread('img/test1_tire.png', cv2.IMREAD_GRAYSCALE)

# 直方图均衡化处理
equalized_pout = cv2.equalizeHist(image_pout)
equalized_tire = cv2.equalizeHist(image_tire)

# 绘制处理前后图像及直方图分布的变化
plt.figure(figsize=(12, 8))

# 原始图像及其直方图
plt.subplot(2, 4, 1)
plt.imshow(image_pout, cmap='gray')
plt.title('Original Pout')
plt.axis('off')

plt.subplot(2, 4, 2)
plt.hist(image_pout.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Histogram (Before)')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')

plt.subplot(2, 4, 5)
plt.imshow(image_tire, cmap='gray')
plt.title('Original Tire')
plt.axis('off')

plt.subplot(2, 4, 6)
plt.hist(image_tire.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Histogram (Before)')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')

# 直方图均衡化后图像及其直方图
plt.subplot(2, 4, 3)
plt.imshow(equalized_pout, cmap='gray')
plt.title('Equalized Pout')
plt.axis('off')

plt.subplot(2, 4, 4)
plt.hist(equalized_pout.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Histogram (After)')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')

plt.subplot(2, 4, 7)
plt.imshow(equalized_tire, cmap='gray')
plt.title('Equalized Tire')
plt.axis('off')

plt.subplot(2, 4, 8)
plt.hist(equalized_tire.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Histogram (After)')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')

plt.tight_layout()
plt.show()
"""
    1-4 RGB和HSV均衡化
"""

image = cv2.imread('img/test1_LenaRGB.tif')

# 处理RGB图像
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # opencv是BGR,  imshow是RGB
r_channel, g_channel, b_channel = cv2.split(image_rgb)
r_equalized = cv2.equalizeHist(r_channel)
g_equalized = cv2.equalizeHist(g_channel)
b_equalized = cv2.equalizeHist(b_channel)
equalized_image = cv2.merge((r_equalized, g_equalized, b_equalized))

plt.figure(figsize=(18, 20))

plt.subplot(4, 2, 1)
plt.imshow(image_rgb)
plt.title('Original Channels', fontsize=18)
plt.axis('off')

plt.subplot(4, 2, 2)
plt.imshow(cv2.merge((r_equalized, g_equalized, b_equalized)))
plt.title('Equalized Channels', fontsize=18)
plt.axis('off')

plt.subplot(4, 2, 3)
plt.hist(r_channel.ravel(), bins=256, range=[0, 256], color='r', alpha=0.5)
plt.hist(g_channel.ravel(), bins=256, range=[0, 256], color='g', alpha=0.5)
plt.hist(b_channel.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Histogram (Before Equalization)', fontsize=18)
plt.xlabel('Pixel Value', fontsize=18)
plt.ylabel('Frequency', fontsize=18)

plt.subplot(4, 2, 4)
plt.hist(r_equalized.ravel(), bins=256, range=[0, 256], color='r', alpha=0.5)
plt.hist(g_equalized.ravel(), bins=256, range=[0, 256], color='g', alpha=0.5)
plt.hist(b_equalized.ravel(), bins=256, range=[0, 256], color='b', alpha=0.5)
plt.title('Histogram (After Equalization)', fontsize=18)
plt.xlabel('Pixel Value', fontsize=18)
plt.ylabel('Frequency', fontsize=18)

# 处理HSV图像
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h_channel, s_channel, v_channel = cv2.split(hsv_image)
equalized_h_channel = cv2.equalizeHist(h_channel)
equalized_s_channel = cv2.equalizeHist(s_channel)
equalized_v_channel = cv2.equalizeHist(v_channel)
equalized_hsv_image = cv2.merge((equalized_h_channel, equalized_s_channel, equalized_v_channel))
equalized_rgb_image = cv2.cvtColor(equalized_hsv_image, cv2.COLOR_HSV2RGB)

plt.subplot(4, 2, 5)
plt.imshow(hsv_image)
plt.title('Original HSV Channels', fontsize=18)
plt.axis('off')

plt.subplot(4, 2, 6)
plt.imshow(equalized_rgb_image)
plt.title('Equalized HSV Channels', fontsize=18)
plt.axis('off')

plt.subplot(4, 2, 7)
plt.hist(h_channel.ravel(), bins=256, range=[0, 256], alpha=0.5)
plt.hist(s_channel.ravel(), bins=256, range=[0, 256], alpha=0.5)
plt.hist(v_channel.ravel(), bins=256, range=[0, 256], alpha=0.5)
plt.title('Histogram (After Equalization)', fontsize=18)
plt.xlabel('Pixel Value', fontsize=18)
plt.ylabel('Frequency', fontsize=18)

plt.subplot(4, 2, 8)
plt.hist(equalized_h_channel.ravel(), bins=256, range=[0, 256], alpha=0.5)
plt.hist(equalized_s_channel.ravel(), bins=256, range=[0, 256], alpha=0.5)
plt.hist(equalized_v_channel.ravel(), bins=256, range=[0, 256], alpha=0.5)
plt.title('Histogram (After Equalization)', fontsize=18)
plt.xlabel('Pixel Value', fontsize=18)
plt.ylabel('Frequency', fontsize=18)


plt.tight_layout()
plt.show()
"""
    1-5 手写直方图均衡化
"""

#建立原始图像各灰度级的灰度值与像素个数对应表
def Origin_histogram( img ):
#     print(img.shape)
    histogram = {}
    for i in range( img.shape[0] ):
        for j in range( img.shape[1] ):
            k = img[i][j]
            if k in histogram:
                histogram[k] += 1
            else:
                histogram[k] = 1
                
    sorted_histogram = {}#建立排好序的映射表
    sorted_list = sorted( histogram )#根据灰度值进行从低至高的排序
    
    for j in range( len( sorted_list ) ):
        sorted_histogram[ sorted_list[j] ] = histogram[ sorted_list[j] ]

    return sorted_histogram

def equalization_histogram( histogram, img ):
#     print(histogram)
    pr = {} #建立概率分布映射表
    for i in histogram.keys():
        pr[i] = histogram[i] / ( img.shape[0] * img.shape[1] ) 

    # 计算累计分布(变换函数)
    tmp = 0
    for m in pr.keys():
        tmp += pr[m]
        pr[m] =  max( histogram ) * tmp
#     print(pr)
    
    # 将原图像每一点都进行变换
    new_img = np.zeros( shape = ( img.shape[0], img.shape[1] ), dtype = np.uint8 )
    for k in range( img.shape[0] ):
        for l in range( img.shape[1] ):
            new_img[k][l] = pr[img[k][l]]

    return new_img

# 计算灰度直方图
def GrayHist( img ):
    height, width = img.shape
    grayHist = np.zeros([256], np.uint64)
    for i in range(height):
        for j in range(width):
            grayHist[img[i][j]] += 1
    return grayHist

img = cv2.imread( 'img/test1_pout.png', cv2.IMREAD_GRAYSCALE )
# 计算原图灰度直方图
origin_histogram = Origin_histogram( img )
# 直方图均衡化
new_img = equalization_histogram( origin_histogram, img )
# 计算均衡化后的灰度直方图
origin_grayHist = GrayHist(img)
equaliza_grayHist = GrayHist( new_img )

# 绘制灰度直方图
x = np.arange(256)
plt.figure(figsize=(15,10))
plt.subplot( 2, 2, 1 )
plt.plot(x, origin_grayHist, linewidth=2 , alpha=0.5)
plt.title("Origin",fontsize=18)
plt.ylabel("Frequency",fontsize=18)

plt.subplot( 2, 2, 2 )
plt.plot(x, equaliza_grayHist, linewidth=2, alpha=0.5)
plt.title("Equalization",fontsize=18)
plt.ylabel("Frequency",fontsize=18)

plt.subplot( 2, 2, 3 )
plt.imshow( img, cmap = plt.cm.gray )
plt.title( 'Origin' ,fontsize=18)

plt.subplot( 2, 2, 4 )
plt.imshow( new_img, cmap = plt.cm.gray )
plt.title( 'Equalization' ,fontsize=18)
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

unity2D跑酷游戏

项目成果 项目网盘 导入资源包 放入Assets文件Assets资源文件 游戏流程分析 摄像机size调小,让图片占满屏幕 人跑本质,相对运动,图片无限向右滚动 图片720,缩小100倍第二个图片x为7.2每unit px100两张图片刚好挨着连贯 空对象Bg…

(奇幻森林)POLYGON - Enchanted Forest - Nature Biomes - 3D Environment Art by Synty

各种雄伟的树木,装饰着优雅简化的树叶,在头顶形成了一个天堂般的树冠,在苔藓覆盖的森林地面上投下了宁静的咒语。 每一项资产,从引人入胜的环境材料到平缓的波浪状山丘,都经过精心制作,将您带到魔法和自然融合的地方。POLYGON-魔法森林-自然生物技术为数字领域注入真正魔…

搭载算能 BM1684 芯片,面向AI推理计算加速卡

搭载算能 BM1684 芯片,是面向AI推理的算力卡。可集成于服务器、工控机中,高效适配市场上所有AI算法,实现视频结构化、人脸识别、行为分析、状态监测等应用,为智慧城市、智慧交通、智慧能源、智慧金融、智慧电信、智慧工业等领域进…

FreeRtos进阶——软件定时器内部逻辑

在FreeRtos软件定时器,是根据Systick来判断定时是否到达,可以是单次定时器也可以是循环定时器。在创建定时器任务后,在每一次SysTick中断中,会将定时器时钟到的任务写入定时器任务队列。在prvTimerTask任务(守护任务&a…

JVM之【运行时数据区1】

JVM简图 运行时数据区简图 一、程序计数器(Program Counter Register) 1.程序计数器是什么? 程序计数器是JVM内存模型中的一部分,它可以看作是一个指针,指向当前线程所执行的字节码指令的地址。每个线程在执行过程中…

基础—SQL—DQL(数据查询语言)排序查询

一、引言 排序查询这里面涉及的关键字:ORDER BY。在我们日常的开发中,这个是很常见的,比如打开一个网购的商城,这里面可以找到一个销量的排序、综合的排序、价格的排序(升序、降序)等等。接下来就学习这一部…

前端传String字符串 后端使用enun枚举类出现错误

情况 前端 String 后端 enum 前端 后端 报错 2024-05-31T21:47:40.61808:00 WARN 21360 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to con…

《QT实用小工具·六十九》基于QT开发的五子棋AI游戏

1、概述 源码放在文章末尾 该项目实现了五子棋对战AI,可以享受和AI下棋的快乐,项目实现思路如下: 博弈树 ●Alpha-Beta剪枝(性能提高较大) ●启发式搜索(性能提高较大) ●落子区域限制(性能提高较大) ●Zobrist哈希(性能小幅提升) ●Qt…

【再探】设计模式—访问者模式、策略模式及状态模式

访问者模式是用于访问复杂数据结构的元素,对不同的元素执行不同的操作。策略模式是对于具有多种实现的算法,在运行过程中可动态选择使用哪种具体的实现。状态模式是用于具有不同状态的对象,状态之间可以转换,且不同状态下对象的行…

记mapboxGL实现鼠标经过高亮时的一个问题

概述 mapboxGL实现鼠标经过高亮可通过注册图层的mousemove和moveout事件来实现,在mousemove事件中可以拿到当前经过的要素,但是当使用该要素时,发现在某个地图级别下会有线和面数据展示不全的情况。究其原因,发现是mapboxGL在绘图…

2024Dragon Knight CTF复现web

穿梭隐藏的密钥 首先看看页面的源代码,但是发现f12和鼠标右键都被禁用了 用ctrlu查看,发现一个可疑页面 访问看看,发现还是只有一张图,查看源代码发现提示 扩展: Fuzz:Fuzz是一种基于黑盒的自动化软件模糊…

数据结构与算法笔记:基础篇 - 栈:如何实现浏览器的前进和后退功能?

概述 浏览器的前进、后退功能,你肯定很熟悉吧? 当依次访问完一串页面 a-b-c 之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面 b 和 a。当后退到页面 a,点击前进按钮,就可以重新查看页面 b 和 c。但…

C/S模型测试

1 1.1代码示例 #include<stdio.h> #include<stdio.h>#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>#include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ #include <arpa/inet.…

004 仿muduo实现高性能服务器组件_Buffer模块与Socket模块的实现

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;仿muduo &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言Buffer模块Socket模块 小结 前言 这章将会向你介绍仿muduo高性能服务器组件的buffer模块与socket模块的实…

12k Star!Continue:Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 12k Star&#xff01;Continue&#xff1a;Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖&#xff01; &…

CSS--学习

CSS 1简介 1.1定义 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#xff09;。 1.2 特性 继承性 子级默认继承父级的文字控制属性。层叠性 相同的属性…

Elasticsearch 认证模拟题 - 5

一、题目 .在集群上有一个索引 food_ingredient&#xff0c;搜索需要满足以下要求&#xff1a; 三个字段 manufacturer&#xff0c;name&#xff0c;brand 都能匹配到文本 cake mix高亮 字段 name&#xff0c;并加标签排序&#xff0c;对字段 brand 正序&#xff0c;_score 降…

【Linux】Linux环境基础开发工具_3

文章目录 四、Linux环境基础开发工具2. vim3. gcc和g动静态库的理解 未完待续 四、Linux环境基础开发工具 2. vim vim 怎么批量化注释呢&#xff1f;最简单的方法就是在注释开头和结尾输入 /* 或 */ 。当然也可以使用快捷键&#xff1a; Ctrl v 按 hjkl 光标移动进行区域选择…

VR导航的实现原理、技术优势和应用场景

VR导航通过虚拟现实技术提供沉浸式环境&#xff0c;结合室内定位技术实现精准导航。目前&#xff0c;VR导航已在多个领域展现出其独特的价值和潜力&#xff0c;预示着智能导航系统的未来发展。 一、实现原理 VR导航技术依托于虚拟现实(VR)和室内定位系统。VR技术利用计算机模…

IMU状态预积分代码实现 —— IMU状态预积分类

IMU状态预积分代码实现 —— IMU状态预积分类 实现IMU状态预积分类 实现IMU状态预积分类 首先&#xff0c;实现预积分自身的结构。一个预积分类应该存储一下数据&#xff1a; 预积分的观测量 △ R ~ i j , △ v ~ i j , △ p ~ i j \bigtriangleup \tilde{R} _{ij},\bigtrian…