Ceci est une ancienne révision du document !
Table des matières
Programme sur Arduino
voir Diviseur de fréquence + affichage nombre de fronts descendants sur MAX7221 sur timer: http://homepages.laas.fr/bvandepo/wiki/doku.php?do=export_code&id=timer&codeblock=0
Noeud pour l'enregistrement des images au format PPM
La camera de gauche est master, elle envoie un signal à la caméra de droite et à elle même pour démarrer la prise de photo. L'arduino récupère ce signal pour incrémenter un compteur qu'il affiche sur l'afficheur 8 segments.
Création d'un catkin etc
Pour créer un catkin initialement
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace
il faut charger les variables d'environnement pour ce catkin (normalement on stocke le source … dans ~/.bashrc)
cd ~/catkin_ws/ source devel/setup.bash echo $ROS_PACKAGE_PATH
Pour péréniser:
echo "source ~/catkin_ws/devel/setup.bash" >>~/.bashrc
Récupération du node ueye_cam
Installation noeud ueye modifié par Ariel et Jessica:
cd ~/catkin_ws/src #changé de git clone ssh://git@redmine.laas.fr/laas/users/apodlubn/ueye_cam.git en: git clone https://github.com/bvandepo/ueye_cam.git
pour visualiser l'image en provenance d'une caméra:
cd ~/catkin_ws roslaunch ueye_cam rgb8.launch rosrun image_view image_view image:=/camera/image_raw rostopic list rostopic echo /camera/camera_info
pour étalonner en monoculaire avec une seule petite mire:
rosrun camera_calibration cameracalibrator.py --size 7x5 --square 0.01 image:=/camera/image_raw
pour étalonner en monoculaire avec deux mires:
rosrun camera_calibration cameracalibrator.py --size 7x6 --square 0.108 --size 8x5 --square 0.029 image:=/camera/image_raw
Grab the images from 2 cameras:
roslaunch ueye_cam stereo.launch
Création du node ueye_cam_test pour test synchro
pour créer un nouveau node vide avec les dépendances adéquates
cd ~/catkin_ws/src catkin_create_pkg ueye_cam_test camera_calibration_parsers camera_info_manager image_transport nodelet roscpp sensor_msgs std_msgs cv_bridge
compléter le fichier créé en ajoutant à la fin de src/ueye_cam_test/CMakeLists.txt:
- CMakeLists.txt
###############BVANDEPO############## include_directories(include ${catkin_INCLUDE_DIRS}) add_executable(ueye_cam_test_exe src/ueye_cam_test.cpp) target_link_libraries(ueye_cam_test_exe ${catkin_LIBRARIES})
copier le fichier cpp source dans:
~/catkin_ws_/src/ueye_cam_test/src/ueye_cam_test.cpp
- ueye_cam_test.cpp
// from ueyecam_nodelet #include <ros/package.h> #include <camera_calibration_parsers/parse.h> #include <sensor_msgs/fill_image.h> #include <sensor_msgs/image_encodings.h> #include <sstream> #include "std_msgs/String.h" // code sample image transport #include <ros/ros.h> #include <image_transport/image_transport.h> #include <opencv2/highgui/highgui.hpp> #include <cv_bridge/cv_bridge.h> // For time synchronizer #include <message_filters/subscriber.h> #include <message_filters/time_synchronizer.h> #include <sensor_msgs/Image.h> #include <iostream> #include <sstream> #include <stdio.h> #include <cstring> using namespace sensor_msgs; using namespace message_filters; unsigned int k(0); /*****************************************************/ /*** SAVE_PPM ***/ /*****************************************************/ void save_ppm(char *filename, char *im, unsigned int width, unsigned int height) { FILE *f; if(!(f=fopen(filename,"wb"))) { fprintf(stderr,"Could not open `%s'",filename); exit(1); } fprintf(f,"P6\n%d %d\n255\n",width,height); fwrite(im,1,width*height*3,f); fclose(f); } /*****************************************************/ /*** SAVE_PPM_NAMED ***/ /*****************************************************/ void save_ppm_named(char *basename, int k,char *endname,cv_bridge::CvImagePtr cv_ptr_1) { std::stringstream sstm; std::string nameFileL; sstm << basename << std::setfill('0') << std::setw(5) << k << endname; nameFileL = sstm.str(); save_ppm((char*)nameFileL.c_str(), (char*)cv_ptr_1->image.data, cv_ptr_1->image.cols, cv_ptr_1->image.rows); } /*****************************************************/ /*** IMAGE CALLBACK ***/ /*****************************************************/ void imageCallback(const sensor_msgs::ImageConstPtr& msg) { try { cv_bridge::CvImagePtr cv_ptr_1 = cv_bridge::toCvCopy(msg, "bgr8"); save_ppm_named((char*)"/tmp/images/ueye_", k,(char*)"_mono.ppm",cv_ptr_1); cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image); cv::waitKey(30); k++; } catch (cv_bridge::Exception& e) { ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str()); } } /*****************************************************/ /*** STEREO CALLBACK ***/ /*****************************************************/ void stereoCallback(const ImageConstPtr& image1, const ImageConstPtr& image2) { // Solve all of perception here... try { cv_bridge::CvImagePtr cv_ptr_1 = cv_bridge::toCvCopy(image1, "bgr8"); cv_bridge::CvImagePtr cv_ptr_2 = cv_bridge::toCvCopy(image2, "bgr8"); // save left image save_ppm_named((char*)"/tmp/images/ueye_", k,(char*)"_left.ppm",cv_ptr_1); // save right image save_ppm_named((char*)"/tmp/images/ueye_", k,(char*)"_right.ppm",cv_ptr_2); // show image cv::imshow("view_left", cv_ptr_1->image); cv::imshow("view_right", cv_ptr_2->image); cv::waitKey(30); k++; } catch (cv_bridge::Exception& e) { ROS_ERROR("Could not convert from '%s' to 'bgr8'.", image1->encoding.c_str()); } } /*****************************************************/ /*** MAIN ***/ /*****************************************************/ int main(int argc, char **argv) { // create folder where we save images system("mkdir /tmp/images"); ros::init(argc, argv, "listenerUeye"); ros::NodeHandle nh; bool stereo(true); if(!stereo){ ROS_INFO("ueye_cam_test in moncular mode"); cv::namedWindow("view"); cv::startWindowThread(); image_transport::ImageTransport it(nh); image_transport::Subscriber sub = it.subscribe("/camera/image_raw", 1, imageCallback); ros::spin(); cv::destroyWindow("view"); } else{ ROS_INFO("ueye_cam_test in binocular mode"); cv::namedWindow("view_left"); cv::namedWindow("view_right"); cv::startWindowThread(); message_filters::Subscriber<Image> image_left_sub(nh, "/stereo/left/image_raw", 1); message_filters::Subscriber<Image> image_right_sub(nh, "/stereo/right/image_raw", 1); TimeSynchronizer<Image, Image> sync(image_left_sub, image_right_sub, 10); sync.registerCallback(boost::bind(&stereoCallback, _1, _2)); ros::spin(); cv::destroyWindow("view_left"); cv::destroyWindow("view_right"); } }
Adapter dans ~/catkin_ws_/src/ueye_cam_test/src/ueye_cam_test.cpp la ligne pour s'abonner au topic image/raw ou /stereo/right/image_raw et /stereo/left/image_raw
bool stereo(false); ou bool stereo(true);
pour compiler:
cd ~/catkin_ws/ catkin_make
Il n'y a pas de launch. Pour lancer le programme en monoculaire:
roscore roslaunch ueye_cam rgb8.launch rosrun image_view image_view image:=/camera/image_raw rosrun ueye_cam_test ueye_cam_test_exe
TODO: expliquer pour lancer en stéréo et tester
Résultats
Bag from files node
Node créé par Raul Mur Artal et adapté par Ariel pour gérer les séquences en stéréo
Nous l'utilisons pour regénérer un fichier bag contenant une séquence d'images précédemment enregistrée par l'outils cameracalibrator.py dans le fichier calibrationdata.tar.gz
cd ~/catkin_ws cd src git clone ssh://git@redmine.laas.fr/laas/users/apodlubn/bagfromimages.git echo "export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:/home/bvandepo/catkin_ws/src/bagfromimages" >>~/.bashrc mkdir build cd build cmake .. make sudo make install cd ..
mkdir -p ~/2ears/seq1 cd ~/2ears/seq1
y écrire ce fichier:
- constructbag.sh
tar xvf calibrationdata.tar.gz mkdir left mkdir right mv left-* left/ mv right-* right/ FOLDER=`pwd` echo $FOLDER rosrun bagfromimages bagfromimages $FOLDER/left/ $FOLDER/right/ .png 2 $FOLDER/images.bag rm -rf left/ rm -rf right/
chmod a+x constructbag.sh ./constructbag.sh
Les paramètres sont les suivants:
- 1: Left images folder
- 2: Right images folder
- 3: image format
- 4: number of frames per second to export to the bag file
- 5: bag's output
Pour rejouer une séquence enregistrée:
cd ~/2ears/seq1 rosbag play images.bag