一、理论:直方图均衡化的一些理论依据一般从连续型和离散型来进行解释。
1、连续型
(1) 基础公式
公式一:
符号说明: 为变换后灰度级s的概率,为变换前灰度级r的概率,dr、ds分别对应变换前的灰度级r、s的微分量,具体来说,如果灰度级r在图像中的像素点个数为n,那么dr为1/n。
公式二 :
符号说明:假设灰度级区间为(0,L-1),L-1即为最大灰度级。
公式三:
公式说明:T为灰度级r经过均衡化变化成灰度级s的一个变换函数记号。
(2)均衡化公式的推导
由公式一和公式二可得到:
所以得到公式四:
对公式四两边求积分可得
公式五(直方图连续型灰度级均衡化变换公式):
2、离散型
(1) 基础公式
公式六:
符号说明:是输入图像灰度级等于k的像素个数,H是输入图像的高,W是输入图像的宽。
公式七:
符号说明:p是输入图像的某个灰度级,q是输出图像的某个灰度级。
(2) 均衡化公式的推导
由公式六和公式七可得:
继续化简可得公式八(直方图离散型灰度级均衡化变化公式):
二、实现:此处使用matlab、Python、C++三种方式实现(正在调试中,整理后上传,2020.2.3)
1、matlab实现
clear all
PI = imread('E:\图像处理\图库\暗图1.jpg');
PI = rgb2gray(PI);
PO = histeq(PI,256);
subplot(2,2,1);
imshow(PO)
subplot(2,2,2);
imshow(PI)
subplot(2,2,3);
imhist(PO)
subplot(2,2,4);
imhist(PI)
2、Python实现
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 2 16:42:11 2020
@author: Administrator
"""
import cv2
import numpy as np
import math
import sys
from matplotlib import pyplot as plt
#import argparse
def calcGrayHist(image):
rows,cols = image.shape
grayHist = np.zeros([256],np.int32)
for r in range(rows):
for c in range(cols):
grayHist[image[r][c]] +=1
return grayHist
def equalHist(image):
#灰度图像矩阵的宽高
rows,cols = image.shape
#计算灰度直方图
grayHist = calcGrayHist(image)
#计算累积灰度直方图
zeroCumuMoment = np.zeros([256],np.uint32)
for p in range(256):
if p == 0:
zeroCumuMoment[p] = grayHist[0]
else:
zeroCumuMoment[p] = zeroCumuMoment[p-1] + grayHist[p]
#根据累加灰度直方图得到输入灰度级和输出灰度级之间的映射关系
outPut_q = np.zeros([256],np.uint8)
cofficient = 256.0/(rows*cols)
for p in range(256):
q = cofficient* float(zeroCumuMoment[p]) -1
if q >= 0:
outPut_q[p] = math.floor(q)
else:
outPut_q[p] = 0
#得到直方图均衡化后的图像
equalHistImage = np.zeros(image.shape,np.uint8)
for r in range(rows):
for c in range(cols):
equalHistImage[r][c] = outPut_q[image[r][c]]
return equalHistImage
if __name__ == "__main__":
#if len(sys.argv) >1:
# image_input =cv2.imread(sys.argv[1],1)
#parser = argparse.ArgumentParser()
#parser.add_argument('path_image_input', help='输入图像路径')
#parser.add_argument('path_image_output', help='输出图像路径')
#args = parser.parse_args()
image_input = cv2.imread('E:\Image_Processing\Image_Repo\dark_Image.jpg',cv2.IMREAD_COLOR)
#print(image_input)
#cv2.imshow('image_input',image_input)
# 把彩色图片变为灰度图片
gray_image = cv2.cvtColor(image_input, cv2.COLOR_BGR2GRAY)
#equal_image = cv2.equalizeHist(gray_image)
equal_image = equalHist(gray_image)
cv2.imshow('gray image', gray_image)
cv2.imshow('equal image', equal_image)
# 保存处理后的文件
#cv2.imwrite(args.path_image_output, equal_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
3、C++实现
三、后记:本文主要是本人在学习过程中的一些学习记录和心得,欢迎大家评论交流纠正。