16

I am trying to use OpenCV on an android phone to detect lines. I modified the 'Tutorial 1 Basic - 2. Use OpenCV Camera' sample. I am also using Hough Line Transform as an example. However, I am getting weird numbers (at least what I believe to be weird numbers) for the points. In the range 1000 to -1000 for b.

I don't fully understand the code (mostly the part about adding/subtracting 1000 * (a or -b)).

In the end I do not see the lines at all.

Could anyone give me a hand? Also let me know if you need more information.

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;
reynman
  • 709
  • 3
  • 9
  • 19

3 Answers3

35

I am using HoughLineP to find lines in my frame and draw them back out.

Here is my code... hope this helps.

    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;
Elhanan Mishraky
  • 2,736
  • 24
  • 26
Brian ONeil
  • 4,229
  • 2
  • 23
  • 25
  • Hey i want to add a matrix on the highlighted portion in the image can you guide me? – Smit Patel May 09 '14 at 09:34
  • @Brian ONeil can you tell me what are getFramHeight() and getFramWidth() methods Refers? – Qadir Hussain Jan 02 '15 at 13:15
  • 1
    In Opencv SDK v3, you should use Imgproc.line instead of Core.line, Core.line does not exist any more. – Roshan Khandelwal May 15 '16 at 13:24
  • 2
    Also in OpenCV 3.2 (I'm not sure about older version) you should iterate over `.rows()` (instead of `.cols()`), and then do `.get(x,0)` (instead of `.get(0,x)`). Otherwise you will get only first line. – Robyer Apr 13 '17 at 10:00
1

You draw the lines to the mIntermediateMat image, but returning mRgba image. That's why you don't see the lines.

The -1000..1000 range for b is correct. HoughLines returns a line angle and distance from zero (a.k.a. rho and theta). To draw them, you need to convert them to two points. The 1000's are the image dimensions, if you would draw to a 2000x2000 image, increase them to 2000 or otherwise the lines will not cross the entire image.

HoughLines is different algorithm from HoughLinesP. HoughLines only finds lines, that cross the entire image. HoughLinesP returns shorter line segments.

Oliv
  • 10,221
  • 3
  • 55
  • 76
0

Here is my code for visual studio, hope it helps.

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

}

Here are 2 graphs about the logic about my code I posted.

The explanation of alpha

The explanation of alpha

The explanation of r_max && r_min

The explanation of r_max && r_min

bummi
  • 27,123
  • 14
  • 62
  • 101
olddunk
  • 1
  • 1