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)
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)