Currently I'm trying to compute histogram spread for image contrast metrics based on this paper Performance metrics for image contrast. The algorithm for easier and faster to read showed by this screenshot of the paper:
Or by quoting the paper:
Histogram spread is the ratio of the quartile distance to the range of the histogram. Quartile distance is denoted as the difference between the 3 rd quartile and the 1 st quartile. Here 3 rd quartile and 1 st quartile means the histogram bins at which cumulative histogram have 75% and 25% of the maximum value respectively (see Fig.1)
I use these two images for these experiments which both are medical images (mammograms):
Here is the code that I used:
import cv2
import numpy as np
def calculate_histogram_spread(gray_img):
#compute image histogram and its cdf
histo,_ = np.histogram(gray_img.flatten(),256,[0,256])
cdf = np.cumsum(histo)
#calculate the Q3 (75%percentile) and Q1 (25%percentile)
Q3 = np.percentile(cdf,75)
Q1 = np.percentile(cdf,25)
#find the which bin value
Q3_bin = np.searchsorted(cdf,Q3)
Q1_bin = np.searchsorted(cdf,Q1)
IQR = Q3_bin - Q1_bin
divider = np.max(gray_img) - np.min(gray_img)
HS = IQR/divider
return Q3_bin,Q1_bin,HS
if __name__ == '__main__':
sample1 = '/home/mario/Desktop/hs1.jpg'
sample2 = '/home/mario/Desktop/hs2.jpg'
img1 = cv2.imread(sample1,0)
img2 = cv2.imread(sample2,0)
print('Sample1')
Q3_bin,Q1_bin,HS = calculate_histogram_spread(img1)
print('Q3_bin={},Q1_bin={},HS={}'.format(Q3_bin,Q1_bin,HS))
print('Sample2')
Q3_bin,Q1_bin,HS = calculate_histogram_spread(img2)
print('Q3_bin={},Q1_bin={},HS={}'.format(Q3_bin,Q1_bin,HS))
Here is my terminal result:
Sample1
Q3_bin=192,Q1_bin=64,HS=0.5019607843137255
Sample2
Q3_bin=192,Q1_bin=64,HS=0.5019607843137255
My question is why the two images have the same exact output while visually the images have different contrast (I think)? Did I do any mistakes? I'm testing those images in same size/resolution.
This seems to give different contrast values for me in Python/OpenCV.
Input 1:
Input 2:
import cv2
import numpy as np
# load images as grayscale
img = cv2.imread("breast1.jpg", 0)
#img = cv2.imread("breast2.jpg", 0)
hh, ww = img.shape[:2]
# compute total pixels
tot = hh * ww
# compute histogram
hist = np.histogram(img,bins=256,range=[0,255])[0]
# compute cumulative histogram
cum = np.cumsum(hist)
# normalize histogram to range 0 to 100
cum = 100 * cum / tot
# get bins of percentile at 25 and 75 percent in cum histogram
i = 0
while cum[i] < 25:
i = i+1
B1 = i
i = 0
while cum[i] < 75:
i = i+1
B3 = i
print('25 and 75 percentile bins:',B1,B3)
# compute min and max graylevel (which are also the min and max bins)
min = np.amin(img)
max = np.amax(img)
print('min:',min, 'max:',max)
# compute contrast
contrast = (B3-B1)/(max-min)
print('contrast:',contrast)
Result for Image 1:
25 and 75 percentile bins: 0 147
min: 0 max: 255
contrast: 0.5764705882352941
Result for Image 2:
25 and 75 percentile bins: 58 162
min: 0 max: 255
contrast: 0.40784313725490196