in ParametricLights.py [0:0]
def findLightBlobs(I):
# per light blob the ratio between max and lowest intensity
energy_ratio = 0.3
# (1-min_energy_wrt_max)*total_energy should be explained by the lights
min_energy_wrt_max = 0.2
min_pixels_left = np.shape(I)[0] * np.shape(I)[1] * 0.1
if len(np.shape(I)) > 2 and np.shape(I)[2] > 1:
rgb2gr = [0.2126, 0.7152, 0.0722]
G=I[:,:,0]*0
for c in range(3):
G = I[:,:,c]*rgb2gr[c]
else:
G = I
k = int(np.shape(I)[0] * 0.01 / 2) * 2 + 1
G = cv2.GaussianBlur(G, (k, k), 0)
W = panoweight(G)
# 1 where pixels yet not yet accounted for
mask = np.ones_like(W)
all_lights = np.zeros_like(W)
total_energy = np.sum(W)
cnt = 1
while 1:
# find the next peak value
seed = np.amax(W * mask)
# find all values within energy_ratio of seed
curr_light = np.zeros_like(W)
curr_light[W * mask >= seed * energy_ratio] = 1
# mask out the connected component to seed
cc = measure.label(curr_light)
# get the component where seed was
seed_pos_1, seed_pos_2 = np.where(W * mask >= seed)
# mark the light
for c_ in cc[seed_pos_1, seed_pos_2]:
if c_:
all_lights[cc == c_] = cnt
# mask it out for next round
mask[cc == c_] = 0
cnt += 1
if np.sum(mask) < min_pixels_left or cnt > 15:
break
if np.sum(mask * W) < min_energy_wrt_max * total_energy:
# there is less than min_energy_wrt_max left in the image
break
all_lights_merge = all_lights.copy()
# Below are heuristics designed to tackle cases that occur in some images
if 1:
# Eliminate the cases where due to lack of sharp lights, almost the entire image/background is detected as one source.
# This should be handled in the ambient component not light segments.
props = measure.regionprops(all_lights_merge.astype(np.int))
img_area = np.shape(I)[0] * np.shape(I)[1]
for p in props:
if p.area / img_area > 0.5 or p.major_axis_length / np.shape(I)[1] > 0.9:
all_lights_merge[all_lights_merge == p.label] = 0
if 1:
# Merging of lights. Due to the thresholds, its possible to get nested lights in some cases.
# Hence we merge such cases
all_lights_merge[all_lights_merge > 0] = 1
all_lights_merge = morphology.dilation(all_lights_merge, square(2)).astype(np.int)
all_lights_merge = measure.label(all_lights_merge)
return all_lights_merge, W