cv :: gpu :: HoughLines无法正常工作

问题描述:

我试图检测一些使用霍夫变换cv::gpu::GpuMat结构的行。我曾尝试使用gpu::HoughLinesgpu::HoughLinesP,但即使门槛极低,我也没有得到任何结果。在调试过程中,我发现应该包含结果的容器(houghLines)只有零存储在其中。我已经写了下面给出的代码,cv :: gpu :: HoughLines无法正常工作

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 
} 

我使用的是图像,

enter image description here

有人能告诉我它是什么,我做错了..?提前致谢。!

坎尼滤波器的输出,

enter image description here

编辑:

我已经在HoughLines的CPU版本测试,它似乎工作得很好。

EDIT_2:

@ jet47发布的解决方案非常完美。

+0

如何图像看起来应用Canny滤波器的后? – Mailerdaimon

+0

哦,只是一秒钟。我会发布它。它已经结束了。 – scap3y

+0

你使用的是什么版本的OpenCv? – Mailerdaimon

您使用不正确的代码下载从GPU返回结果到CPU:

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

您使用不正确类型temp_Mat - CV_8UC3,它必须是CV_32SC4

正确的代码是:

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

你能解释一下为什么它需要'CV_32SC4'而不是'CV_8UC3' ..?我并不完全清楚,说实话.. – scap3y

+0

'lines_vector'是'cv :: Vec4i'的一个向量。 'cv :: Vec4i'是32位整数值的4分量矢量。所以它是一个'CV_32SC4',而'CV_8UC3'是一个3通道8位值。 'GpuMat :: download'方法检查输出矩阵的类型并在类型不匹配的情况下重新分配数据。 – jet47

+0

太棒了,谢谢你的解释。我已经尝试过,它完美运作。 – scap3y

我的猜测是你使用的方法已过时(但我不完全确定)。

这是我应该怎样做(如本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); 
} 

编辑以上使用OpenCV的3.0接口

+0

这是3.0界面,对.. ..?我需要让它在2.4.x界面上工作,因为这是使用cv 2.4的更大应用程序的一部分。 我也遵循相同的示例(但用于2.4.6),但我没有收到任何东西。 – scap3y

+0

是的,我认为这样,我会离开答案,虽然对于使用3.0的人来说。在你的情况下,它似乎是另一个问题。 – Mailerdaimon

+0

谢谢。对于发生的事情,我完全不知所措。起初我认为这是因为GPU模块没有正确构建,但事实并非如此,因为其他的东西工作正常。 – scap3y