2013-11-21 2 views
1

Я пытаюсь обнаружить некоторые линии, используя Hough Transform на cv::gpu::GpuMat структура. Я попытался использовать как gpu::HoughLines, так и gpu::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

EDIT:

Я проверил на версии ЦП HoughLines и, кажется, работает нормально.

EDIT_2:

Решение опубликовано @ jet47 отлично работает.

+0

Как изображение выглядеть после применения Осторожного фильтра? – Mailerdaimon

+0

О, всего лишь секунда. Я отправлю его. И все. – scap3y

+0

Какую версию OpenCv вы используете? – Mailerdaimon

ответ

2

Вы используете неправильный код для загрузки результатов 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' представляет собой 4-компонентный вектор из 32-битных целых значений. Таким образом, это «CV_32SC4», а «CV_8UC3» - это 3-канальные 8-битные значения. Метод 'GpuMat :: download' проверяет тип выходной матрицы и перераспределяет данные, если тип mistmatch. – jet47

+0

Удивительный, спасибо за объяснение. Я уже пробовал, и он работал отлично. – scap3y

0

Я предполагаю, что метод, который вы используете, устарел (но я не совсем уверен).

Это, как я хотел бы сделать это (как показано в этом 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 выше использует OpenCV 3.0 интерфейс

+0

Это с интерфейсом 3.0, справа ..? Мне нужно заставить его работать с интерфейсом 2.4.x, так как это часть более крупного приложения, которое использует cv 2.4 .. Я также придерживался того же примера (но для 2.4.6), но я ничего не получаю. – scap3y

+0

Да, я так думаю, я оставлю ответ, хотя для людей, использующих 3.0. В вашем случае это, похоже, другая проблема. – Mailerdaimon

+0

Спасибо. Я совершенно не понимаю, что происходит.Сначала я подумал, что это потому, что модуль GPU не был построен должным образом, но это не так, поскольку другие вещи прекрасно работают. – scap3y

Смежные вопросы