|
import cv2 |
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
import sys |
|
|
|
|
|
def DerivGauss(im, sigma=0.5): |
|
gaussian_die_off = 0.000001 |
|
var = sigma ** 2 |
|
|
|
width = None |
|
for i in range(1, 51): |
|
if np.exp(-(i ** 2) / (2 * var)) > gaussian_die_off: |
|
width = i |
|
if width is None: |
|
width = 1 |
|
|
|
|
|
x = np.arange(-width, width + 1) |
|
y = np.arange(-width, width + 1) |
|
coordinates = np.meshgrid(x, y) |
|
x = coordinates[0] |
|
y = coordinates[1] |
|
derivate_gaussian_2D = -x * \ |
|
np.exp(-(x * x + y * y) / (2 * var)) / (var * np.pi) |
|
|
|
|
|
ax = cv2.filter2D(im, -1, derivate_gaussian_2D) |
|
ay = cv2.filter2D(im, -1, np.transpose(derivate_gaussian_2D)) |
|
magnitude = np.sqrt((ax ** 2) + (ay ** 2)) |
|
return magnitude |
|
|
|
|
|
def GPconstancy_GI(im, gray_pixels, delta_th=10**(-4)): |
|
|
|
|
|
mask = np.logical_or(np.max(im, axis=2) >= 0.95, |
|
np.sum(im, axis=2) <= 0.0315) |
|
|
|
|
|
|
|
|
|
|
|
|
|
r = im[:, :, 0] |
|
g = im[:, :, 1] |
|
b = im[:, :, 2] |
|
|
|
|
|
mask = np.logical_or.reduce((mask, r == 0, g == 0, b == 0)) |
|
|
|
|
|
eps = np.finfo(np.float32).eps |
|
r[r == 0] = eps |
|
g[g == 0] = eps |
|
b[b == 0] = eps |
|
norm = r + g + b |
|
|
|
|
|
delta_r = DerivGauss(r) |
|
delta_g = DerivGauss(g) |
|
delta_b = DerivGauss(b) |
|
mask = np.logical_or(mask, np.logical_and.reduce( |
|
(delta_r <= delta_th, delta_g <= delta_th, delta_b <= delta_th))) |
|
|
|
|
|
log_r = np.log(r) - np.log(norm) |
|
log_b = np.log(b) - np.log(norm) |
|
|
|
|
|
delta_log_r = DerivGauss(log_r) |
|
delta_log_b = DerivGauss(log_b) |
|
mask = np.logical_or.reduce( |
|
(mask, delta_log_r == np.inf, delta_log_b == np.inf)) |
|
|
|
|
|
data = np.concatenate( |
|
(np.reshape(delta_log_r, (-1, 1)), np.reshape(delta_log_b, (-1, 1))), axis=1) |
|
mink_norm = 2 |
|
norm2_data = np.sum(data ** mink_norm, axis=1) ** (1 / mink_norm) |
|
map_uniquelight = np.reshape(norm2_data, delta_log_r.shape) |
|
|
|
|
|
map_uniquelight[mask] = np.max(map_uniquelight) |
|
|
|
|
|
|
|
|
|
|
|
gray_index_unique = map_uniquelight |
|
sort_unique = np.sort(gray_index_unique.flatten()) |
|
gindex_unique = np.full(gray_index_unique.shape, False, dtype=bool) |
|
gindex_unique[gray_index_unique <= sort_unique[gray_pixels - 1]] = True |
|
choosen_pixels = im[gindex_unique] |
|
mean = np.mean(choosen_pixels, axis=0) |
|
result = mean / np.apply_along_axis(np.linalg.norm, 0, mean) |
|
return result |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
im_path = 'example.png' |
|
im = cv2.cvtColor(cv2.imread(im_path), cv2.COLOR_BGR2RGB) |
|
im = np.float32(im) / 255 |
|
|
|
tot_pixels = im.shape[0] * im.shape[1] |
|
|
|
n = 0.1 |
|
num_gray_pixels = int(np.floor(n * tot_pixels / 100)) |
|
|
|
|
|
gt = np.array([0.6918, 0.6635, 0.2850]) |
|
lumTriplet = GPconstancy_GI(im, num_gray_pixels, 10**(-4)) |
|
|
|
|
|
print(lumTriplet) |
|
print(np.arccos(np.dot(lumTriplet, gt)) * 180 / np.pi) |
|
|