基于熵保持映射先验的快速图像对比度增强算法的python实现

# -*- coding: utf-8 -*-
# @FileName: (2区)基于熵保持映射先验的快速图像对比度增强算法
# @Software: PyCharm
# @Author  : Xu
# @Time    :2021//09//28

import cv2
import copy
import numpy as np
from matplotlib import pyplot as plt
from scipy.ndimage import convolve

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


class EPMP:
    def __init__(self, image, theta0, theta1, theta2):
        self.image = image
        self.theta0 = theta0
        self.theta1 = theta1
        self.theta2 = theta2
        pass

    def InputHistogram(self, V_Mat):
        '''
        获取输入强度通道的概率密度pdf
        '''
        # 获取图像的大小
        height = self.image.get_height()
        width = self.image.get_width()
        tt = height * width
        # 获取图像中灰度级的最大最小值
        h_density = []
        h_gray = []
        for i in range(256):
            t = np.sum(V_Mat == i)
            d = t / tt
            h_density.append(d)
            h_gray.append(i)
        '''
        显示直方图
        # '''
        # plt.plot(h_gray, h_density)
        # plt.xlabel("V分量灰度级")
        # plt.ylabel("V分量概率密度")
        # plt.title('原始V分量的pdf')
        # plt.show()
        return h_density, h_gray

    def get_CumDist(self, h_density, h_gray):
        '''
        获取图像的累计概率密度cdf
        '''
        size = len(h_density)
        cumDist = []
        sum = 0
        for i in range(size):
            sum = sum + h_density[i]
            if i == 0:
                cumDist.append(h_density[i])
            else:
                cumDist.append(cumDist[i - 1] + h_density[i])
        plt.plot(h_gray, cumDist)
        plt.xlabel("V分量灰度级")
        plt.ylabel("V分量累计概率密度")
        plt.title('HE算法后V分量的cdf')
        plt.show()
        return cumDist

    def get_Equalization(self, cdf):
        '''
        对强度V通道进行直方图均衡化
        '''
        # 原始图像的V通道
        v_mat = self.image.get_v_mat()
        # cdf像素值映射
        v_map = [int(255 * cdf[i]) for i in range(256)]
        # 像素值替换
        assert isinstance(v_mat, np.ndarray)  # 判断类型
        h, w = v_mat.shape
        v_HE = np.zeros_like(v_mat)
        for i in range(h):
            for j in range(w):
                v_HE[i, j] = v_map[v_mat[i, j]]
        # cv2.imshow('v_mat',v_mat)
        # cv2.imshow('v_HE',v_HE)
        # cv2.waitKey()
        return v_HE

    def convol(self,v_density):
        '''
        公式19计算梯度
        '''
        # 创建一个单位矩阵
        E = np.mat(np.identity(len(v_density)))
        #x轴的梯度算子【-1,1】,注意,一维数组转置需要指定shape
        gradient_x = E+np.diagflat([-1]*255, 1)
        gradient_x_T = gradient_x.transpose()
        gradient_temp = np.dot(gradient_x_T, gradient_x)
        temp_3 = convolve(E, gradient_temp)
        return temp_3

    def get_T(self, theta0, theta1, theta2, v_density, v_HE_density,temp_3):
        '''
        利用论文公式(19)计算T
        '''
        # 创建一个单位矩阵
        E = np.mat(np.identity(len(v_density)))
        temp1 = theta0 * E
        temp2 = theta1 * E
        temp3 = theta2 *temp_3
        result1 = np.linalg.inv(temp1+temp2+temp3)
        result2= theta0*np.array(v_HE_density)+theta1*np.array(v_density)
        result_T=np.dot(result1,result2)
        # print(result_T)
        # print(result_T.shape)
        return result_T

    def plot(self,T):
        '''
        绘制映射后的T曲线
        '''
        x_data = np.arange(256)
        y_data = np.array(T)[0]
        new_T=[]
        sum=0
        for i in range(256):
            sum = sum+y_data[i]
            if i==0:
                new_T.append(y_data[i])
            else:
                new_T.append(new_T[i-1]+y_data[i])
        # print(new_T)
        plt.plot(x_data, new_T)
        plt.xlabel("V分量灰度级")
        plt.ylabel("V分量累计概率密度")
        plt.title('映射曲线T')
        plt.show()
        return new_T

    def new_gray(self,v_CumDist, new_cumDist):
        '''
        查找cdf最近距离的灰度级
        '''
        # new_V=[]
        # for i in range(256):
        #     t=np.abs(v_CumDist[i]-new_cumDist)
        #     idx=t.argmin()
        #     new_V.append(idx)
        # # new_V=np.array(new_V)
        # #灰度级替换
        img_map = [int(255 * (new_cumDist[i]/1)+0.5) for i in range(256)]  # 像素值映射
        v_mat=self.image.get_v_mat()
        # 像素值替换
        assert isinstance(v_mat, np.ndarray)
        r, c = v_mat.shape
        for ri in range(r):
            for ci in range(c):
                v_mat[ri, ci] = img_map[v_mat[ri, ci]]
        # cv2.imshow('v_mat',v_mat)
        return v_mat


    def plot_img(self,new_V):
        '''
        最终效果图显示
        '''
        h_mat=self.image.get_h_mat()
        s_mat = self.image.get_s_mat()
        hsv_img=cv2.merge([h_mat,s_mat,new_V])
        bgr_img=cv2.cvtColor(hsv_img,cv2.COLOR_HSV2BGR)
        cv2.imshow('update_img',bgr_img)
        cv2.waitKey()
