Translating coordinates of two pictures - python

I'm trying to translate coordinates from one picture (Res: 311, 271) to another picture (Res: 1920, 1080).
The coordinates don't need to be accurate in the 2nd picture, it just needs to be the same vector relative to the center of the images
Don't know if that makes sense...
Edit:
So far I've tried to calculate the difference between the center of the first image and the coordinates and then apply them to the bigger image. However this doesn't seem to work very consistently.

You'll need to use trigonometry.
Say there's some object in the image you're trying to get the vector for. Given the x and y distances from the center of the original image, you can tabulate the angle and hypotenuse distance. Simply use the same angle and scale the hypotenuse distance with the new size image.

Related

Calculating positions of objects as (x,y) on a known platform (opencv-python)

I have a platform which I know the sizes. I would like to get the positions of objects placed on it as (x,y) while looking through the webcam, the origin being the top-left corner of the platform. However, I can only look through from a low angle: example
I detect the objects using the otsu threshold. I want to use the bottom edge of the bounding rectangles, then proportion it accordingly concerning the corners (the best I can think of), but I don't know how to implement it. I tried warp perspective but it enlarges the objects too much. image with threshold // attempt of warp perspective
Any help or suggestion would be appreciated.
Don't use warp perspective to transform the image to make the table cover the complete image as you did here.
While performing perspective transformations in image processing, try not to transform the image too much.
Below is the image with your table marked with red trapezium that you transformed.
Now try to transform it into a perfect rectangle but you do not want to transform it too much as you did. One way is to transform the trapezium to a rectangle by simply adjusting the shorter edge's vertices to come directly above the lower edge's vertices as shown in the image below with green.
This way, things far from the camera will be skewed wrt width only a little. This will give better results. Another even better way would be to decrease the size of the lower edge a little and increase the size of the upper edge a little. This will evenly skew objects kept over the table as shown below.
Now, as you know the real dimensions of the table and the dimensions of the rectangle in the image, you can do the mapping. Using this, you can determine the exact position of the objects kept on the table.

Numpy- how to sample a line in world coordinates to pixel coordinates

I have a line given as
x1,x2, y1,y2.
In WORLD coordinates.
Assuming we place the image plane, whose center (or corner) is at xc,yc, and whose resolution is w,h pixels.
I would like to get an efficient way of getting the list of pixels of the given line, sampled at the picture's pixels it intersects
I am aware of the bresenham algorithm, but a pythonic implementation is slow.
Is there a numpy way of doing this?
Is there another python library for doing this?
Is there a way to do this for many lines, all in some vectorized way?
Thanks!

Python subpixel-accurate image crop

I need to crop an image with subpixel accuracy. For example, I might need to create an interpolated rectangular crop with corners (108.5, 350.9) and (368.3, 230.1) out of an image with dimensions 640x480. How can I achieve this?
Edit: It's a reasonable concession to stretch the cropped area to fit it into a data matrix. However you can't just change the borders of the crop to integer coordinates.
Well I'm not sure if I can call this an answer because I don't really know what your question is but I try to shed some light on you.
So I guess your problem arises from some misconception.
First of all DPI, PPI or whatever you want to use is nothing but a factor that tells you how many dots, points, pixels you have per inch. That factor allows you to determin print sizes or convert between pixel dimensions and inch dimensions.
That's by no means related to cropping an image.
Cropping a rectangular region is a very common task.
Also having ROIs with sub-pixel coordinates is pretty common as their coordinates often arise from calculations that yield non-integer values.
Usually you simply round coordinates to integers so your problem vanishes.
If you want to get intensity values for sub-pixel coordinates you can interpolate between neigbouring pixels. But as images cannot have half pixels you will have to store that information in an image that has more or less pixels.
So here's what I would do if I didn't want to use rounded coordinates.
If my coordinate is >= x.5 I'd add a column or row, otherwise I'd skip the pixel.
If I would add a column or row I would interpolate it's values.
But to be honest I don't see any use case for this and I never had to do anything but using integer coordinates for cropping in my career.
You cannot print fractions of pixels and you cannot display them either, so what's the point?
The solution seems to require that you calculate the center of the rectangle that you want to crop out of the image, and the height and width of the rectangle as well. Then just scale up the entire image until the desired rectangle has integer dimensions, then do a usual crop. You will have to scale the horizontal and vertical dimensions by separate amounts, so this will slightly distort the cropped portion and you will have to adjust for the distortion in the image encoding format you use.

Determining the pattern orientation of a spatiotemporal image

How can I obtain average direction of the pattern shown in the figure below. It is the direction of the red arrow relative to the yellow (horizontal) line. Any ideas for an approach? I couldn't figure out a way to approach. This is a spatio-temporal image created from a video. Thank you.
Here is my original image:
The simplest approach would be to compute the gradient vector (x derivative and y derivative) and find its direction at each pixel (atan2(y,x)). The average orientation is what you want, not the average direction (will cancel out). So apply modulus pi, then average across the image.
The best way to compute image gradients is through the Gaussian gradients.
The structure tensor is the more robust way of accomplishing this. In short, it computes local averages of the gradient vector to reduce the effect of noise. It does this by computing the outer product of the gradient vector with itself, which produces a symmetric matrix. The individual components of this matrix can then be locally averaged (i.e. apply a smoothing filter). This is similar to computing the angle of the vectors, doubling the angles to make vectors in opposite directions equal, then averaging them.
Note that you can apply either of these solutions in 3D (you can think of the video data as 2D + time = 3D). That way, you compute both the speed and the direction of motion within the 2D frame, rather than just the speed along the direction in which you extracted the 2D image you show in the question. The image gradient and the concept of the structure tensor easily extend to 3D. This 3D approach is similar to the approach by Lucas-Kanade for optical flow. If you follow that link to Wikipedia, you'll see it uses the structure tensor in 2D, and adds gradients along the time dimension.
Might be useful to try Fourier transform.
In your case you should get two vertical lines in the middle of the transformed image corresponding to the information when traveling vertically in the image.
On the other hand there shouldn't be a horizontal line since when traveling horizontally in the image there is little information (little change)
For example you can use this online site to play with fourier transforms:
https://www.ejectamenta.com/Fourifier-fullscreen/
It might sound like the problem remains the same but in fact it is much easier now.
The 2D pattern is converted into dominant lines which are quite easy to find in the transformed image.
For example you can search for the strongest pixels in the image and simply determine if they are more likely to be horizontal line or a vertical line or determine the angle of the dominant line. Then rotate by 90 degrees.
For example see this image of wood grain and the resulting transformed image:
And don't worry about the two lines. The image is symmetric so just ignore 3/4 of the image and look in 1 quarter.
I recommend giving the Hough transform a go, it is available in OpenCv. The Hough transform maps lines to angles, and might be useful in your case.

Why are my images not being cropped appropriately?

I have a data set of different images. After drawing ellipses, I want to crop them.
I drew ellipses on them. The actual ellipses are the blue ones. The green ones are just how they look like with their angle 0 degrees.
I am using numpy array slicing to get the cropped image:
output_image[y-(minor_axis/2):y+(minor_axis/2), x-(major_axis/2):x+(major_axis/2)]
However the result isn't as it should be. For example the result of the large ellipse looking like an oval is as follows:
I first thought that it is happening because I am using angle during numpy slicing. Therefore, I drew the green circles of angle 0 degree having the same other major axis, minor axis etc values but the result also doesn't correspond to the green circle.
What's going on here?
As far as I can tell from the images and from the single line of code you posted, the problem is that you are not taking the rotation of the ellipse into account.
y + (minor_axis / 2) would only correspond to the top of the cropped region if the minor axis of the ellipse was exactly aligned with the x-axis. However, since your ellipse is rotated by 45 degrees, this is not the case.
You could try to work out the bounding box yourself, based on the parametric equations for an ellipse (see this post for an example). A much simpler option is to let OpenCV do the work, and get the bounding box using cv2.boundingRect, as Miki mentioned in the comments above.

Categories