图像处理_直方图均衡化(数学原理推导、matlab、python、c++完全实现)

一、理论:直方图均衡化的一些理论依据一般从连续型和离散型来进行解释。

  1、连续型

   (1) 基础公式

         公式一:

         {P_{s}(s)}={P_{r}(r)}*\left | \frac{dr}{ds} \right |

         符号说明: {P_{s}(s)}为变换后灰度级s的概率,{P_{r}(r)}为变换前灰度级r的概率,dr、ds分别对应变换前的灰度级r、s的微分量,具体来说,如果灰度级r在图像中的像素点个数为n,那么dr为1/n。

         公式二 :

         {P_{s}(s)}=\frac{1}{L-1}

        符号说明:假设灰度级区间为(0,L-1),L-1即为最大灰度级。

         公式三:

         s=T\left ( r\right )

         公式说明:T为灰度级r经过均衡化变化成灰度级s的一个变换函数记号。

 (2)均衡化公式的推导

         由公式一和公式二可得到:

         {P_{s}(s)}={P_{r}(r)}*\left | \frac{dr}{ds} \right |={P_{r}(r)}*\frac{1}{(L-1)*{P_{r}(r)}}

        所以得到公式四:

          \frac{ds}{dr}=(L-1)*{P_{r}(r)}

        对公式四两边求积分可得

         公式五(直方图连续型灰度级均衡化变换公式):

         s=T(r)=(L-1)\int_{0}^{r}{P_{r}(w)}dw

2、离散型

 (1) 基础公式

        公式六:

        {hist_{O}(k)}\approx \frac{H*W}{256}

      符号说明:{hist_{I}(k)}是输入图像灰度级等于k的像素个数,H是输入图像的高,W是输入图像的宽。

       公式七:

       \sum_{k=0}^{p} {hist_{I}(k)}=\sum_{k=0}^{q} {hist_{O}(k)}

     符号说明:p是输入图像的某个灰度级,q是输出图像的某个灰度级。

(2) 均衡化公式的推导

       由公式六和公式七可得:

       \sum_{k=0}^{p} {hist_{I}(k)} \approx (q+1) \frac{H*W}{256}

      继续化简可得公式八(直方图离散型灰度级均衡化变化公式):

      q \approx \frac{\sum_{k=0}^{p}{hist_{I}(k)}}{H*W}*256-1

二、实现:此处使用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++实现

三、后记:本文主要是本人在学习过程中的一些学习记录和心得,欢迎大家评论交流纠正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值