Android OpenCV рисует линии

Я пытаюсь использовать OpenCV на телефоне Android для обнаружения линий. Я изменил образец Tutorial 1 Basic - 2. Использование OpenCV Camera. Я также использую Hough Line Transform в качестве примера. Тем не менее, я получаю странные цифры (по крайней мере те, которые я считаю странными числами) для очков. В диапазоне от 1000 до -1000 для б.

Я не совсем понимаю код (в основном часть о добавлении / вычитании 1000 * (a или -b)).

В конце концов я не вижу линий вообще.

Кто-нибудь может мне помочь? Также дайте мне знать, если вам нужна дополнительная информация.

capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
Imgproc.Canny(mGray, mIntermediateMat, 80, 100);
Imgproc.HoughLines(mIntermediateMat, mLines, 1, Math.PI/180, 100);

Scalar color = new Scalar(0, 0, 255);

double[] data;
double rho, theta;
Point pt1 = new Point();
Point pt2 = new Point();
double a, b;
double x0, y0;
for (int i = 0; i < mLines.cols(); i++)
{
    data = mLines.get(0, i);
    rho = data[0];
    theta = data[1];
    a = Math.cos(theta);
    b = Math.sin(theta);
    x0 = a*rho;
    y0 = b*rho;
    pt1.x = Math.round(x0 + 1000*(-b));
    pt1.y = Math.round(y0 + 1000*a);
    pt2.x = Math.round(x0 - 1000*(-b));
    pt2.y = Math.round(y0 - 1000 *a);
    Core.line(mIntermediateMat, pt1, pt2, color, 3);
}

Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);

Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

if (Utils.matToBitmap(mRgba, bmp))
    return bmp;

bmp.recycle();
return null;

2 ответа

Я использую HoughLineP, чтобы найти линии в моем кадре и вывести их обратно.

Вот мой код... надеюсь, это поможет.

    Mat mYuv = new Mat();
    Mat mRgba = new Mat();
    Mat thresholdImage = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
    mYuv.put(0, 0, data);
    Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);
    Imgproc.cvtColor(mRgba, thresholdImage, Imgproc.COLOR_RGB2GRAY, 4);
    Imgproc.Canny(thresholdImage, thresholdImage, 80, 100, 3);
    Mat lines = new Mat();
    int threshold = 50;
    int minLineSize = 20;
    int lineGap = 20;

    Imgproc.HoughLinesP(thresholdImage, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);

    for (int x = 0; x < lines.cols(); x++) 
    {
          double[] vec = lines.get(0, x);
          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(mRgba, start, end, new Scalar(255,0,0), 3);

    }

    Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888);

    if (Utils.matToBitmap(mRgba, bmp))
         return bmp;

Вы рисуете линии на mIntermediateMat изображение, но возвращение mRgba образ. Вот почему вы не видите линии.

Диапазон -1000..1000 для b верно. HoughLines возвращает угол наклона линии и расстояние от нуля (aka rho и theta). Чтобы нарисовать их, вам нужно конвертировать их в две точки. 1000 - это размеры изображения. Если вы рисуете изображение 2000x2000, увеличьте его до 2000, иначе линии не будут пересекать все изображение.

HoughLines отличается от алгоритма HoughLinesP, HoughLines находит только линии, которые пересекают все изображение. HoughLinesP возвращает более короткие отрезки.

Вот мой код для визуальной студии, надеюсь, это поможет.

void drawLines(Mat &input, const std::vector<Vec2f> &lines) {
for (int i = 0; i < lines.size(); i++) {
    float alpha = CV_PI/2-atan(input.rows/input.cols);
    float r_max;
    float r_min;
    float r = lines[i][0];
    float theta = lines[i][1];
    if (theta<alpha || theta>CV_PI-alpha) {
        r_max = input.cols*cos(theta);
        r_min = input.rows*sin(theta);
        if (r > r_max) {
            Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
            Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
            line(input, pt1, pt2, Scalar(255, 0, 0), 1);
        }
        else if (r < r_max && r > r_min) {
            Point pt1(r / cos(theta), 0);
            Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
            line(input, pt1, pt2, Scalar(255, 0, 0), 1);
        }
        else {
            Point pt1(r / cos(theta), 0);
            Point pt2(0, r / sin(theta));
            line(input, pt1, pt2, Scalar(255, 0, 0), 1);
        }

    }
    else {
            r_min = input.cols*cos(theta);
            r_max = input.rows*sin(theta);
            if (r > r_max) {
                Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
                Point pt2((r - input.rows*sin(theta)) / cos(theta), input.rows);
                line(input, pt1, pt2, Scalar(0, 0, 255), 1);
            }
            else if (r < r_max && r > r_min) {
                Point pt1(input.cols, (r - input.cols*cos(theta)) / sin(theta));
                Point pt2(0, r / sin(theta));
                line(input, pt1, pt2, Scalar(0, 0, 255), 1);
            }
            else {
                Point pt1(r / cos(theta), 0);
                Point pt2(0, r / sin(theta));
                line(input, pt1, pt2, Scalar(0, 0, 255), 1);
            }
    }

}

Вот 2 графика о логике моего кода, который я разместил.

Объяснение альфа

Объяснение альфа

Объяснение r_max && r_min

Объяснение r_max && r_min

Другие вопросы по тегам