对具有分散字符的图像进行倾斜角度检测 [英] Skew angle detection on a image with scattered characters

查看:299
本文介绍了对具有分散字符的图像进行倾斜角度检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注本教程,以获得图像的倾斜角。



这是我的输入图片:



这是HoughLinesP发现的行: / p>

这不是真的得到大多数的行,它似乎很明显为什么。这是因为我已将我的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)
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)
{
//随机数生成器
cv :: RNG rng(0xFFFFFFFF);

cv :: Size size = src.size();
cv :: bitwise_not(src,src);
std :: vector< cv :: Vec4i>线;
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] );
}
angle / = nb_lines; //平均角度,以弧度表示。

std :: cout<<角度* 180 / CV_PI < std :: endl;

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

返回角度* 180 / CV_PI;
}
int main()
{
//加载灰度。
cv :: Mat img = cv :: imread(IMG_TESTE.jpg,0);
cv :: Mat旋转;
double angle = compute_skew(img);
rotate(img,angle,rotated);
//显示图片
cv :: imshow(Rotated,rotating);
cv :: waitKey(0);
}

干杯

解决方案

我建议首先查找单个组件(即行和字母),例如使用 cv :: threshold code> cv :: findContours 。



然后,可以删除狭窄的单个组件(即字母)。你可以使用 cv :: floodFill 来做到这一点。



有效地,摆脱字母可以为Hough变换提供更容易的输入。


I've been following this tutorial to get the skew angle of an image. It seems like HoughLinesP is struggling to find lines when characters are a bit scattered on the target image.

This is my input image:

This is the lines the HoughLinesP has found:

It's not really getting most of the lines and it seems pretty obvious to me why. This is because I've set my minLineWidth to be (size.width / 2.f). The point is that because of the few lines it has found it turns out that the skew angle is also wrong. (-3.15825 in this case, when it should be something close to 0.5)

I've tried to erode my input file to make characters get closer and in this case it seems to work out, but I don't feel this is best approach for situations akin to it.

This is my eroded input image:

This is the lines the HoughLinesP has found:

This time it has found a skew angle of -0.2185 degrees, which is what I was expecting but in other hand it is losing the vertical space between lines which in my humble opinion isn't a good thing.

Is there another to pre-process this kind of image to make houghLinesP get better results for scattered characters ?

Here is the source code I'm using:

#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);
}

Cheers

解决方案

I'd suggest finding individual components first (i.e., the lines and the letters), for example using cv::threshold and cv::findContours.

Then, you could drop the individual components that are narrow (i.e., the letters). You can do this using cv::floodFill for example. This should leave you with the lines only.

Effectively, getting rid of the letters might provide easier input for the Hough transform.

这篇关于对具有分散字符的图像进行倾斜角度检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