具有散字符的图像上倾斜角度检测(Skew angle detection on a image wi

2019-10-21 21:57发布

我一直在关注这个教程中获得的图像的倾斜角度。 好像HoughLinesP正在努力寻找行时字符是一个有点散乱的目标图像。

这是我的输入图像:

这是HoughLinesP发现线路:

这不是真正得到大多数线,似乎很明显,我为什么。 这是因为我已经把我的minLineWidth为(size.width / 2.F)。 问题的关键是,由于几行已发现的事实证明,倾斜角度也是错误的。 (在这种情况下-3.15825,当它应该是接近0.5)

我试图蚕食我的输入文件以使角色更接近,在这种情况下,它似乎工作,但我不觉得这是一个类似于它的情况下最好的办法。

这是我的侵蚀输入图像:

这是HoughLinesP发现线路:

这一次,它已经找到-0.2185度的倾斜角度,这正是我所期待的,但在另一方面,它正在失去行之间的垂直空间,在我的愚见是不是一件好事。

是否有另一种预先处理这类形象,使houghLinesP得到分散人物更好的结果?

下面是我使用的源代码:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;


static cv::Scalar randomColor( cv::RNG& rng )
{
  int icolor = (unsigned) rng;
  return cv::Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
}

void rotate(cv::Mat& src, double angle, cv::Mat& dst)
{
    int len = std::max(src.cols, src.rows);
    cv::Point2f pt(len/2., len/2.);
    cv::Mat r = cv::getRotationMatrix2D(pt, angle, 1.0);

    cv::warpAffine(src, dst, r, cv::Size(len, len));
}

double compute_skew(cv::Mat& src)
{
    // Random number generator
    cv::RNG rng( 0xFFFFFFFF );

    cv::Size size = src.size();
    cv::bitwise_not(src, src);
    std::vector<cv::Vec4i> lines;
    cv::HoughLinesP(src, lines, 1, CV_PI/180, 100, size.width / 2.f, 20);
    cv::Mat disp_lines(size, CV_8UC3, cv::Scalar(0, 0, 0));
    double angle = 0.;
    unsigned nb_lines = lines.size();
    for (unsigned i = 0; i < nb_lines; ++i)
    {
        cv::line(disp_lines, cv::Point(lines[i][0], lines[i][1]),
                 cv::Point(lines[i][2], lines[i][3]), randomColor(rng));
        angle += atan2((double)lines[i][3] - lines[i][1],
                       (double)lines[i][2] - lines[i][0]);
    }
    angle /= nb_lines; // mean angle, in radians.

    std::cout << angle * 180 / CV_PI << std::endl;

    cv::imshow("HoughLinesP", disp_lines);
    cv::waitKey(0);

    return angle * 180 / CV_PI;
}
int main()
{
    // Load in grayscale.
    cv::Mat img = cv::imread("IMG_TESTE.jpg", 0);
    cv::Mat rotated;
    double angle = compute_skew(img);
    rotate(img, angle, rotated);
    //Show image
    cv::imshow("Rotated", rotated);
    cv::waitKey(0);
}

干杯

Answer 1:

我建议首先找到各个组件(即线和字母)使用,例如cv::thresholdcv::findContours

然后,你可以丢弃狭窄(即字母)的各个组件。 为此,您可以使用cv::floodFill例如。 这应该让你只用线条。

实际上,摆脱字母可能会提供更方便的输入为Hough变换。



Answer 2:

尝试检测字符组块,然后找到这些块的轮廓。 下面我用模糊,形态开阈值操作来完成它。

Mat im = imread("yCK4t.jpg", 0);
Mat blurred;
GaussianBlur(im, blurred, Size(5, 5), 2, 2);
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
Mat morph;
morphologyEx(blurred, morph, CV_MOP_OPEN, kernel);
Mat bw;
threshold(morph, bw, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);
Mat cont = Mat::zeros(im.rows, im.cols, CV_8U);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
{
    drawContours(cont, contours, idx, Scalar(255, 255, 255), 1);
}

然后使用上轮廓图像霍夫变换线。 与蓄压器80的阈值,我获得以下导致的-3.81的角度线。 这是因为异常行几乎是垂直的高。 通过这种方法,大部分线路都会有不同的一些局外类似角度值。 检测和丢弃异常值会给你的角度更好的近似。

HoughLinesP(cont, lines, 1, CV_PI/180, 80, size.width / 4.0f, size.width / 8.0f);



文章来源: Skew angle detection on a image with scattered characters