[英]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.