Distance or Speed Estimation from 2D Image - opencv

I want to estimate vehicle speed. For calibration (converting pixels to meter) I only have two photos from camera.
In the first photo one vehicle is on top of the image (Photo 1).
In the second photo the same vehicle is moved for 12 meters (Photo 2).
The information that I have in meters includes:
Movement Distance in meters (Purple line)
License plate dimensions (X, Y -> its width and height in meters)
H Height of the license plate from the ground in meters
I want to know how can I write a function with these information to take an arbitrary license plate L (i.e. its width and height and location on the image in pixels) and return the distance from the first photos license plate (or any arbitrary location) in meters (Orange lice marked as Question?).
If the camera were in the top of the road we could simply convert pixels to meter but in perspective view I do not know how can I do this if it is possible?
The problem is when vehicle is small for example 5 pixel of movement (up -> down) is about 0.5 meter and when vehicle is near the camera and is larger 5 pixels is about 0.2 meter (Numbers are just for example).
Update:
Using a third point between Photo 1 and Photo 2 I created a polynomial function with two degrees (a + bx + cx^2) and now I can calculate distance. I measured speed and the result is about ±4 Km/h.
In the following picture X is start height of the license plate in pixels and Y is the distance in meters.

Related

How to calculate the distance between object and camera, knowing the pixels occupied by the object in an image

By using the segmentation I am able to find the number of pixels occupied by an object in an image. Now I need to kind the distance by using the pixels occupied.
object real dimensions (H x W) = 11 x 5.5 cm.
The object is placed at 50 cm distance pixels occupied are = 42894
The object is placed at 60 cm distance pixels occupied are = 31269.
The total pixel in an image = 480 x 640 = 307200.
what is the distance if the image occupies 22323 pixels ???
The distance to the object is 67.7cm
Please read https://en.wikipedia.org/wiki/Pinhole_camera_model
Image size is inversely proportional to the distance. Repeat your experiement for a few distances and plot a size vs distance to see for yourself.
Of course this is a simplyfied model that only works for a fixed focal length.

Calculate image size of an object from real size

I try to place a car(2D image of the car) on the road in the image, but I need to calculate a car size in pixels for the chosen horizontal position. I've found this
formula. It has object height(mm) which I need, but I don't have a distance to object(mm). Is there any way to calculate the distance from the camera to the horizontal line where car placed?
I knew camera matrix(fx,fy,cx,cy) and the real size of the car
If you know the size of the car, then it is possible to know the distance to it. However, you also need the information from the sensor size and focal position.
As depicted in this image , the distance D can be deduced from d, h and H by a simple conversion: d/D = h/H. Therefore, D=(H*d)/h. With h the size of the sensor in pixel, d the focal distance in mm and H the object size in pixels. D is the distance to the object in mm.

OpenCV: X and Y angles of a particular pixel knowing both hFOV and vFOV

