使用 numpy and/or cv2 查找深度图中最暗的区域
Finding the darkest region in a depth map using numpy and/or cv2
我试图在从视频生成的一系列深度图图像中始终找到最暗的区域。深度图是使用 PyTorch 实现生成的 here
他们的示例 运行 脚本生成与输入相同大小的预测,其中每个像素都是浮点值,highest/brightest 值最接近。使用 ConvNets 的标准深度估计。
深度预测然后按如下方式归一化以制作 png 以供审查
bits = 2
depth_min = prediction.min()
depth_max = prediction.max()
max_val = (2**(8*bits))-1
out = max_val * (prediction - depth_min) / (depth_max - depth_min)
我正在尝试识别视频中每个图像中最暗的区域,并假设该区域最“开放”space。
我试过几种方法:
cv2
模板匹配
使用 cv2
模板匹配和 minMaxLoc
我创建了一个 np.zeros(100,100) 的模板,然后应用类似于 docs
的模板
img2 = out.copy().astype("uint8")
template = np.zeros((100, 100)).astype("uint8")
w, h = template.shape[::-1]
res = cv2.matchTemplate(img2,template,cv2.TM_SQDIFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = min_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
val = out.max()
cv2.rectangle(out,top_left, bottom_right, int(val) , 2)
如您所见,此实现与许多误报非常不一致
np.argmin
使用 np.argmin(out, axis=1)
生成许多索引。我取前两个,然后在那些坐标
处写下单词 MIN
text = "MIN"
textsize = cv2.getTextSize(text, font, 1, 2)[0]
textX, textY = np.argmin(prediction, axis=1)[:2]
cv2.putText(out, text, (textX, textY), font, 1, (int(917*max_val), int(917*max_val), int(917*max_val)), 2)
这不那么不一致,但仍然缺乏
np.argwhere
使用np.argwhere(prediction == np.min(preditcion)
然后在坐标处写上MIN
。我以为这会给我图像上最暗的像素,但事实并非如此
我也想过运行用50x50的核做一个卷积运算,然后取最小值的区域作为最暗的区域
我的问题是为什么会出现不一致和误报。我该如何解决?直觉上,这似乎是一件非常简单的事情。
更新
感谢汉斯的想法。请按照this link下载png格式的输出深度。
最小值不是一个点,通常是一个更大的区域。 argmin
找到该区域的第一个 x 和 y(左上角):
In case of multiple occurrences of the minimum values, the indices
corresponding to the first occurrence are returned.
你需要的是这个最小区域的中心。您可以使用 moments
找到它。有时您有多个最小区域,例如 frame107.png
。在这种情况下,我们通过找到面积最大的轮廓来取最大的一个。
我们仍然有一些跳跃标记,因为有时你有一个最小的区域,例如在 frame25.png
。因此,我们使用最小面积阈值 min_area
,即我们不使用绝对最小区域,而是使用大于或等于该阈值的所有区域中具有最小值的区域。
import numpy as np
import cv2
import glob
min_area = 500
for 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
有五个区域,其中图像 0
显示为增强伽玛:
frame25
最小区域非常小(红色箭头),我们取第五大最小区域(白色圆圈):
结果(对于 min_area=500
)在某些地方仍然有点跳动,但是如果你进一步增加 min_area
你会得到错误的结果,帧的下降非常陡峭(因此每值小)暗区。也许你可以使用时间轴(帧数)来过滤掉最暗区域的位置在3帧内来回跳跃的帧。
我试图在从视频生成的一系列深度图图像中始终找到最暗的区域。深度图是使用 PyTorch 实现生成的 here
他们的示例 运行 脚本生成与输入相同大小的预测,其中每个像素都是浮点值,highest/brightest 值最接近。使用 ConvNets 的标准深度估计。
深度预测然后按如下方式归一化以制作 png 以供审查
bits = 2
depth_min = prediction.min()
depth_max = prediction.max()
max_val = (2**(8*bits))-1
out = max_val * (prediction - depth_min) / (depth_max - depth_min)
我正在尝试识别视频中每个图像中最暗的区域,并假设该区域最“开放”space。
我试过几种方法:
cv2
模板匹配
使用 cv2
模板匹配和 minMaxLoc
我创建了一个 np.zeros(100,100) 的模板,然后应用类似于 docs
img2 = out.copy().astype("uint8")
template = np.zeros((100, 100)).astype("uint8")
w, h = template.shape[::-1]
res = cv2.matchTemplate(img2,template,cv2.TM_SQDIFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = min_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
val = out.max()
cv2.rectangle(out,top_left, bottom_right, int(val) , 2)
如您所见,此实现与许多误报非常不一致
np.argmin
使用 np.argmin(out, axis=1)
生成许多索引。我取前两个,然后在那些坐标
MIN
text = "MIN"
textsize = cv2.getTextSize(text, font, 1, 2)[0]
textX, textY = np.argmin(prediction, axis=1)[:2]
cv2.putText(out, text, (textX, textY), font, 1, (int(917*max_val), int(917*max_val), int(917*max_val)), 2)
这不那么不一致,但仍然缺乏
np.argwhere
使用np.argwhere(prediction == np.min(preditcion)
然后在坐标处写上MIN
。我以为这会给我图像上最暗的像素,但事实并非如此
我也想过运行用50x50的核做一个卷积运算,然后取最小值的区域作为最暗的区域
我的问题是为什么会出现不一致和误报。我该如何解决?直觉上,这似乎是一件非常简单的事情。
更新 感谢汉斯的想法。请按照this link下载png格式的输出深度。
最小值不是一个点,通常是一个更大的区域。 argmin
找到该区域的第一个 x 和 y(左上角):
In case of multiple occurrences of the minimum values, the indices corresponding to the first occurrence are returned.
你需要的是这个最小区域的中心。您可以使用 moments
找到它。有时您有多个最小区域,例如 frame107.png
。在这种情况下,我们通过找到面积最大的轮廓来取最大的一个。
我们仍然有一些跳跃标记,因为有时你有一个最小的区域,例如在 frame25.png
。因此,我们使用最小面积阈值 min_area
,即我们不使用绝对最小区域,而是使用大于或等于该阈值的所有区域中具有最小值的区域。
import numpy as np
import cv2
import glob
min_area = 500
for 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
有五个区域,其中图像 0
显示为增强伽玛:
frame25
最小区域非常小(红色箭头),我们取第五大最小区域(白色圆圈):
结果(对于 min_area=500
)在某些地方仍然有点跳动,但是如果你进一步增加 min_area
你会得到错误的结果,帧的下降非常陡峭(因此每值小)暗区。也许你可以使用时间轴(帧数)来过滤掉最暗区域的位置在3帧内来回跳跃的帧。