```python
from EPMP import EPMP
from util import Image
from matplotlib import pyplot as plt

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False



def init_EPMP(image, theta0, theta1, theta2):
    Map = EPMP(image, theta0, theta1, theta2)
    # 获取图像的强度V分量
    v_Mat = image.get_v_mat()
    # print(' 原始亮度V通道的灰度级为:', v_Mat)
    # 获取原始图像的pdf,cdf
    v_density, v_gray = Map.InputHistogram(v_Mat)
    v_CumDist = Map.get_CumDist(v_density, v_gray)
    # print('v_density', v_density)
    # print('v_CumDist', v_CumDist)
    # 对V强度通道进行直方图均衡化
    v_HE = Map.get_Equalization(v_CumDist)
    # 对均衡化后的V分量计算pdf和cdf
    v_HE_density, v_HE_gray = Map.InputHistogram(v_HE)
    v_HE_CumDist = Map.get_CumDist(v_HE_density, v_HE_gray)
    # print('v_HE_density', v_HE_density)
    # print('v_HE_CumDist', v_HE_CumDist)
    #公式(19)的求解
    temp_3 = Map.convol(v_density)
    result_T = Map.get_T (theta0, theta1, theta2, v_density, v_HE_density,temp_3)
    new_cumDist = Map.plot(result_T)

    #更新后的灰度级
    new_gray=Map.new_gray(v_CumDist, new_cumDist)
    # print(' 映射后的灰度级为:', new_gray)
    #图像显示
    Map.plot_img(new_gray)

def run(path,t, pathName):
    image = Image(path)
    # 得到一维输出V分量图像
    theta0 = 1.3945
    theta1 = 9.1377
    theta2 = 0.5
    init_EPMP(image, theta0, theta1, theta2)


if __name__ == '__main__':

    # t = "picturedataset/datasetLcenter/"
    t = ""
    for i in range(6):
        name = str(i + 1)
        path = t + name + ".png"
        run(path,t,name)


import cv2

class Image:

    def __init__(self,image_path):
        '''
        读取图像
        '''
        self.image_path=image_path#读取图像的路径
        img_bgr=cv2.imread(self.image_path)
        (hMat,sMat,vMat)=cv2.split(cv2.cvtColor(img_bgr,cv2.COLOR_BGR2HSV))
        self.h_mat=hMat
        self.s_mat=sMat
        self.v_mat=vMat
        self.height=vMat.shape[0]
        self.width=vMat.shape[1]
        pass

    def get_h_mat(self):
        return self.h_mat

    def get_s_mat(self):
        return self.s_mat

    def get_v_mat(self):
        return self.v_mat

    def get_height(self):
        return self.height

    def get_width(self):
        return self.width

    def get_image_path(self):
        return self.image_path





你可能感兴趣的:(论文代码,python,计算机视觉,深度学习)