Rotate an image without black area - python

When we use some image processing library to rotate an image, the rotated image will always contains some black area. For example, I use the following python code to rotate an image:
from scipy import misc
img = misc.imread('test.jpg')
img = misc.imrotate(img,15)
misc.imsave('rotated.jpg')
The image is as follows:
My question is: how can I rotate an image without producing black area. I believe there exists some interpolation method to compensate for the missing area, which makes the image more natural.
It will be appreciated if anyone can provide a python code to achieve my task.

If you want to 'clone' or 'heal' the missing areas based on some part of the background, that's a complex problem, usually done with user intervention (in tools like Photoshop or GIMP).
Alternatives would be to fill the background with a calculated average colour - or just leave the original image. Neither will look 'natural' though.
The only approach that will work for all images will be to crop the rotated image to the largest rectangle within the rotated area. That will achieve your objective of having no black areas and looking natural, but at the cost of reducing the image size.

isnt there a simple paint fill function in your "some image library" ?, simple do that at all 4 corner pixels and then make it white or so.

Related

Deskewing an image with background (Python)

I am working on a project where I am doing OCR on text on a label. My job is to deskew the image to make it readable with tesseract.
I have been using this approach, that greyscales and thresholds the picture, gets the coordinates of the black pixels, draws a minAreaRect around it and then corrects the skew by the skew angle of this rectangle. This works on , but not on images with background, like the presented image. There, it calculates a skew angle of 0.0 and does not rotate the image. (Expected result: 17°)
I suspect this happens because there are black pixels in the background. Because of them the minAreaRect goes around the whole picture, thus leading to a skew angle of 0.
I tried doing a background removal, but couldn't find a method that works well enough so that only the label with the text is left
Another approach I tried was clustering the pixels through k-means-clustering. But even when choosing a good k manually, the cluster with the text still contains parts of the background.
Not to mention that I would still need another method that goes through all the clusters and uses some sort of heuristic to determine which cluster is text and which is background, which would cost a lot of runtime.
What is the best way to deskew an image that has background?
You can try deep learning based natural scene text detection methods. With these methods you can get rotated bounding boxes for each text. Based on these get rotated bounding rectangle covering all boxes. Then use the 4 corners of that rectangle to correct the image.
RRPN_plusplus
Based on sample image RRPN_plusplus seems to do quite well on extreme angles.
EAST
Pyimagesearch has a tutorial with EAST scene text detector. Though not sure east will do good with extreme angles.
https://www.pyimagesearch.com/2018/08/20/opencv-text-detection-east-text-detector/
Image from, https://github.com/argman/EAST.
These should help you find recent better repos and methods,
https://github.com/topics/scene-text-detection
https://paperswithcode.com/task/scene-text-detection
https://paperswithcode.com/task/curved-text-detection
You could use a fast cross platform command like
deskew32 -o out1.png -a 20 -f b1 -g c Sdgqm.png
Or for more complex cases combine with dewarp but will need a third step as the auto thresholding is not upper and lower
dewarping mmrnt.png square.png 0 0

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.

How to draw contours around black areas in pixeld image?

i am quite new to Python and i try to write some code for image analysing.
Here is my initial image:
Initial image
After splitting the image in to the rgb channels, converting in to gradient, using a threshold and merging them back together i get the following image:
Gradient/Threshold
Now i have to draw contours around the black areas and get the size of the surrounded areas. I just dont know how to do it, since my trials with find/draw.contours in opencv are not succesfull at all.
Maybe someone also knows an easier way to get that from the initial image.
Hope someone can help me here!
I am coding in Python 3.
Try adaptive thresholding on the grayscale image of the input image.
Also play with the last two parameters of the adaptive thresholding. You will find good results as I have shown in the image. (Tip: Create trackbar and play with value, this will be quick and easy method to get best values of these params.)

Opencv: How to stitch four trapezoid images to make a square image?

I am currently trying very hard to figure out a way to make these four trapezoid images into one nice image. The final image should look something like this(used photoshop to make it):
That above image will be complied with four of these images:
The problem is that when I try to rotate and combine these images, the black surroundings come into the final image as well like this:
How am I supposed to rid of the blacked out area or make it transparent? I've tried using a mask but that only make the black area white instead. I have also tried using the alpha channel, but that didn't work(although maybe I was doing wrong). Any ideas on what I can do in OpenCV?
I did actually figure it out. I did it with these steps:
Create two SAME SIZED black backgrounds with numpy zeros
Put one image in each background where you want them(for me, it was left and top)
Then all you need to do is cv.add(first, second)
The reason it works is because black pixels are 0,0,0 so adding to a pixel that is, say, 25,62,34, the pixel doesn't change and thus rids of the black corner.

How can I use PIL to crop a select area based on face detection?

Hi I am wanting to use the python imaging library to crop images to a specific size for a website. I have a problem, these images are meant to show people's faces so I need to automatically crop based on them.
I know face detection is a difficult concept so I'm thinking of using the face.com API http://developers.face.com/tools/#faces/detect which is fine for what I want to do.
I'm just a little stuck on how I would use this data to crop a select area based on the majority of faces.
Can anybody help?
Joe
There is a library for python that have a concept of smart-cropping that among other options, can use face detection to do a smarter cropping.
It uses opencv under the hood, but you are isolated from it.
https://github.com/globocom/thumbor
If you have some rectangle that you want to excise from an image, here's what I might try first:
(optional) If the image is large, do a rough square crop centered on the face with dimensions sqrt(2) larger than the longer edge (if rectangular). Worst-case (45° rotation), it will still grab everything important.
Rotate based on the face orientation (something like rough_crop.rotate(math.degrees(math.atan(ydiff/xdiff)), trig is fun)
Do a final crop. If you did the initial crop, the face should be centered, otherwise you'll have to transform (rotate) all your old coordinates to the new image (more trig!).

Categories