Dnyanesh M
Dnyanesh M

Reputation: 1409

Find Skew Angle and Rotate the Image in C++ OpenCV

Need help, Plz see the following question, I'm asking this question second time, because last time I didn't get any answer. Consider following Two links => 1:=> Finding Skew Angle 2:=> Rotating Image as per skew angle

I wants to do the same, and the code given on this links works good. But the problem is, See the text displayed in these images, this code works fine for well aligned text only (as displayed in the images on the given links), but It gets failed when your text is in scattered form. Please tell me how to do it for images that contains text in the scattered form..? Thanks in advance..!! [ Here the main challenge is TO FIND CORRECT SKEW ANGLE..] I am very frustrated because of this problem... Plz Help..!!!

My Code is as follows:=>

// Find Skew angle.
double compute_skew(const char* filename)
{

    // Load in grayscale.
    cv::Mat img = cv::imread(filename, 0);

    // Binarize
    cv::threshold(img, img, 225, 255, cv::THRESH_BINARY);

    // Invert colors
    cv::bitwise_not(img, img);

    cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 3));
    cv::erode(img, img, element);

    std::vector<cv::Point> points;
    cv::Mat_<uchar>::iterator it = img.begin<uchar>();
    cv::Mat_<uchar>::iterator end = img.end<uchar>();
    for (; it != end; ++it)
        if (*it)
            points.push_back(it.pos());

    cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));

    double angle = box.angle;
    if (angle < -45.)
        angle += 90.;

    cv::Point2f vertices[4];
    box.points(vertices);
    for(int i = 0; i < 4; ++i)
        cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), 1, CV_AA);

    std::cout << "File **************Angle***************** " << filename << ": " << angle << std::endl;


    return angle;
}

// Rotate Image  according to skew angle.
void deskew(const char* filename, double angle)
{
    cv::Mat img = cv::imread(filename, 0);

    Point2f src_center(img.cols/2.0F, img.rows/2.0F);
    Mat rot_mat = getRotationMatrix2D(src_center, angle, 1.0);
    Mat rotated;
    warpAffine(img, rotated, rot_mat, img.size(), cv::INTER_CUBIC);

    imwrite(filename,rotated);

}

Upvotes: 1

Views: 3678

Answers (1)

dvhamme
dvhamme

Reputation: 1450

That approach is doomed to fail if you have scattered text because it relies on finding long text lines. Also, the term "skew" is a bit unfortunate in this instance because it is pure rotation in the posted examples.

What I would do is make line projections over a range of orientations (cfr. Radon transform or Hough line search). When your line projection has the right orientation, there will be a lot of zeros in the line projection caused by the interline gaps. The orientation which yields the most zero values in the projection is the most likely rotation angle of the text.

Upvotes: 1

Related Questions