Finding the darkest region in a depth map using numpy and/or cv2 Finding the darkest region in a depth map using numpy and/or cv2 numpy numpy

Finding the darkest region in a depth map using numpy and/or cv2


The minimum is not a single point but as a rule a larger area. argmin finds the first x and y (top left corner) of this area:

In case of multiple occurrences of the minimum values, the indicescorresponding to the first occurrence are returned.

What you need is the center of this minimum region. You can find it using moments. Sometimes you have multiple minimum regions for instance in frame107.png. In this case we take the biggest one by finding the contour with the largest area.

We still have some jumping markers as sometimes you have a tiny area that is the minimum, e.g. in frame25.png. Therefore we use a minimum area threshold min_area, i.e. we don't use the absolute minimum region but the region with the smallest value from all regions greater or equal that threshold.

import numpy as npimport cv2import globmin_area = 500for file in glob.glob("*.png"):    img = cv2.imread(file, cv2.IMREAD_GRAYSCALE)    for i in range(img.min(), 255):        if np.count_nonzero(img==i) >= min_area:            b = np.where(img==i, 1, 0).astype(np.uint8)            break    contours,_ = cv2.findContours(b, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)    max_contour = max(contours, key=cv2.contourArea)    m = cv2.moments(max_contour)    x = int(m["m10"] / m["m00"])    y = int(m["m01"] / m["m00"])    out = cv2.circle(img, (x,y), 10, 255, 2 )    cv2.imwrite(file,out)

frame107 with five regions where the image is 0 shown with enhanced gamma:enter image description here

frame25 with very small min region (red arrow), we take the fifth largest min region instead (white cirle):enter image description here

The result (for min_area=500) is still a bit jumpy at some places, but if you further increase min_area you'll get false results for frames with a very steeply descending (and hence small per value) dark area. Maybe you can use the time axis (frame number) to filter out frames where the location of the darkest region jumps back and forth within 3 frames.

output for min_area=500