pyfusion.utils.histMatch 的原始碼

import cv2
import numpy as np
import math
import copy
import numba

[文件]def histMatch(src, ref): """Histogram matching The histMatch function will return the image been matched by `ref`, the `src` and `ref` should be grayscale image :param src: The source image, it should be `numpy.ndarray` structure, the image read by `opencv` would be best practice :param ref: The reference image, it should be `numpy.ndarray` structure, the image read by `opencv` would be best practice :return: The result image :rtype: numpy.ndarray """ # first calculate the histogram of source and reference image src_hist = cv2.calcHist([src],[0],None,[256],[0,256]) ref_hist = cv2.calcHist([ref],[0],None,[256],[0,256]) # Normalized src_hist /= src.shape[0]*src.shape[1] ref_hist /= ref.shape[0]*ref.shape[1] # Cumulative distribution function src_cdf = [0]*256 ref_cdf = [0]*256 # Calculate the cumulative probability of the original and reference histograms for i in range(256): if i == 0: src_cdf[i], ref_cdf[i] = src_hist[i], ref_hist[i] else: src_cdf[i], ref_cdf[i] = src_cdf[i-1] + src_hist[i], ref_cdf[i-1] + ref_hist[i] # Difference of cumulative probability diff_cdf = np.zeros([256,256]) for i in range(256): for j in range(256): diff_cdf[i,j] = math.fabs(src_cdf[i] - ref_cdf[j]) # build lut lut_o = np.zeros([256], dtype=np.uint8) np.argmin(diff_cdf, axis=1, out=lut_o) # using LUT to generate the result image secmin = np.min(lut_o[lut_o>0]) lut_o[lut_o<secmin] =secmin return cv2.LUT(src, lut_o)
[文件]@numba.jit def lut(src, result, lut, start, factor=1): """LUT This is a custom LUT implementation, the `cv2.LUT` can only work with `numpy.uint8` dtype :param src: The source image :param result: The result image :param lut: The LUT table :param start: The start value :param factor: The factor :return: None """ for i in range(src.shape[0]): for j in range(src.shape[1]): index = src[i, j] - start t = lut[index] + start result[i, j] = t / factor
[文件]def histMatch2(src, ref): """Histogram matching The histmatch2 function will return the image which matched by reference image, the source and reference image will not be 8-bit image, it used by PCA fusion :param src: The source image, it should be `numpy.ndarray` structure, the image read by `opencv` would be best practice :param ref: The reference image, it should be `numpy.ndarray` structure, the dtype would be `numpy.float32` :return: The result image :rtype: numpy.ndarray """ # convert the dtype result = copy.deepcopy(src) result = result.astype(np.float64) # find max and min value minpixel_src, maxpixel_src, _, _ = cv2.minMaxLoc(src) minpixel_ref, maxpixel_ref, _, _ = cv2.minMaxLoc(ref) # convert the `src` and `ref` src = src.astype(np.float64) ref = ref.astype(np.float64) # transform the `src` to `ref` range src_ref = ((src - minpixel_src) / (maxpixel_src - minpixel_src)) * (maxpixel_ref - minpixel_ref) + minpixel_ref # copy the src and ref src_copy = copy.deepcopy(src_ref) ref_copy = copy.deepcopy(ref) # calculate the factor factor = math.ceil(4000 / (maxpixel_ref - minpixel_ref)) # factor will make histMatch possiable src_copy = src_copy * factor ref_copy = ref_copy * factor src_copy = src_copy.astype(np.int) ref_copy = ref_copy.astype(np.int) src_copy_min, src_copy_max, _, _ = cv2.minMaxLoc(src_copy) src_copy_min, src_copy_max = int(src_copy_min), int(src_copy_max) histsize = src_copy_max - src_copy_min + 1 src_hist, _ = np.histogram(src_copy, bins=histsize) ref_hist, _ = np.histogram(ref_copy, bins=histsize) src_hist = src_hist.astype(np.float64) ref_hist = ref_hist.astype(np.float64) src_hist /= (src.shape[0]*src.shape[1]) ref_hist /= (ref.shape[0]*ref.shape[1]) # Cumulative distribution function src_cdf = [0]*histsize ref_cdf = [0]*histsize # Calculate the cumulative probability of the original and reference histograms for i in range(histsize): if i == 0: src_cdf[i], ref_cdf[i] = src_hist[i], ref_cdf[i] else: src_cdf[i], ref_cdf[i] = src_cdf[i-1] + src_hist[i], ref_cdf[i-1] + ref_hist[i] # Difference of cumulative probability diff_cdf = np.zeros([histsize,histsize]) for i in range(histsize): for j in range(histsize): diff_cdf[i,j] = math.fabs(src_cdf[i] - ref_cdf[j]) lut_o = np.zeros([histsize], dtype=np.int) np.argmin(diff_cdf, axis=1, out=lut_o) lut(src_copy, result, lut_o, src_copy_min, factor) return result