Kinect v2保存图像和深度图序列
上班后的端午節就意味著多一天的假期!!!
本工作的主要出發點是錄制數據集,用來供后續的建圖和bug重現。
軟硬件配置
環境配置如下:
系統:Ubuntu 16.04 LTS? 64位
CPU: Intel? Core? i7-7700 CPU @ 3.60GHz × 8?
內存:16G
工作內容
1)保存的工作主要是在ROS環境下,所以沒有ROS環境的話,可以先配置一下ROS環境;
2)Kinect v2的驅動應該是已經配置好了的,包括libfreenet2和catkin工作環境下的iai_kinect2;
3)如果對Kinect v2保存不要求幀率,可以參考這篇博客(感謝這位博主提供的教程)中的保存圖像序列。在這個工作中,能夠保存對應的彩色圖,深度圖,彩色深度圖以及點云文件pcd,但幀率很慢,我在10s內通過這種方法保存了28張圖片,所以幀率大約是在2~3fps之間。
4)為了能夠使圖像之間更加連續,關聯性更大,發現代碼保存是每一個循環都會調用一個imwrite,如果一張1920x1080圖片0.8M,按照Kinect v2官方給出的fps為30,那么你的磁盤寫入速率應該達到24M/s,如果考慮到深度圖還要寫入,那么應該是48M/s,我覺得可能是寫這塊太耗時,而且我也用不著每一幀的點云文件和彩色深度圖,所以在saveCloudAndImages函數里注釋掉這兩行
OUT_INFO("saving cloud: " << cloudName); writer.writeBinary(cloudName, *cloud);OUT_INFO("saving depth: " << depthColoredName); cv::imwrite(depthColoredName, depthColored, params);然后重新在catkin_make? , source devel/set_up.bash后,保存速度可以達到5fps。仍然很慢。
5)查看ROS讀取Kinect v2的平均速度是在10~20fps之間跳動,所以達不到30fps(目前我猜測可能是ROS讀取的原因),但5fps也太慢了,我決定不要求每一次讀入圖片都立即保存,先將其存在內存中,等結束時再統一寫入磁盤,這樣帶來的問題是很吃內存,所以不能保存太長時間。經過這樣的修改方案,保存結果是8fps,比之前有所提升,但還是比較慢。修改如下:
注:這個修改是基于上面提出那篇博客的基礎之上修改的,當然也沒有保存pcd點云文件和彩色深度圖。
在Receiver類中添加私有變量?
bool save_stop; std::vector<cv::Mat> vcolor; std::vector<cv::Mat> vdepth;在Receiver的構造函數中添加
save_stop(false);我這次主要是在imageviewer這個函數里修改,void imageViewer(),而不是下面的Cloudviewer,讀者有興趣可以對比著原來的代碼看看,我主要是將讀取鍵盤的指令移入到for循環當中了。
void imageViewer(){cv::Mat color, depth, depthDisp, combined;std::chrono::time_point<std::chrono::high_resolution_clock> start, now;double fps = 0;size_t frameCount = 0;std::ostringstream oss;const cv::Point pos(5, 15);const cv::Scalar colorText = CV_RGB(255, 255, 255);const double sizeText = 0.5;const int lineText = 1;const int font = cv::FONT_HERSHEY_SIMPLEX;cv::namedWindow("Image Viewer");oss << "starting...";start = std::chrono::high_resolution_clock::now();for(; running && ros::ok();){if(updateImage){lock.lock();color = this->color;depth = this->depth;updateImage = false;lock.unlock();++frameCount;now = std::chrono::high_resolution_clock::now();double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count() / 1000.0;if(elapsed >= 1.0){fps = frameCount / elapsed;oss.str("");oss << "fps: " << fps << " ( " << elapsed / frameCount * 1000.0 << " ms)";//std::cerr << "fps: " << fps << " ( " << elapsed / frameCount * 1000.0 << " ms)"<< std::endl;start = now;frameCount = 0;}dispDepth(depth, depthDisp, 12000.0f);combine(color, depthDisp, combined);//combined = color;cv::putText(combined, oss.str(), pos, font, sizeText, colorText, lineText, CV_AA);cv::imshow("Image Viewer", combined);int key = cv::waitKey(1);switch(key & 0xFF){case 27:case 'q':running = false;break;case 'b': save_seq = true; save = true; break;case 'e': save_seq = false; save = false; save_stop = true; break;case ' ':case 's':if (save_seq) break;}if (save_seq) {save = false;cv::Mat depthDisp;dispDepth(depth, depthDisp, 12000.0f);vcolor.push_back(color.clone());vdepth.push_back(depthDisp.clone()); }if(!save_seq && save_stop){std::cerr << "starting saving ..."<<std::endl;for(size_t i = 0; i < vcolor.size(); i ++){oss.str("");oss << "./" << std::setfill('0') << std::setw(4) << i;const std::string baseName = oss.str();const std::string colorName = baseName + "_color.jpg";const std::string depthName = baseName + "_depth.png";OUT_INFO("saving color: " << colorName);cv::imwrite(colorName, color, params);OUT_INFO("saving depth: " << depthName);cv::imwrite(depthName, depth, params);}OUT_INFO("saving complete!");save_stop = false;//save_seq = false;vcolor.clear();vdepth.clear();}}}cv::destroyAllWindows();cv::waitKey(100);}保存后再次在~/catkin_ws目錄下運行catkin_make,應該還有一些后綴,讀者自己找一下吧,然后source一下devel/setup.bash,
運行原來的命令就好,但是這條命令最后的cloud應該改為image,
rosrun kinect2_viewer ve_seq hd image這樣就可以保存1920x1080的圖片序列和深度圖序列了。
后續可能可以修改的點,我覺得8fps還是太慢,我后面還要用Kinect v2的話,應該會考慮不在ROS下運行,然后保存。我看到過一篇博文,博主說能保存到15fps,不過看他是在windows下實現的,沒有細看,有興趣的朋友可以找找看。
總結
以上是生活随笔為你收集整理的Kinect v2保存图像和深度图序列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android studio 跳转后保留
- 下一篇: 光滑噪声数据常用的方法_整理一份详细的数