How to measure distance between 2 objects in a video? - Edited
Hello My name is Felipe and I'm from Chile. I'm currently making a project with 2 points and measuring the dinstance between them in real time. I know it can be done with images, but I can't find a real solution with videos. I made a mask and then erotionate to recognize the colours that I need. I think that the next step is labeling them, and then get the distance. The two objects I will move them up and down, and I need to measure the distance between them in real time. Here is an image to show how it shows until now.
-------------------------EDIT----------------------------- Now i can recognize an measure "distance" beetween the 2 points, but the values that I get appears to be in pixel values not in cm or inches. I dont know if somebody con confirmate that. Now I have to export that values to a txt or csv file, because I need to send it in real time trough google drive in a spreedsheet. So my questions now if you can help me with export that values in a file, and if is possible to show the values more slow, i mean like one value per second, because it shows so fast, and propably it will be so fast to the spreadsheet. (I hope you can understand my english hahaha) Thank you again to everyone who respond. my code is currently this
import cv2
import numpy as np
#Captura de video a traves de la webcam
cap=cv2.VideoCapture(0)
while(1):
d=0.1
centers=[]
_, img = cap.read()
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) #Se obtiene un histograma basada en las saturaciones de colores.
blue_lower=np.array([80,150,100],np.uint8)
blue_upper=np.array([150,255,255],np.uint8)
blue=cv2.inRange(hsv,blue_lower,blue_upper) #Se crea una mascara utilizando intervalos de color azul.
kernal = np.ones((5 ,5), "uint8") #Crea una matriz de 5x5 la cual recorrera el video,
blue=cv2.erode(blue,kernal, iterations=1) #Se erosiona utilizando el kernel sobre la mascara.
res1=cv2.bitwise_and(img, img, mask = blue) #La nueva imagen reemplazara a blue.
(_,contours,hierarchy)=cv2.findContours(blue,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #Encuentra los contornos de los objetos que se ven en el filtro
for pic, contour in enumerate(contours):
area = cv2.contourArea(contour) #funcion de opencv que obtiene los contornos
if(area>300):
x,y,w,h = cv2.boundingRect(contour) #Encuentra coordenadas de los contornos.
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.putText(img,"Marcador",(x,y),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,0,0))
M = cv2.moments(contour) #Se obtiene el centro de masa de los marcadores enconrados.
cx = int(M['m10'] /M['m00'])
cy = int(M['m01'] /M['m00'])
centers.append([cx,cy])
cv2.circle(img, (cx, cy), 7, (255, 255, 255), -1)
if len(centers)==2:
D = np.linalg.norm(cx-cy) #Se aplica distancia euclidiana para encontrar la distancia entre los centros de ...
I did something like this a little while ago. What I did was loop through the image's pixels and flood filling any white pixels (sections) using a unique colour. From there I calculated the centre of each coloured section (that is, the centre is in terms of pixels), and the distance calculation is done between the centres. Getting the rays from the camera to the card centres is pretty simple trigonometry, based on the distance of the cards from the camera; this would give you the distance in real life. Here's some code to convert a pixel location to a point along an image plane 1 unit of distance in front of the camera:
https://www.gamedev.net/forums/topic/...
Are you familiar with posting code on GitHub?
P.S. I'm considering the video to be merely a bunch of still images, and it's on these images that I calculate the centres. So, it doesn't really matter that it's a video versus an image, right?
I made a code that marks the centres of each section in the image:
https://github.com/sjhalayka/mask_dis...
Note that there's 3 sections... so you would need to find the centres from the two largest sections. Fortunately, the code creates a std::multiset that sorts the sections in terms of size, so that's always a bonus.
@sjhalayka Why such a complicated solution? Couldn't him finding the contours, then calculate their moments along with their mass centers then find the euclidean distance between them accomplish what he wants without any camera calibrations and stuff? I am just curious why you did it that way.
Inexperience, mostly. I'll work on a code that does what you describe.
So basically you want to measure the distance in space between the two cards? Do you have your camera matrices? You'd likely need to have the depth map of the cards. Does your camera give you a depth map?
I don't know how it all works in OpenCV yet, but with the OpenGL camera it is pretty easy to solve to the distance problem once the Z-buffer is used: you just trace rays.
Yes, I would like to measure the distance between the two centers in cm, but I don't know how to get the depth map of my camera, any idea to do it in opencv?
Do you have a Kinect? Perhaps your camera just simply doesn't get depth maps because it doesn't have a depth sensor.
Dear Felipe, My name is Nam, and I'm working on a project, in which I want to measure the distance between 2 objects in a 30 seconds video. I would like to learn about this software. If you can please contact me at this email: [email protected]. Thank you so much for your time.