I thought I’ll write a little tutorial about how we can straighten an image. This is very important because (for example) we can do more accurate OCR after the image is straight and not rotated.

This is how I made it:

  • Pre-Processing:
    • Binary Image: With this step we create a binary image from our original image. This step is important because that way we can detect only the important parts of the image. With this example this is not so spectacular, because the image I have is already in Black and White. But we have to do this step with this image too.
    • Word detection: After we have a binary image we can use morphology to detect areas where we have text. I simply use CLOSE with a big kernel size in the x direction.After these steps we have an image like this:


  • Angle calculation:
    • Line detection: We can thinks about these words as lines and fortunately OpenCV has a function where we can detect lines on the image. It’s called *HoughLinesP*. So with that function we can find (we only need one line) the angle. And with that angle if we rotate our image it will be straight.
    • Angle calculation: After we used HoughLinesP we can calculate the start end end point of the line we detected. And from that we can calculate the angle we need. We just need a simple equation from the math class: atan2((endPoint.y – startPoint.y), (endPoint.x – startPoint.x)) × (180 / PI).We are done! Now we know the angle. The most important thing from the image. Here is the line we detected:


  • Rotate the image:
    Here comes the easiest part of this tutorial. We just need to rotate the image. If we simply rotate it it will be cropped so we can calculate a bounding box we will need for this. Because after we rotate an image we can have a bigger width or height. From the angle and from the image center Point we will know the rotation matrix in 2D. So we calculate a bounding box what we will need and than just rotate it with our rotation matrix (warpAffine).

The results:



Cool, isn’t it? 😉 Now we can do OCR on our image more precisely and things like that. 🙂

Did you think I won’t share my code with you? You were wrong. Here is the code written in Java. (It’s easy to “convert” it to other languages). Btw. I think you should try to create your own version based on my tutorial because that way you’ll understand it more easily.
I used java because I wanted to try it out quickly and that was the perfect moment.

Stay tuned! 😉