山东大学软件学院2018级项目实训 第七周-加入直方图

山东大学软件学院2018级项目实训 第七周-加入直方图

写在前面:之前实现的功能都需要滑块的辅助来实现
滑块的本质其实是根据滑块改变卷积核的大小来实现图像模糊,或者腐蚀膨胀

这周要加入的新功能有:1,绘制直方图 2,直方图均衡化
很显然,这两个功能并不需要滑块来传入数值,只需要点击鼠标传入信号调用函数即可

1,什么是直方图

简单地说,直方图可以视为图形或绘图,从而可以总体了解图像的强度分布。它是在X轴上具有像素值(不总是从0到255的范围),在Y轴上具有图像中相应像素数的图。
通过直方图,可以直观地了解该图像的对比度,亮度,强度分布等。当今几乎所有图像处理工具都提供直方图功能。

通俗的讲,直方图是图像中像素灰度值大小的频率分布。
(是不是和高中学习的频率分布直方图很像!)

2,绘制直方图

代码部分可以使用Matplotlib库实现:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('photo.jpg',0)
plt.hist(img.ravel(),256,[0,256]); plt.show()

效果
在这里插入图片描述

接下来需要把这个功能放进我们的项目中来

1.首先,在图像菜单中添加直方图子选项
上一周的项目中图像菜单下只有“模糊” 和 “形态转换”两个功能

	# 子菜单直方图中有两个选项,绘制直方图和直方图均衡化
    change_menu3 = QMenu('直方图', instance)
    change_menu3.addAction(histogram_draw_action)
    change_menu3.addAction(histogram_equalization_action)

    # 新增一个菜单选项:图像
    # 图像选项新增一个子菜单直方图
    menubar = instance.menuBar()
    editMenu = menubar.addMenu('&图像')
    editMenu.addMenu(change_menu1)
    editMenu.addMenu(change_menu2)
    # 添加子菜单选项change_menu3对应着直方图!
    editMenu.addMenu(change_menu3)

效果:
在这里插入图片描述
不过这个时候的子菜单只是空有一个名字,是没有肉体和灵魂(功能)的
我们下一步要为他增加功能

2,创建一个窗口
在定义子菜单选项的位置增加对直方图的定义
因为不需要滑块,所以这里只需要定义显示窗口即可

# --------------------------直方图部分------------------------------------------------------------
    # 绘制直方图
    # 创建一个窗口,定义位置,标题等属性
    instance.widegt_draw_histogram = QWidget()
    instance.widegt_draw_histogram.setWindowTitle('绘制直方图')

    # 创建一个action,当该action被触发时运行mean_blur_widegt_show
    histogram_draw_action = QAction('&绘制直方图', instance)

    # 直方图均衡化
    # 创建一个窗口,定义位置,标题等属性
    instance.widegt_equalization_histogram = QWidget()
    instance.widegt_equalization_histogram.setWindowTitle('直方图均衡化')

    # 创建一个action,当该action被触发时运行mean_blur_widegt_show
    histogram_equalization_action = QAction('&直方图均衡化', instance)

到这里子菜单有了两幅躯壳但还没有灵魂
下一步我们需要对两个功能绘制和直方图均衡化进行区分,当点击不同功能时调用不同的函数

3,发射信号
首先一步的区分是为两个功能设定对象名:

    # 设置名字,后面根据名字执行判断
    histogram_draw_action.setObjectName("histogram_draw_action")
    histogram_equalization_action.setObjectName("histogram_equalization_action")
    # 具体实现的函数收到信号后还需要判断其来源,根据来源调用不同的函数
    # 这里实现的方法很简单,根据对象名不同调用不同函数

发射信号:

	# 上面定义了一个QAction,当触发这个行为之后和signal_emit_by_name_part2函数连接
    histogram_draw_action.triggered.connect(instance.signal_emit_by_name_part2)
    histogram_equalization_action.triggered.connect(instance.signal_emit_by_name_part2)

	def signal_emit_by_name_part2(self):
        m_blur.singal_emit_by_name(self,self.sender().objectName())
    
    # signal_emit_by_name_part2收到信号后判断发射信号的对象名,紧接着调用singal_emit_by_name函数
    # singal_emit_by_name通过调用具体函数来实现相关功能
    # 我们在前面写的绘制直方图的方法在这里就可以派上用场了	
	def singal_emit_by_name(self, name):
	    if name == "histogram_draw_action":
	        fun_histogram_draw(self)
	    if name == "histogram_equalization_action":
	        fun_histogram_equalization(self)

绘制直方图的实现:

def fun_histogram_draw(instance):
    print("绘制直方图")
    plt.hist(instance.m_image.ravel(), 256, [0, 256])
    plt.show()

在这里插入图片描述

3,直方图均衡化

前面的步骤完全重复一遍,在最后声明直方图均衡化函数即可

def fun_histogram_equalization(instance):
    print("直方图均衡化")
    img = instance.m_image
    # 原本图像输入时改为了RGB格式,这里需要先改为YUV格式
    img_yuv = cv.cvtColor(img, cv.COLOR_RGB2YUV)

    # equalize the histogram of the Y channel
    img_yuv[:, :, 0] = cv.equalizeHist(img_yuv[:, :, 0])

    # convert the YUV image back to RGB format
    img_output = cv.cvtColor(img_yuv, cv.COLOR_YUV2BGR)
    
    cv.imshow('Histogram equalized', img_output)
    cv.waitKey(0)

效果:
在这里插入图片描述
可以看到输入图像亮度偏低,均衡化后整体亮度有比较明显的提升,对比度也有提高

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值