简体   繁体   English

Android中的OpenCV旋转(去偏斜)-C ++到Java的转换

[英]OpenCV Rotation (Deskewing) in Android - C++ to Java Conversion

I'm trying to detect the skew angle of a text in an image link . 我正在尝试检测图像链接中文本的偏斜角。 The problem is that this post is written in C++, and I'm having trouble converting some things to Java. 问题是这篇文章是用C ++编写的,我在将某些东西转换成Java时遇到了麻烦。

I did the implementation of Hugh Transform. 我做了休变换的实现。 Most of the conversion to java I did guiding me from this post (1). 这篇文章 (1)指导了我大部分到Java的转换。 But it's not working fine. 但这不能正常工作。 Is giving an angle of 0.27919363 when is supposed to give an angle of 15.9882. 当假定角度为15.9882时,角度为0.27919363。 This is the image I'm working with. 是我正在使用的图像。

And this is my code: 这是我的代码:

public double compute_skew1(String filename){
    Log.d(TAG, "Computing skew 1");

    Mat src = Highgui.imread(filename, 0);
    Size size = src.size();
    //double minLineSize = 20;
    double minLineSize = src.width() / 2.f;

    Core.bitwise_not(src, src);

    Mat lines = new Mat();
    double angle = 0.;
    try {
        Imgproc.HoughLinesP(src, lines, 1, Math.PI / 180, 100, minLineSize, 20);

        Mat disp_lines = new Mat(size, CvType.CV_8UC1, new Scalar(0, 0, 0));
        int nb_lines = lines.cols();
        for (int i = 0; i < nb_lines; i++) {
            double[] vec = lines.get(0, i);
            double x1 = vec[0], 
                   y1 = vec[1],
                   x2 = vec[2],
                   y2 = vec[3];
            Point start = new Point(x1, y1);
            Point end = new Point(x2, y2);
            Core.line(disp_lines, start, end, new Scalar(255,0,0));
            angle += Math.atan2(y2 - y1, x2 - x1);
        }
        angle /= nb_lines; // mean angle, in radians.*/
        //Log.d(TAG, "ANGLE: "+angle);
        Log.d(TAG, "ANGLE: "+ angle * 180 / Math.PI);
    } catch (Exception e) {
        Log.e(TAG, "Error in compute_skew1");
        Log.e(TAG, e.getMessage());
    }

    return angle;
}

I'm almost certain the problem is with this line "int nb_lines = lines.cols();" 我几乎可以肯定问题出在这行“ int nb_lines = lines.cols();” since the original line is "unsigned nb_lines = lines.size();", java doesn't jave unsigned variables, and that's the way it works in the post(1). 由于原始行是“ unsigned nb_lines = lines.size();”,因此Java不会伪装无符号变量,这就是它在post(1)中的工作方式。 Also, I don't quite understand this line "double[] vec = lines.get(0, i);" 另外,我不太理解这一行“ double [] vec = lines.get(0,i);” but that's the way it worked in the post (1) as well. 但这也是帖子(1)中的工作方式。 What am I doing wrong? 我究竟做错了什么?

Also, after I get the angle, I need to do the rotation or deskewing of the text, and I also have some trouble with this conversion, especially with this part of the code: 另外,在确定角度之后,我需要旋转文本或进行倾斜校正,并且在进行这种转换时也会遇到一些麻烦,尤其是在这部分代码中:

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());

With the help of this post2 , I believed this to be the conversion: post2的帮助下,我相信这是转换:

List <Point> points = new ArrayList<Point>();
for (int i = 0; i < img.rows(); i++) {
    for (int j = 0; j < img.cols(); j++) {
        double pixel = img.get(i, j)[0];
        if (pixel != 0.0)
            points.add(new Point(i,j));
    }
}

But does not work, there is never a pixel = 0.0 and so the p array just fills with every pixel. 但是不起作用,永远不会有一个像素= 0.0,因此p数组只会填充每个像素。

So. 所以。 Please let me know what I'm doing wrong. 请让我知道我在做什么错。 Thanks in advance. 提前致谢。

Here is the java code to calculate skew angle: 这是计算偏斜角的Java代码:

    Mat source = Imgcodecs.imread(input.getName(),0);
    Size size = source.size();
    Core.bitwise_not(source, source);
    Mat lines = new Mat();
    Imgproc.HoughLinesP(source, lines, 1, Math.PI / 180, 100, size.width / 2.f, 20);
    double angle = 0.;
    for(int i = 0; i<lines.height(); i++){
        for(int j = 0; j<lines.width();j++){
            angle += Math.atan2(lines.get(i, j)[3] - lines.get(i, j)[1], lines.get(i, j)[2] - lines.get(i, j)[0]);
        }
    }
    angle /= lines.size().area();
    angle = angle * 180 / Math.PI;

here is the java code to deskew your image: 这是用于校正图像的Java代码:

Mat deskew(Mat src, double angle) {
    Point center = new Point(src.width()/2, src.height()/2);
    Mat rotImage = Imgproc.getRotationMatrix2D(center, angle, 1.0);
    //1.0 means 100 % scale
    Size size = new Size(src.width(), src.height());
    Imgproc.warpAffine(src, src, rotImage, size, Imgproc.INTER_LINEAR + Imgproc.CV_WARP_FILL_OUTLIERS);
    return src;
}

The angle should be in radians not in degrees. 角度应以弧度而不是度为单位。

This is possible using classes of tess4j ie ImageDeskew & ImageHelper 这可以使用tess4j类实现,例如ImageDeskew和ImageHelper

ImageDeskew imgdeskew=new ImageDeskew(img); // BufferedImage img
ImageHelper.rotateImage(bim, -imgdeskew.getSkewAngle()); // rotateImage static method

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM