OpenCV Rotation (Deskewing) в Android — преобразование C ++ в Java

Я пытаюсь определить угол наклона текста на изображении ссылка на сайт. Проблема в том, что этот пост написан на C ++, и у меня возникают проблемы с преобразованием некоторых вещей в Java.

Я сделал реализацию Хью Трансформация. Большую часть перехода в Java я сделал, руководствуясь мной эта почта (1). Но это не работает нормально. Дает угол 0,27919363, когда предполагается дать угол 15,9882. это это изображение, с которым я работаю.

И это мой код:

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 не содержит переменных без знака, и именно так это работает в посте (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 просто заполняет каждый пиксель.

Так. Пожалуйста, дайте мне знать, что я делаю не так. Заранее спасибо.

0

Решение

Вот код 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;
4

Другие решения

Вот код 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;
}

Угол должен быть в радианах, а не в градусах.

1

Это возможно при использовании классов tess4j, т.е. ImageDeskew & ImageHelper

ImageDeskew imgdeskew=new ImageDeskew(img); // BufferedImage img
ImageHelper.rotateImage(bim, -imgdeskew.getSkewAngle()); // rotateImage static method
0
По вопросам рекламы [email protected]