Saghir A. Khatri
Saghir A. Khatri

Reputation: 3128

HoughLinesP not detecting lines OpenCV android

I am working with OpenCV 3.0 for Android. I have an image in which i want to detect angle of hands inside circular dials. for that i am working on HoughLinesP to detect hands. Here is the code.

Mat imgSource = new Mat(), imgCirclesOut = new Mat(),imgLinesOut=new Mat();
//grey opencv
Imgproc.cvtColor(Image, imgSource, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur( imgSource, imgSource, new Size(9, 9), 2, 2 );

int threshold = 0;
int minLineSize = 0;
int lineGap = 0;

Imgproc.HoughLinesP(imgSource, imgLinesOut, 1, Math.PI/180, threshold, minLineSize, lineGap);
for( int j = 0; i < imgLinesOut.cols(); i++ )
{
    double[] vec=imgLinesOut.get(0,j);
    Point pt1, pt2;
    pt1=new Point(vec[0],vec[1]);
    pt2=new Point(vec[2],vec[3]);
    Imgproc.line( Image, pt1, pt2, new Scalar(0,0,255), 3, Core.LINE_AA,0);
}

But result is enter image description here

What i need is the angle of hands in these circles. Any help regarding this issue is highly appreciated. Thanks in ADvance

Edit I have updated my code with this

 Mat imgSource = new Mat(), imgCirclesOut = new Mat(),imgLinesOut=new Mat();

 Imgproc.GaussianBlur( Image, imgSource, new Size(5, 5), 2, 2 );      
 int threshold = 20;
 int minLineSize = 0;
 int lineGap = 10;
 Imgproc.Canny(imgSource, imgSource, 70, 100);
 Imgproc.HoughLinesP(imgSource, imgLinesOut, 1, Math.PI/180, threshold, minLineSize, lineGap);
for( int j = 0; j < imgLinesOut.cols(); j++ )
{
    double[] vec=imgLinesOut.get(0,j);

    Point pt1, pt2;
    pt1=new Point(vec[0],vec[1]);
    pt2=new Point(vec[2],vec[3]);

    Imgproc.line( imgSource, pt1, pt2, new Scalar(0,0,255), 3, Core.LINE_AA,0);
}

as suggested by @Micka, there is no need of Graying image(I removed cvtcolor). I also decreased value of GuassianBlur Size to 5. I have added Canny on image too for edges.

Resulting blur image is

enter image description here

Upvotes: 2

Views: 1972

Answers (2)

Miki
Miki

Reputation: 41765

Detecting lines can be a problem in such small images, since you have to few points to fill the Hough accumulator properly.

I propose to use a different approach:

  1. Segment each circle (dial)
  2. Extract the largest dark blob (hand)

Below is a simple implementation of this idea. The code is in C++, but you can easily port to Java, or at least use as a reference.

#include "opencv2/opencv.hpp"
using namespace cv;

int main(int, char**)
{
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    Mat3b res;
    cvtColor(img, res, COLOR_GRAY2BGR);

    // Find dials
    vector<Vec3f> circles;
    HoughCircles(img, circles, CV_HOUGH_GRADIENT, 1, img.cols/10, 400, 40);

    // For each dial
    for (int i = 0; i < circles.size(); ++i)
    {

        // Segment the dial
        Mat1b dial(img.size(), uchar(255));
        Mat1b mask(img.size(), uchar(0));
        circle(mask, Point(circles[i][0], circles[i][1]), circles[i][2], Scalar(255), CV_FILLED);
        img.copyTo(dial, mask);

        // Apply threshold and open
        Mat1b bin;
        threshold(dial, bin, 127, 255, THRESH_BINARY_INV);
        Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5,5));
        morphologyEx(bin, bin, MORPH_OPEN, kernel);

        // Get min area rect
        vector<Point> points;
        findNonZero(bin, points);
        RotatedRect r = minAreaRect(points);

        // Draw min area rect
        Point2f pts[4];
        r.points(pts);
        for (int j = 0; j < 4; ++j) {
            line(res, pts[j], pts[(j + 1) % 4], Scalar(0, 255, 0), 1);
        }       
    }

    imshow("Result", res);
    waitKey();

    return 0;
}

Starting from this image:

enter image description here

I find hands here:

enter image description here

Upvotes: 3

Jubilee r
Jubilee r

Reputation: 55

for( int j = 0; j < imgLinesOut.size(); j++ )

This will give the size of the vector.To iterate through that vector

Upvotes: -1

Related Questions