object dimensions in image according to camera distance faraway - image

I have a camera placed 10 meters faraway from a portrait (rectangle) having width = 50cm and height = 15cm, I want to get the dimensions of this portrait inside the image captured. The image captured has width=800 px and height=600 px.
How can I calculate the dimensions of the portrait inside the image? Any help please?

I am assuming the camera is located along the center normal of the portrait, looking straight at the portrait's center.
Let's define some variables.
Horizontal field of view: FOV (you need to specify)
Physical portrait width: PW = 50 cm
Width of portrait plane captured: CW cm (unknown)
Image width: IW = 800 px
Width of portrait in image space: X px (unknown)
Distance from camera to subject: D = 10 m
We know tan(FOV) = (CW cm) / (100 * D cm). Therefore CW = tan(FOV) * 100 * D cm.
We know PW / CW = X / IW. Therefore X = (IW * PW) / (tan(FOV) * 100 * D) px.

I agree with Timothy's answer, in that you need to the know the camera's field of view (FOV). I'm not sure I totally follow/agree with his method however. I think this is similar, but it differs, the FOV needs to be divided by two to split our view into two right-angled triangles. Use tan(x)=opposite/adjacent
tan(FOV/2) = (IW/2) / (Dist * 100)
where IW is the true image width (must divide by two as we are only finding finding half of the width with the right-angled triangle), Dist is the distance from the camera to the portrait (converted to cm).
Rearrange that to find the Width of the entire image (IW):
IW = tand(FOV/2) * (2*Dist*100)
You can now work out the width of each pixel (PW) using the number of pixels in the image width (800 for you).
PW = IW / NumPixels
PW = IW / 800
Now divide the true width by this value to find the number of pixels.
PixelWidth = TrueWidth / PW
The same can be done for the height, but you need your camera's field of view.
Im not sure this is the same a Timothy's answer, but I'm pretty sure this is correct.

Related

Calculating the width of the YOLO bounding box in pixels

I am trying to find the width of the bounding box of the output image in pixels:
In this article, it says YOLO v3 extracts coordinates and dimensions of the bounding box (line 82). YOLO returns bounding box coordinates in the form:
(centerX, centerY, width, and height)
Are these coordinates, width and height, real pixel values? Or do they perform scaling on them?
Can I print out the value of width and consider it as a real pixel value for the width of the aforementioned box?
Please note that my question is about YOLO v3.
Those are what are called normalized coordinates. To get the width in pixels you would need to multiply by the width of the images. For example if your image 640x480 than multiple the width values outputted by Yolo by the width of the image.
If the numbers in your screenshot are the width:
Dog width = .98 * 640 = 627 px
Cat width = .88 * 563 = 563 px

Find the new position of rectangle for resized image

I have a four element position vector [xmin ymin width hight] that specifies the size and position of crop rectangle from image I. How can i find the new position and size for the resized image I?
It is not entirely clear, what you want, as we don't know your coordinate system. Assuming x is the horizontal axis and y is the vertical axis and your point (1,1) is at the top left corner, you can use the following snippet:
p = [xmin ymin width height];
I = I_orig(p(2):p(2)+p(4)-1,p(1):p(1)+p(3)-1);
The size is of course your specified width and height.
You can convert your original bounding box to relative values (that is assuming the image size is 1x1)
[origH origW] = size( origI(:,:,1) );
relativeBB = [xmin / origW, ymin / origH, width / origW, hight / origH];
Now, no matter how you resized your origI, you can recover the bounding box w.r.t the new size from the relative representation:
[currH currW] = size(I(:,:,1));
currBB = relativeBB .* [currW, currH, currW, currH];
You might need to round things a bit: you might find floor better for xmin and ymin and ceil more suitable for width and height.

zoom an image to fit a screen horizontally - algorithm

This is a general question regarding an algorithm to zoom an image to fit the width of a screen, there are some givens and some constraints. We can assume we are using Java but this question is more mathematical that language dependent.
First of all, the image loads and fits into the dimensions of the screen vertically first, not horizontally.
We can get the dimensions of the screen and the dimensions of the image with methods, but we cannot set the dimensions of either (We only have getters not setters).
imageWidth = image.getWidth(); //integer
imageHeight = image.getHeight(); //integer
screenWidth = screen.getWidth(); //integer
screenHeight = screen.getHeight(); //integer
The only method to resize the image is by setting scale (zooming essentially).
image.setScale(some float); // optionally image.setZoom(integer);
What I would like to know is how to calculate the scale (zoom) level for some l x h image so that it fits a L x H screen horizontally?
All you have to do to make the Image fill your screen is scale along the x axis:
scaling_factor = screen.getWidth()/image.getWidth()
image.setScale(zoom_factor);
The formula is very intuitive:
The image height is irrelevant. The scaling you desire would be the same for a landscape and vertical image, as long as the width of both images are the same
When the image's width increases, your scaling factor decreases
When your screen size increses, the scaling factor increases.

Image scaling inside a canvas

Let's assume we have a container with the size of 500 x 300 (w x h).
Inside this container we have a canvas with the same size, but with a different reference system inside it, with the size of 700 x 1000.
When I put an image of 700 x 1000 in this canvas it will obviously appear distorted, because the canvas occupies the entire 500 x 300 pixels of its parent container - even if inside it is still 700 x 1000.
Now, I am trying to figure out a formula to scale the image in the interlal reference system so the image doesn't appear distorted then loaded in the canvas.
Can anybody help?
First of all, if you have w = 700, h = 1000, i.e. w_container / w_canvas = 5/7 != h_container / h_canvas = 3/10, you will not be able to load you image not being distorted and taking entire space of the container. I just can tell you how to resize your image properly.
To save the width-height ratio of your image (equals 7/10, I think this is what you mean under "distorted image") you should calculate how your image's ratio rescales after putting the image on the canvas.
canvas_ratio(7/10) * x = container_ratio(5/3), hence x = 50/21. So if your image has the ratio y, then it will become y*x = y*50/21.
So you should just resize your image before putting it on the canvas such a way that after multiplying this ratio by x it would be 7/10 (the ratio when your image looks perfect). We have an equation y*50/21 = 7/10, hence y = 147/500. That's the ratio your image should have!
For example, you can make image size 294x1000, and after putting it to the canvas it will have height of 300 pixels in your container's coordinate system and 294*(500/700) = 210 pixel width (unfortunately, not 500). Hope this will be useful information for you.
Good luck!

Little Math-help for image resize needed

I have an Image with the Value X width and Y height.
Now I want to set the height ever to 60px.
With which calculation I can calculate the height that the image is correct resized?
I think you are trying to maintain aspect ratio. If so use the following:
ratio = orginialHeight / newHeight
newWidth = orginialWidth * ratio
I assume you want the width after the rescale to relate to the height in the same way it did before the rescale, i.e. you want the aspect ratio to remain constant.
aspect_ratio = width_old / height_old
This gives:
aspect_ratio = width_new / height_new
Thus
width_new = width_old * height_new / height_old
Which means
width_new = (60 * width_old) / height_old
For instance, assume an incoming image of 640x480 (plain old VGA). This has an aspect_ratio of 1.33333...
Rescaling this to be 60 pixels high would then require a new width of 60 * 640 / 480, or 80, which seems proper since 80/60 is indeed 1.3333...
You want to maintain an aspect ratio of y/x, which means that you need to compute y/x for the original image. Let z = y/x, then, given any new height y' (in your case, 60 px), to find the new width x':
y/x = z = y'/x'
x' = y' * z

Resources