Opencv 在 HoughLineP() 的输出上运行 Kmeans:矢量到垫子的转换

Opencv running Kmeans on output of HoughLineP(): Vector to Mat conversion?

本文关键字:转换 Kmeans 运行 HoughLineP 输出 Opencv      更新时间:2023-10-16

我一直在尝试在cv::HoughLinesP((的输出上运行kmeans。我的问题来自将 HoughLinesP(( 的输出转换为 opencv_lines ,这是一个Vector<Vec4i>向量到矩阵。这听起来非常简单,我敢打赌是这样,但是,我是opencv和数据结构的新手,并且尝试了很多东西。 这是我尝试实现的代码。

HoughLinesP(image_after_canny, opencv_lines, 2, 0.05*CV_PI/180, lower_hough_prob_min_no_of_intersections_trackbar + hough_prob_min_no_of_intersections_trackbar, lower_hough_prob_min_no_of_points_trackbar + hough_prob_min_no_of_points_trackbar, lower_hough_prob_max_gap_bw_points_trackbar + hough_prob_max_gap_bw_points_trackbar);
//opencv_lines is an Nx4 opencv[0] = [x1, y1, x2, y2]
//Spatial Clustering on line endpoints
//For each frame the endpoints should not change much relative to location

//sanity checking
// Mat samples = Mat(opencv_lines);
// samples.convertTo(samples, CV_32F);
// cout << samples.dims << endl;
// cout << samples.depth() << endl;
// cout << samples.type() << endl;
//Convert the opencv_lines into a matrix for kmeas
//There must be an better way
Mat samples  = Mat(opencv_lines.size(), 4, CV_32FC1); //create a Nx4 matrix oftype 32F 
for(int r = 0; r<opencv_lines.size(); r++){
      Vec4i l_cur = opencv_lines[r];
      for(int c = 0; c<4; c ++){
        samples.at<float>(r,c) = opencv_lines[r][c];
      }
}

cout << "Running Kmeans" << endl;
cv::kmeans(opencv_lines,K,labels, TermCriteria( CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, max_iteration, epsilone), attempts, cv::KMEANS_PP_CENTERS, centers);

我收到的错误是:


检测线 OpenCV 错误:断言失败(data0.dims <= 2 && type == CV_32F && K> 0(,在 kmeans,文件/Development/OpenCV/modules/core/src/kmeans.cpp,第 230 行 libc++abi.dylib:以 cv 类型的未捕获异常终止::异常:/Development/OpenCV/modules/core/src/kmeans.cpp:230:错误:(-215( data0.dims <= 2 && type == 函数 kmeans 中的 CV_32F && K> 0

Abort trap: 6

我已经尝试了许多使用 memecopy(samples.data, opencv_lines.data()*sizeof(float)); 和其他各种循环结构来做到这一点的方法。

我什至切换到 python 实现并遇到了同样的 dang 问题!! 所以我正式卡住了。

PS 我知道 hough 的输出工作正常并且有线条。更新:我添加了一些打印语句,并一直在使用 reshape(( 函数,认为我不满足 data0.dims <=2。

以下是新的编辑:

 Mat samples  = Mat(opencv_lines.size(), 4, CV_32F); //create a Nx4 matrix oftype 32F 
    for(int r = 0; r<opencv_lines.size(); r++){
          Vec4i l_cur = opencv_lines[r];
          for(int c = 0; c<4; c ++){
            samples.at<float>(r,c) = opencv_lines[r][c];
            cout << opencv_lines[r][c] << " " ;
          }
          cout << ""<< endl;
    }
    samples=samples.reshape(1,samples.rows * 2);
    samples.convertTo(samples, CV_32F);
    cout << "M = "<< endl << " "  << samples << endl << endl;
    cout << "Running Kmeans" << endl;
    cv::kmeans(opencv_lines,K,labels, TermCriteria( CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, max_iteration, epsilon), attempts, cv::KMEANS_PP_CENTERS, centers);

然而同样的错误:

   Fetching Video
Initializing Parameter
Begin Playback
Frame
Generating Skeleton Image
Detecting Lines
335 471 335 112 
337 443 338 105 
339 443 339 103 
355 68 382 478 
291 479 313 162 
356 66 383 478 
436 2 533 223 
293 479 316 152 
440 3 523 195 
416 0 500 427 
359 63 383 474 
416 4 499 425 
437 0 534 223 
343 479 376 153 
427 0 525 305 
427 1 579 479 
344 478 378 153 
M = 
 [335, 471;
 335, 112;
 337, 443;
 338, 105;
 339, 443;
 339, 103;
 355, 68;
 382, 478;
 291, 479;
 313, 162;
 356, 66;
 383, 478;
 436, 2;
 533, 223;
 293, 479;
 316, 152;
 440, 3;
 523, 195;
 416, 0;
 500, 427;
 359, 63;
 383, 474;
 416, 4;
 499, 425;
 437, 0;
 534, 223;
 343, 479;
 376, 153;
 427, 0;
 525, 305;
 427, 1;
 579, 479;
 344, 478;
 378, 153]
Running Kmeans
OpenCV Error: Assertion failed (data0.dims <= 2 && type == CV_32F && K > 0) in kmeans, file /Development/OpenCV/modules/core/src/kmeans.cpp, line 230
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: Development/OpenCV/modules/core/src/kmeans.cpp:230: error: (-215) data0.dims <= 2 && type == CV_32F && K > 0 in function kmeans
Abort trap: 6

有人可以帮助澄清文档中描述的输入结构。

用于聚类分析的数据。需要具有浮点坐标的 N 维点数组。此数组的示例可以是:

Mat points(count, 2, CV_32F);
Mat points(count, 1, CV_32FC2);
Mat points(1, count, CV_32FC2);
std::vector<cv::Point2f> points(sampleCount);

我最终改用 python 实现并使用 sci-kit 在 hough 输出上运行 dbscan。通过这种方式,我能够通过过滤器将概率 hough 输出聚类到不同的部分,在此处输入不需要的线段的图像描述。