东南大学《数字图像处理》课程作业 6 - Retinex 增强

说明.pdf.1

说明.pdf.2

说明.pdf.3

程序代码

# coding: utf-8

'''
东南大学《数字图像处理》课程 作业6 - 对比度增强
09017227 卓旭 written with Python 3

本程序内灰度图像作为二维数组,存储顺序为[行][列],像素点坐标表示为img[x][y],坐标系为
O--------> [y axis]
|
|
V [x axis]
'''

import imageio
import numpy as np
import cv2 # OpenCV仅用于显示图片
import matplotlib.pyplot as plt

IMAGE_PATH='./img_Retinex.bmp'

'''
  读入灰度图像,转为二维numpy数组
'''
def readImage(imagePath):
  return imageio.imread(imagePath)

'''
  Retinex实现
'''
def Retinex(I):
  I = I + 1. # 为避免log(0)错误,转为1~256区间
  # 不使用 I=I+微小量 的原因是log(0)→-∞,会对后续exp过程产生影响
  I_log = np.log(I) # log I = log L + log R
  I_log_fft = np.fft.fft2(I_log) # 对数域作DFT转入频域
  I_log_fft_shift = np.fft.fftshift(I_log_fft) # shift结果,把低频放到中心而不是四角

  # 频谱绘制相关
  # plt.subplot(121)
  # plt.imshow(np.log(np.abs(I_log_fft_shift)), cmap='gray')

  # 接下来设计一个滤波器,它减益低频,增益高频
  # 这是一个调整过的高斯滤波器,详见说明文档
  # 其中心在图像中心,与前面的shift对应
  def AdjustedGaussFilter(lowAlpha, highAlpha, c, cutFreq, height, width):
    H = np.zeros((height, width))
    squareD0 = cutFreq ** 2
    delta = highAlpha - lowAlpha
    centerX, centerY = height // 2, width // 2
    for i in range(height):
      for j in range(width):
        squareD = (i - centerX) ** 2 + (j - centerY) ** 2
        res = delta * (1 - np.exp(-c * squareD / squareD0)) + lowAlpha
        H[i, j] = res
    return H
  HL = 0.8 # 低频减益系数
  HH = 1.85 # 高频增益系数
  C = 1 # 坡度控制参数
  CUT_FREQ = 40 # 截止频率
  AGF = AdjustedGaussFilter(HL, HH, C, CUT_FREQ, I.shape[0], I.shape[1])

  # 频谱绘制相关
  # plt.subplot(122)
  # plt.imshow(AGF, cmap='gray')
  # plt.show()

  # 用这个滤波器作用于I_log_fft_shift,可以认为削减了照度L的量
  R_log_fft_shift = I_log_fft_shift * AGF
  # 反傅里叶变换
  R_log_fft = np.fft.ifftshift(R_log_fft_shift)
  R_log = np.fft.ifft2(R_log_fft)
  R = np.abs(np.exp(R_log)) # 指数处理,去掉log
  R = R - 1 # 把之前加的1减去
  # 化到0~255区间
  R_norm = np.zeros(R.shape)
  minR, maxR = np.min(R), np.max(R)
  rangeR = maxR - minR
  for i in range(R.shape[0]):
    for j in range(R.shape[1]):
      R_norm[i, j] = (R[i, j] - minR) / rangeR * 255.

  return np.asarray(R_norm, np.uint8)

if __name__ == '__main__':
  print("开始计算...")
  result = Retinex(readImage(IMAGE_PATH))
  imageio.imwrite('Retinex_Result.bmp', result)
  cv2.imshow("Retinex", result)
  cv2.waitKey(0)
posted @ 2021-02-07 23:46  z0gSh1u  阅读(276)  评论(0编辑  收藏  举报