Once that I calibrated my camera and I know horizontal and vertical fields of view (through OpenCV's calibrationMatrixValues function), is it possible to know the X and Y angles (from the center) of a particular pixel?
Suppose I have a camera with fields of view of 100° (h) and 80° (v) and a resolution of 500x400. The angle/pixel ratio is (0.2°, 0.2°). So the central pixel will be (0°, 0°), its left neighbor (-0.2°, 0), the topmost central pixel (0°, +40°) and so on.
Is actually this relation constant through all the image or there is a formula to perform this calculation? Is the obtained information reliable?
This is going to be the first step for triangulating objects in a multi camera environment.

calculate the real distance between to point using image

I do some image processing task in 3D and I have a problem.
I use a simulator which provides me an special kind of cameras which can tell the distance between the position of camera and any arbitrary point, using the pixels of that point in the image of camera. For example I can get the distance between camera and the object which is placed in pixel 21:34.
Now I need to calculate the real distance between two arbitrary pixels in the image of camera.
It is easy when camera is vertical and placed on the above of the field and all objects are on the ground but when camera is horizontal the depth of objects in image is different.
So, how should I do?
Simple 3D reconstruction will accomplish this. The distance from camera to points in 3D is along optical axis that is Z, which you already have. You will need X, Y as well:
X = u*Z/f;
Y = v*Z/f,
where f is camera focal length in pixels, Z your distance in mm or meters and u,v is an image centered coordinates: u = column-width/2, v = height/2-row. Note the asymmetry due to the fact that rows go down while Y and v go up. As soon as you get your X, Y, Z the distance in 3D is given by Euclidean formula:
dist = sqrt((X1-X2)2+(Y1-Y2)2+(Z1-Z2)2)

OpenCV: measuring distance between two balls in millimeters - how to improve accuracy

I also posted this topic in the Q&A forum at opencv.org but I don't know how many experts from here are reading this forum - so forgive me that I'm also trying it here.
I'm currently learning OpenCV and my current task is to measure the distance between two balls which are lying on a plate. My next step is to compare several cameras and resolutions to get a feeling how important resolution, noise, distortion etc. is and how heavy these parameters affect the accuracy. If the community is interested in the results I'm happy to share the results when they are ready! The camera is placed above the plate using a wide-angle lens. The width and height of the plate (1500 x 700 mm) and the radius of the balls (40 mm) are known.
My steps so far:
camera calibration
undistorting the image (the distortion is high due to the wide-angle lens)
findHomography: I use the corner points of the plate as input (4 points in pixels in the undistorted image) and the corner points in millimeters (starting with 0,0 in the lower left corner, up to 1500,700 in the upper right corner)
using HoughCircles to find the balls in the undistorted image
applying perspectiveTransform on the circle center points => circle center points now exist in millimeters
calculation the distance of the two center points: d = sqrt((x1-x2)^2+(y1-y2)^2)
The results: an error of around 4 mm at a distance of 300 mm, an error of around 25 mm at a distance of 1000 mm But if I measure are rectangle which is printed on the plate the error is smaller than 0.2 mm, so I guess the calibration and undistortion is working good.
I thought about this and figured out three possible reasons:
findHomography was applied to points lying directly on the plate whereas the center points of the balls should be measured in the equatorial height => how can I change the result of findHomography to change this, i.e. to "move" the plane? The radius in mm is known.
the error increases with increasing distance of the ball to the optical center because the camera will not see the ball from the top, so the center point in the 2D projection of the image is not the same as in the 3D world - I will we projected further to the borders of the image. => are there any geometrical operations which I can apply on the found center to correct the value?
during undistortion there's probably a loss of information, because I produce a new undistorted image and go back to pixel accuracy although I have many floating point values in the distortion matrix. Shall I search for the balls in the distorted image and tranform only the center points with the distortion matrix? But I don't know what's the code for this task.
I hope someone can help me to improve this and I hope this topic is interesting for other OpenCV-starters.
Thanks and best regards!
Here are some thoughts to help you along... By no means "the answer", though.
First a simple one. If you have calibrated your image in mm at a particular plane that is distance D away, then points that are r closer will appear larger than they are. To get from measured coordinates to actual coordinates, you use
Actual = measured * (D-r)/D
So since the centers of the spheres are radius r above the plane, the above formula should answer part 1 of your question.
Regarding the second question: if you think about it, the center of the sphere that you see should be in the right place "in the plane of the center of the sphere", even though you look at it from an angle. Draw yourself a picture to convince yourself this is so.
Third question: if you find the coordinates of the spheres in the distorted image, you should be able to transform them to the corrected image using perspectiveTransform. This may improve accuracy a little bit - but I am surprised at the size of errors you see. How large is a single pixel at the largest distance (1000mm)?
EDIT
You asked about elliptical projections etc. Basically, if you think of the optical center of the camera as a light source, and look at the shadow of the ball onto the plane as your "2D image", you can draw a picture of the rays that just hit the sides of the ball, and determine the different angles:
It is easy to see that P (the mid point of A and B) is not the same as C (the projection of the center of the sphere). A bit more trig will show you that the error C - (A+B)/2 increases with x and decreases with D. If you know A and B you can calculate the correct position of C (given D) from:
C = D * tan( (atan(B/D) + atan(A/D)) / 2 )
The error becomes larger as D is smaller and/or x is larger. Note D is the perpendicular (shortest) distance from the lens to the object plane.
This only works if the camera is acting like a "true lens" - in other words, there is no pincushion distortion, and a rectangle in the image plane maps into a rectangle on the sensor. The above combined with your own idea to fit in the uncorrected ('pixel') space, then transform the centers found with perspectiveTransform, ought to get you all the way there.
See what you can do with that!

Resources