scap3y
scap3y

Reputation: 1198

cv::gpu::HoughLines is not working properly

I am trying to detect some lines using Hough Transform on a cv::gpu::GpuMat structure. I have tried using both gpu::HoughLines and gpu::HoughLinesP but even with extremely low thresholds, I am not getting any results at all. During debugging, I see that the container which should contain the results (houghLines) has only zeros stored inside it. The code I have written is given below,

static cv::Mat drawHoughLinesOnMat (cv::gpu::GpuMat hough_Mat, cv::gpu::GpuMat houghLines)
{
    cv::Mat output_Mat;
    cv::cvtColor(cv::Mat(hough_Mat), output_Mat, CV_GRAY2BGR);

    std::vector<cv::Vec4i> lines_vector;
    if (!houghLines.empty())
    {
        lines_vector.resize(houghLines.cols);
        cv::Mat temp_Mat (1, houghLines.cols, CV_8UC3, &lines_vector[0]);
        houghLines.download (temp_Mat);
    }

    for (size_t i=0; i<lines_vector.size(); ++i)
    {
        cv::Vec4i l = lines_vector[i];
        cv::line(output_Mat, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(0, 0, 255), 1, 8);
    }

    return output_Mat;
}


int main()
{
    cv::Mat input = cv::imread(INPUT_DATA_1->c_str(), CV_LOAD_IMAGE_GRAYSCALE);
    std::string imageType = getImgType(input.type());

    cv::gpu::GpuMat mat_input(input), bil_out, mat_thresh, hough_lines;
    cv::gpu::HoughLinesBuf hough_buffer;

    int bilateral_thresh = 15; // 5 == 0.085s; 15 == 0.467s at run-time
    cv::gpu::bilateralFilter(mat_input, bil_out, bilateral_thresh, bilateral_thresh*2, bilateral_thresh/2);
    //cv::gpu::threshold(bil_out, mat_thresh, 10, 255, CV_THRESH_BINARY);
    cv::gpu::Canny(bil_out, mat_thresh, 10, 60, 5);

    cv::gpu::HoughLinesP(mat_thresh, hough_lines, hough_buffer, 1.0f, (float)(CV_PI/180.0f), 5, 1);
    //cv::Mat test_hough(hough_lines);
    cv::Mat hough_Mat = drawHoughLinesOnMat(mat_input, hough_lines);
    cv::gpu::HoughLines(mat_thresh, hough_lines,  1.0f, (float)(CV_PI/180.0f),   1, true);
    /*cv::Mat */hough_Mat = drawHoughLinesOnMat(mat_input, hough_lines);

    return EXIT_SUCCESS
}

The image I am using is,

enter image description here

Could someone tell me what it is that I am doing wrong..? Thanks in advance.!

The output of the Canny filter is,

enter image description here

EDIT:

I have tested on the CPU version of HoughLines and it seems to work just fine.

EDIT_2:

The solution posted by @jet47 works perfectly.

Upvotes: 2

Views: 2586

Answers (2)

vinograd47
vinograd47

Reputation: 6420

You use incorrect code for downloading results from GPU back to CPU:

lines_vector.resize(houghLines.cols);
cv::Mat temp_Mat (1, houghLines.cols, CV_8UC3, &lines_vector[0]);
houghLines.download (temp_Mat);

You use incorrect type for temp_Mat - CV_8UC3, it must be CV_32SC4.

The correct code is:

lines_vector.resize(houghLines.cols);
cv::Mat temp_Mat(1, houghLines.cols, CV_32SC4, &lines_vector[0]);
houghLines.download(temp_Mat);

Upvotes: 3

Mailerdaimon
Mailerdaimon

Reputation: 6080

My guess is that the Method you are using is outdated (but im not entirely sure).

This is how i would do it(as demonstrated in this Example Code):

//d_src filled with your image somewhere
GpuMat d_lines;
{
    Ptr<cuda::HoughSegmentDetector> hough = cuda::createHoughSegmentDetector(1.0f, (float) (CV_PI / 180.0f), 50, 5);

    hough->detect(d_src, d_lines);
}

vector<Vec4i> lines_gpu;
if (!d_lines.empty())
{
    lines_gpu.resize(d_lines.cols);
    Mat h_lines(1, d_lines.cols, CV_32SC4, &lines_gpu[0]);
    d_lines.download(h_lines);
}

for (size_t i = 0; i < lines_gpu.size(); ++i)
{
    Vec4i l = lines_gpu[i];
    line(dst_gpu, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA);
}

EDIT The above uses the OpenCv 3.0 Interface

Upvotes: 1

Related Questions