2013-05-15 82 views
4

我正在從兩幅圖像(我從opencv StereoBM獲取它)獲取深度圖,現在我需要找到它們中的簇 我決定使用pcl區域生長分割http://www.pointclouds.org/documentation/tutorials/region_growing_segmentation.php 。我在閱讀這篇文章http://blog.martinperis.com/2012/01/3d-reconstruction-with-opencv-and-point.html後將cv :: Mat轉換爲點雲,現在我擁有簇索引 這就是這裏的功能https://gist.github.com/Daiver/5586252 現在我想要使用這些索引在StereoBM(cv :: Mat)使用rgb圖像中的點雲聚簇索引

我想這一點,但我不太滿意的結果

pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; //cloud from depth map and rgb image 
    std::vector <pcl::PointIndices> clusters;// clusters inices, extracted before 
    for(int j = 0; j < clusters.size(); j++) 
    { 
     cv::Mat to_show = cv::Mat::zeros(288, 384, cv::DataType<uchar>::type);//image has size that equal size of rgb image and depth map   
     for(int i = 0; i < clusters[j].indices.size(); i++) 
     { 
     to_show.data[clusters[j].indices[i]] = 200;// regions in this Mat must be equal with regions from depth map 
     } 
     cv::imshow("", to_show); 
     cv::waitKey(); 
    } 

結果 某些集羣 enter image description here 另一個集羣 enter image description here

可視化雲 enter image description here

我如何將項目投影到cv :: Mat? PS抱歉我寫錯了。英語不是我的母語

UPD 我tryed通過使用類似的循環迴路中mat_to_cloud功能

int counter = 0; 
cv::Mat to_show = cv::Mat::zeros(288, 384, cv::DataType<uchar>::type); 
for(int i = 0; i < cloud->height; i++) 
{ 
    for(int j = 0; j < cloud->width; j++) 
    { 
    to_show.at<uchar>(i, j) = cloud->at(counter).z; 
    counter++; 
    } 
} 

enter image description here

和循環的另一種秩序 INT計數器「恢復」深度圖= 0; cv :: Mat to_show = cv :: Mat :: zeros(288,384,cv :: DataType :: type); 對(INT J = 0;Ĵ<雲>寬度; J ++){ 爲 (INT I = 0;我<雲>高度;我++){ to_show.at(I,J)=雲>在(計數器).Z; counter ++; }}

enter image description here

我不知道爲什麼這些圖像類似於

+0

究竟對結果是錯誤的或你不喜歡?另外,截圖中的哪張圖片顯示了什麼? – Sarien

+0

我想在深度圖中看到獨立的羣集。像單頭或單燈或單個相機 –

+0

這就是你想要的,但是你的結果是什麼以及它有什麼問題? – Sarien

回答

0

我解決了我的問題,但我的解決方案有點骯髒和愚蠢。 我做我自己的簡單重投影功能

void straight_reproject_cloud(cv::Mat& img_rgb, cv::Mat& img_disparity, pcl::PointCloud<pcl::PointXYZRGB>::Ptr& point_cloud_ptr) 
{ 
    uchar pr, pg, pb; 
    for (int i = 0; i < img_rgb.rows; i++) 
    { 
     uchar* rgb_ptr = img_rgb.ptr<uchar>(i); 
     uchar* disp_ptr = img_disparity.ptr<uchar>(i); 
     for (int j = 0; j < img_rgb.cols; j++) 
     { 
      uchar d = disp_ptr[j]; 
      if (d == 0) continue; //Discard bad pixels 
      pb = rgb_ptr[3*j]; 
      pg = rgb_ptr[3*j+1]; 
      pr = rgb_ptr[3*j+2]; 
      //Insert info into point cloud structure 
      pcl::PointXYZRGB point; 
      point.x = j; 
      point.y = i; 
      point.z = d; 
      uint32_t rgb = (static_cast<uint32_t>(pr) << 16 | 
        static_cast<uint32_t>(pg) << 8 | static_cast<uint32_t>(pb)); 
      point.rgb = *reinterpret_cast<float*>(&rgb); 
      point_cloud_ptr->push_back (point); 
     } 
    } 
} 

此功能將指向直接雲從圖像,無需改動 新的雲沒有與老重投影正值,但我可以用它

工作,現在點的座標在雲concided在圖像座標 我可以顯示來自雲中的所有集羣中的圖像:

for(int k = 0; k < clusters.size(); k++) 
{ 
    cv::Mat res = cv::Mat::zeros(img_rgb.rows, img_rgb.cols, CV_8U); 
    //for(int i =0 ; i < point_cloud_ptr->points.size(); i++) 
    for(int j =0 ; j < clusters[k].indices.size(); j++) 
    { 
     int i = clusters[k].indices[j]; 
     int x = point_cloud_ptr->at(i).x; 
     int y = point_cloud_ptr->at(i).y; 
     res.at<uchar>(y, x) = (int)(point_cloud_ptr->at(i).z); 
    } 
    cv::imshow("rec2", res); 
    cv::waitKey(); 
} 

enter image description here

新的雲

enter image description here

+0

也許我的reprojection幫助某人 –

1

我還沒有和PCL的工作之前,但它看起來像這條線可能是錯的:

to_show是一個opencv矩陣,但您使用點雲中的索引。您需要首先將索引轉換爲像素座標。

+0

謝謝你的回答。我認爲你是對的,但是來自雲的索引取決於來自Mat的像素,因爲我在這個週期中添加了點雲: for(int i = 0; i push_back(point); // push_back添加了點向量的結尾點?我認爲,雲點的順序與「數據」點相同。 } } –

+0

可能是對的,我認爲你的數據類型不正確,或者存在對齊問題,或者圖像數據按列主模式排序。嘗試檢查這些。 – Sarien

+0

你的意思是to_Show的數據類型? 「或圖像數據在列主模式下排序」我想過它,但我不知道如何檢查它 –