contrast normalization of image python

Question:

i want to ask how to get the image result (Icon) with python code as indicated in

enter image description here

where ishade is a preprocessed image and std(Ishade) is the standard deviation of this image

result = ndimage.median_filter(blur, size=68)
std=cv2.meanStdDev(result)
Asked By: Cy Rine

||

Answers:

I am not sure I understand what you want. There are different types of normalization formulae.

The most common would be to subtract the mean from the image and then divide by the standard deviation. (I-mean(I))/std(I)

But if you want to do your formulae, I/std(I), then it can be done as follows:

Input:

enter image description here

import cv2
import numpy as np
import skimage.exposure

# load image
img = cv2.imread("lena.jpg")

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.float64)/255

# get local mean from blurred gray image and square it
sigma=15
mean = cv2.GaussianBlur(gray, (0,0), sigmaX=sigma, sigmaY=sigma)
mean_sq = cv2.multiply(mean,mean)

# get mean of gray image squared
gray2 = cv2.multiply(gray,gray)
mean2 = cv2.GaussianBlur(gray2, (0,0), sigmaX=sigma, sigmaY=sigma)

# get variance image from the two means
var = cv2.subtract(mean2, mean_sq)

# get the standard deviation image from the variance image
std = np.sqrt(var)
print(std.dtype, np.amax(std), np.amin(std))

# divide image by std and scale using skimage
divide = (255*cv2.divide(gray, std, scale=1)).clip(0,255).astype(np.uint8)
divide = skimage.exposure.rescale_intensity(divide, in_range='image', out_range=(0,255)).astype(np.uint8)
print(divide.dtype, np.amax(divide), np.amin(divide))

# write result to disk
cv2.imwrite("lena_std_division.jpg", divide)

# display it
cv2.imshow("std", std)
cv2.imshow("divide", divide)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result (depending upon the sigma value):

enter image description here

An alternate formula for which I have posted a number of examples (called division normalization), would be to divide the image by its local mean image. I/mean(I))

Answered By: fmw42

I tried to follow the article in the reference you posted and the reference in that post to the original. But I do not get exactly what they do. Nevertheless, here is my interpretation (apart from the initial CLAHE). You can adjust the mean and median filter sizes as desired.

Input:

enter image description here

import cv2
import numpy as np
import skimage.exposure

# load image
img = cv2.imread("lena.jpg")

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Gaussian blurred gray image
mean = cv2.GaussianBlur(gray, (0,0), sigmaX=5, sigmaY=5)

# apply median filter to mean image
median = cv2.medianBlur(mean, 25)

# divide mean by median
division = cv2.divide(mean.astype(np.float64)/255, median.astype(np.float64)/255)

# get global standard deviation of division
std = np.std(division)
print(std)

# divide the division by the std and normalize to range 0 to 255 as unint8
result = np.divide(division, std)
result = skimage.exposure.rescale_intensity(result, in_range='image', out_range=(0,255)).astype(np.uint8)
    
# write result to disk
cv2.imwrite("lena_std_division2.jpg", result)

# display it
cv2.imshow("mean", mean)
cv2.imshow("median", median)
cv2.imshow("division", division)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

enter image description here

Answered By: fmw42
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.