channels = cv2.split(image)
colors = ('r', 'g', 'b')

histogram = [0.0]
for (channel, color) in zip(channels, colors):
    histogram += cv2.calcHist([channel], [0], None, [256], [0, 256])

normalized_histogram = normalize(histogram, norm='l1', axis=0, copy=True, return_norm=False)

"""
Explanation: Ke Contrast
The constrast is based on the calculation of the aggregated RGB histogram of the image.
End of explanation
"""


def middleMassWidth(percentage, histogram):
    bias = (int)((1 - percentage)/2)
    accumulator = 0.0
    start = 0
    for index, bin_value in enumerate(histogram):
        accumulator = accumulator + bin_value
        if(accumulator < bias):
            start = index
        if(accumulator > bias + percentage):
            return index - start - 1

middleMassWidth(0.98, normalized_histogram)

middleMassWidth(0.95, normalized_histogram)

"""
Explanation: Then the width of 98% mass is calculated
End of explanation
"""


hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_image)

print(v)

"""
Explanation: Ke brightness
The mean brightness may be calculated as the mean of the value channel of the HSV representation of the image.
End of explanation
"""


np.mean(v) / 256 * 100

"""
Explanation: The value channel ranges from 0 to 255. So, to get the brightness average percentage of the image we can use.
End of explanation
"""


hue_countable = []
for rows in hsv_image:
    for cols in rows:
        if cols[2]/256 > 0.15 and cols[2]/256 < 0.95 and cols[1]/256 > 0.2:
            hue_countable.append(cols[0])


print(len(hue_countable))

hue_count_histogram = np.histogram(hue_countable, bins=20)

print(hue_count_histogram)

m = np.max(hue_count_histogram[0])
alpha = 0.05

N = 0
for bin in hue_count_histogram[0]:
    if bin > alpha * m:
        N = N + 1
print(N)

qh = 20 - N
print(qh)

"""
Explanation: Hue Count
End of explanation
"""


laplacian = np.array([ [0.2/1.2, 0.8/1.2, 0.2/1.2],
                       [0.8/1.2, -4/1.2, 0.8/1.2],
                       [0.2/1.2, 0.8/1.2, 0.2/1.2]])
print(laplacian)

r, g, b = cv2.split(image)
print(r)

r_laplacian = np.absolute(signal.convolve2d(r, laplacian, mode='same', boundary='fill', fillvalue=0))
g_laplacian = np.absolute(signal.convolve2d(g, laplacian, mode='same', boundary='fill', fillvalue=0))
b_laplacian = np.absolute(signal.convolve2d(b, laplacian, mode='same', boundary='fill', fillvalue=0))

mean_laplacian = np.mean([r_laplacian, g_laplacian, b_laplacian], axis=0)
mean_laplacian = mean_laplacian / mean_laplacian.max() * 255
print(np.max(mean_laplacian))

plt.imshow(mean_laplacian, cmap='gray_r')
plt.show()

resized_laplacian_image = sp.misc.imresize(mean_laplacian, [100, 100], interp='lanczos')
resized_laplacian_image = skimage.img_as_float(resized_laplacian_image)
normalize(resized_laplacian_image, norm='l1', axis=1, copy=False, return_norm=False)
resized_laplacian_image = resized_laplacian_image/100

plt.imshow(resized_laplacian_image, cmap='gray_r')
plt.show()

"""
Explanation: Spacial distribution of edges
End of explanation
"""


Px = np.sum(mean_normalized_laplacian, axis=0)
Py = np.sum(mean_normalized_laplacian, axis=1)

print(Px)

quality = 1 - middleMassWidth(0.98, Px) * middleMassWidth(0.98, Py)/10000
print("quality: ", quality)

"""
Explanation: Edges bounding box area
End of explanation
"""


fft_r = np.fft.fft2(r)
fft_g = np.fft.fft2(g)
fft_b = np.fft.fft2(b)

fft = np.mean([fft_r, fft_g, fft_b], axis=0)

fshift = np.fft.fftshift(fft)
magnitude_spectrum = 20*np.log(np.abs(fshift))

plt.plot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

np.abs(magnitude_spectrum).max()

(np.sum(np.abs(fft) > 5, axis=None)) / (len(fft) * len(fft[0]))

"""
Explanation: Blur
End of explanation
"""


