英文:
How to convert distances on perspective grid to head map
问题
我正试图将人眼可观察到的物体位置从由固定摄像机拍摄的图像数据转移到俯视的2D场景中,显示区域没有纹理信息,只有物体的名称和位置。
然而,我不知道如何在谷歌中搜索我所需要的信息。
这是我使用的网格。
这是透视网格图像。
这是相机位置的内部信息。
如果我说网格的每一边都是50厘米(因此一个正方形的区域是50x50),墙的高度是2.5米。
那么,有哪种方法可以用来生成一个热图,其中像素的颜色表示从墙到网格上的点的距离?
网格可以扩大到黑色空间。
以下是网格和透视网格的代码。
import cv2
import numpy as np
import imutils
# ...(此处省略了部分代码)
英文:
I am trying to transfer objects locations that can be observed by human eye on image data taken by fixed camera to 2d field displays the area from above without texture info but object names and location.
However, I don't know how to google that I need is below.
This is the grid I use.
This is the perspectived grid image.
And this is the insight how camera position is.
If I say that every side on grid is 50 centimeters(so area is 50x50 for one square), and wall height is 2.5 meters.
So which method can be used to generate an heat map which pixel colors tell the distance from wall to the point on grid?
The grid can be enlarged to black spaces.
The below code for grid and perspectived grid.
import cv2
import numpy as np
import imutils
img = np.zeros((480,640),dtype=np.uint8)
size = 40
for i in range(int(img.shape[1]/size)+1):
img = cv2.line(img, (i*size, 0), (i*size, img.shape[0]), thickness = 2, color = 255)
for i in range(int(img.shape[0]/size)+1):
img = cv2.line(img, (0, i*size), (img.shape[1], i*size), thickness = 2, color = 255)
cv2.imshow("img",img)
cv2.waitKey(0)
h, w = img.shape
a = [
[0, 0],
[h - 1, 0],
[0, w - 1],
[h - 1, w - 1]]
pt_A = a[0]
pt_B = a[1]
pt_C = a[2]
pt_D = a[3]
width_AD = np.sqrt(((pt_A[0] - pt_D[0]) ** 2) + ((pt_A[1] - pt_D[1]) ** 2))
width_BC = np.sqrt(((pt_B[0] - pt_C[0]) ** 2) + ((pt_B[1] - pt_C[1]) ** 2))
maxWidth = max(int(width_AD), int(width_BC))
height_AB = np.sqrt(((pt_A[0] - pt_B[0]) ** 2) + ((pt_A[1] - pt_B[1]) ** 2))
height_CD = np.sqrt(((pt_C[0] - pt_D[0]) ** 2) + ((pt_C[1] - pt_D[1]) ** 2))
maxHeight = max(int(height_AB), int(height_CD))
input_pts = np.float32([pt_A, pt_B, pt_C, pt_D])
output_pts = np.float32([[800, 600], [900, 300], [-300, 500], [100, 200]])
def perspective(img, input_pts=input_pts, output_pts=output_pts, maxWidth=maxWidth, maxHeight=maxHeight):
M = cv2.getPerspectiveTransform(input_pts,output_pts)
out = cv2.warpPerspective(img,M,(maxWidth, maxHeight),flags=cv2.INTER_LINEAR)
out = imutils.resize(out,height=500)
return out
frame = perspective(img)
# Display image
cv2.imshow('frame', frame)
cv2.waitKey(0)
答案1
得分: 0
距离可以用毕达哥拉斯定理来计算:
然后将结果映射到颜色并相应显示:
import cv2
import numpy as np
img = np.zeros((480, 640), dtype=np.uint8)
size = 40
for i in range(int(img.shape[1] / size) + 1):
img = cv2.line(img, (i * size, 0), (i * size, img.shape[0]), thickness=2,
color=255)
for i in range(int(img.shape[0] / size) + 1):
img = cv2.line(img, (0, i * size), (img.shape[1], i * size), thickness=2,
color=255)
cv2.imshow("img", img)
cv2.waitKey(0)
h, w = img.shape
a = [
[0, 0],
[h - 1, 0],
[0, w - 1],
[h - 1, w - 1]]
pt_A = a[0]
pt_B = a[1]
pt_C = a[2]
pt_D = a[3]
width_AD = np.sqrt(((pt_A[0] - pt_D[0]) ** 2) + ((pt_A[1] - pt_D[1]) ** 2))
width_BC = np.sqrt(((pt_B[0] - pt_C[0]) ** 2) + ((pt_B[1] - pt_C[1]) ** 2))
maxWidth = max(int(width_AD), int(width_BC))
height_AB = np.sqrt(((pt_A[0] - pt_B[0]) ** 2) + ((pt_A[1] - pt_B[1]) ** 2))
height_CD = np.sqrt(((pt_C[0] - pt_D[0]) ** 2) + ((pt_C[1] - pt_D[1]) ** 2))
maxHeight = max(int(height_AB), int(height_CD))
input_pts = np.float32([pt_A, pt_B, pt_C, pt_D])
output_pts = np.float32([[800, 600], [900, 300], [-300, 500], [100, 200]])
def perspective(img, input_pts=input_pts, output_pts=output_pts,
maxWidth=maxWidth, maxHeight=maxHeight):
M = cv2.getPerspectiveTransform(input_pts, output_pts)
out = cv2.warpPerspective(img, M, (maxWidth, maxHeight),
flags=cv2.INTER_LINEAR)
return out
def calc_distance(cam_pos, img, tile_px, tile_size=50):
"""计算相机与地板之间的欧氏距离。"""
cam_pos_x, cam_pos_y, cam_pos_z = cam_pos
floor_size_x = int(img.shape[1] / tile_px) * tile_size
floor_size_y = int(img.shape[0] / tile_px) * tile_size
floor_pos_x, floor_pos_y = np.meshgrid(
np.arange(img.shape[1]) / img.shape[1] * floor_size_x,
np.arange(img.shape[0]) / img.shape[0] * floor_size_y)
floor_pos_z = 0
return np.sqrt(
(floor_pos_x - cam_pos_x) ** 2 + (floor_pos_y - cam_pos_y) ** 2 + (
floor_pos_z - cam_pos_z) ** 2)
# 计算并归一化距离到[0, 255]
cam_pos = [0,0,250]
distance = calc_distance(cam_pos, img, size)
distance_img = ((distance - distance.min()) / (distance.max() - distance.min()) * 255).astype(np.uint8)
# 创建颜色编码的距离图像,去除非网格部分,显示透视图像
distance_img = cv2.applyColorMap(distance_img, cv2.COLORMAP_PARULA)
distance_img_grid = distance_img * img[..., None] / img.max()
frame = perspective(distance_img_grid)
# 显示图像
cv2.imshow('frame', frame)
cv2.waitKey(0)
英文:
The distance can be calculated in a pythagorean way:
The result then can be mapped to a color and displayed accordingly:
import cv2
import numpy as np
img = np.zeros((480, 640), dtype=np.uint8)
size = 40
for i in range(int(img.shape[1] / size) + 1):
img = cv2.line(img, (i * size, 0), (i * size, img.shape[0]), thickness=2,
color=255)
for i in range(int(img.shape[0] / size) + 1):
img = cv2.line(img, (0, i * size), (img.shape[1], i * size), thickness=2,
color=255)
cv2.imshow("img", img)
cv2.waitKey(0)
h, w = img.shape
a = [
[0, 0],
[h - 1, 0],
[0, w - 1],
[h - 1, w - 1]]
pt_A = a[0]
pt_B = a[1]
pt_C = a[2]
pt_D = a[3]
width_AD = np.sqrt(((pt_A[0] - pt_D[0]) ** 2) + ((pt_A[1] - pt_D[1]) ** 2))
width_BC = np.sqrt(((pt_B[0] - pt_C[0]) ** 2) + ((pt_B[1] - pt_C[1]) ** 2))
maxWidth = max(int(width_AD), int(width_BC))
height_AB = np.sqrt(((pt_A[0] - pt_B[0]) ** 2) + ((pt_A[1] - pt_B[1]) ** 2))
height_CD = np.sqrt(((pt_C[0] - pt_D[0]) ** 2) + ((pt_C[1] - pt_D[1]) ** 2))
maxHeight = max(int(height_AB), int(height_CD))
input_pts = np.float32([pt_A, pt_B, pt_C, pt_D])
output_pts = np.float32([[800, 600], [900, 300], [-300, 500], [100, 200]])
def perspective(img, input_pts=input_pts, output_pts=output_pts,
maxWidth=maxWidth, maxHeight=maxHeight):
M = cv2.getPerspectiveTransform(input_pts, output_pts)
out = cv2.warpPerspective(img, M, (maxWidth, maxHeight),
flags=cv2.INTER_LINEAR)
return out
def calc_distance(cam_pos, img, tile_px, tile_size=50):
"""Calculate eucledian distance between camera and floor."""
cam_pos_x, cam_pos_y, cam_pos_z = cam_pos
floor_size_x = int(img.shape[1] / tile_px) * tile_size
floor_size_y = int(img.shape[0] / tile_px) * tile_size
floor_pos_x, floor_pos_y = np.meshgrid(
np.arange(img.shape[1]) / img.shape[1] * floor_size_x,
np.arange(img.shape[0]) / img.shape[0] * floor_size_y)
floor_pos_z = 0
return np.sqrt(
(floor_pos_x - cam_pos_x) ** 2 + (floor_pos_y - cam_pos_y) ** 2 + (
floor_pos_z - cam_pos_z) ** 2)
# calculate and normalize distance to [0, 255]
cam_pos = [0,0,250]
distance = calc_distance(cam_pos, img, size)
distance_img = ((distance - distance.min()) / (distance.max() - distance.min()) * 255).astype(np.uint8)
# create color coded distance image, remove non-grid parts, show perspective img
distance_img = cv2.applyColorMap(distance_img, cv2.COLORMAP_PARULA)
distance_img_grid = distance_img * img[..., None] / img.max()
frame = perspective(distance_img_grid)
# Display image
cv2.imshow('frame', frame)
cv2.waitKey(0)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论