繁体   English   中英

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

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

我正在尝试检测图像链接中文本的偏斜角。 问题是这篇文章是用C ++编写的,我在将某些东西转换成Java时遇到了麻烦。

我做了休变换的实现。 这篇文章 (1)指导了我大部分到Java的转换。 但这不能正常工作。 当假定角度为15.9882时,角度为0.27919363。 是我正在使用的图像。

这是我的代码:

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

我几乎可以肯定问题出在这行“ int nb_lines = lines.cols();” 由于原始行是“ unsigned nb_lines = lines.size();”,因此Java不会伪装无符号变量,这就是它在post(1)中的工作方式。 另外,我不太理解这一行“ double [] vec = lines.get(0,i);” 但这也是帖子(1)中的工作方式。 我究竟做错了什么?

另外,在确定角度之后,我需要旋转文本或进行倾斜校正,并且在进行这种转换时也会遇到一些麻烦,尤其是在这部分代码中:

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

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

但是不起作用,永远不会有一个像素= 0.0,因此p数组只会填充每个像素。

所以。 请让我知道我在做什么错。 提前致谢。

这是计算偏斜角的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;

这是用于校正图像的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;
}

角度应以弧度而不是度为单位。

这可以使用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