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.
Related
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.
pyopengl How to color concave polygons,graphics like this,When filling the color, I always fill the concave place flat. I hope I can fill the color according to the outline of the figure
When filling the color, I always fill the concave place flat. I hope I can fill the color according to the outline of the figure
Don't draw a polygon. Draw many triangles, which combine to make the polygon.
Of course, you can generate the triangles in any way you like, such as with pencil and paper and a ruler and typing in the coordinates.
For this polygon, you might find GL_TRIANGLE_FAN useful, since not much change is needed: add one new vertex at the beginning of the vertices, in the middle of the polygon, so that every other vertex can see the one you added. OpenGL will generate triangles radiating outwards from the central point to all the edge vertices. This is convenient for polygons like yours which are "mostly convex". The triangles will look like this:
If the polygon wasn't "mostly convex", you would most likely need to use GL_TRIANGLES which allows you to split it up however you like.
Another option is to draw an alpha-textured quad, with alpha test turned on. The GPU will draw a square and ignore the pixels in the corners where the alpha is 0. Since your polygon is "almost a square" the wasted work to calculate those pixels and ignoring them could be less than the extra work to process a bunch more triangles. There's no way to perfectly predict that. With this approach, the corner shape would be pixel-based instead of triangle-based, so it would get blocky if you zoomed in.
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.
I'm currently trying to write a program that can automatically extract data from some graphs in multiple scanned documents. Mainly by using opencv I would like to detect some features of the graphs in order to convert them into usable data. In the left graph I'm looking for the height of the circle sectors and in the right graph the distance from the center to the points where the dotted lines intersect with the gray area. In both cases I would like to convert these values into numeric data for further usage.
What follows is a step by step plan of how I think my algorithm will work:
Align the image based on the big dotted lines. This way I can ensure that the graphs in all the scanned images will have the exact same positions. After all, it is possible that some images will be slightly tilted or moved in comparison with other images, due to the manual scanning process. Basically I want the coordinate of a pixel in one image to correspond to the exact same pixel in another image.
We now know that the coordinates of the graph centers and the angles for the circle sectors are identical for all images now. For each circle sector, filter the darker pixels from the lighter ones. This is done using the openCV inRange function.
Search for the best fitting segment over the darker pixels in the left graph and search for the best fitting triangle in the right graph. This is done by global optimization.
Return the radius of the optimal segment and return the edge lengths of the optimal triangle. Now we have values that we can use as data.
I have more or less figured out how to do every step, except the first one. I have no clue on how I would go about aligning my images. Does someone might have an idea or a strategy on how to achieve this alignment?
Step 1: canny, it give you perfect long edge. If this is the only part you dont understand, here is the answer. You can adjust the parameter to get the best result. The first will be idea for both line and pie circle. But if you only keen to find pie. change the parameter accordingly to get my 2nd image
The red denotes the doted line. sample from opencv directly
Step 2: local area enhancement/segmentation to find both circles (from image 1 parameter with houghcircle param2 set to 110)
Step 3: Segment the pie out(all the way to the edge of image) and find the median line
Step 4: OCR on the test image pies and find the distance of none-background color along the median line.
Step 5: generate list out and send to csv or sth
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.