grasp
All Data Structures Namespaces Functions Modules
reconstructionRoutine.cpp
1 /* Copyright: (C) 2014 iCub Facility - Istituto Italiano di Tecnologia
2  * Authors: Ilaria Gori
3  * email: ilaria.gori@iit.it
4  * Permission is granted to copy, distribute, and/or modify this program
5  * under the terms of the GNU General Public License, version 2 or any
6  * later version published by the Free Software Foundation.
7  *
8  * A copy of the license can be found in the file LICENSE located in the
9  * root directory.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details
15 */
16 
17 #include <reconstructionRoutine.h>
18 
19 using namespace std;
20 using namespace cv;
21 using namespace yarp::dev;
22 using namespace yarp::sig;
23 using namespace yarp::os;
24 using namespace iCub::ctrl;
25 
26 /************************************************************************/
27 ReconstructionRoutine::ReconstructionRoutine() :
28  cloud(new pcl::PointCloud<pcl::PointXYZRGB>),
29  cloudComplete(new pcl::PointCloud<pcl::PointXYZRGB>)
30 {
31  resetClouds();
32 }
33 
34 /************************************************************************/
35 bool ReconstructionRoutine::open(const Property &options)
36 {
37  Property &opt=const_cast<Property&>(options);
38 
39  string configFileDisparity=opt.check("ConfigDisparity",Value("icubEyes.ini")).asString().c_str();
40  string cameraContext=opt.check("CameraContext",Value("cameraCalibration")).asString().c_str();
41  string name=opt.check("name",Value("object-reconstruction")).asString().c_str();
42  disparityOut.open("/"+name+"/depth:o");
43 
44  ResourceFinder cameraFinder;
45  cameraFinder.setDefaultContext(cameraContext.c_str());
46  cameraFinder.setDefaultConfigFile(configFileDisparity.c_str());
47  cameraFinder.setVerbose();
48  cameraFinder.configure(0,NULL);
49 
50  disp=new DisparityThread(name,cameraFinder, false, false, true);
51  disp->start();
52 
53  return true;
54 }
55 
56 /************************************************************************/
57 void ReconstructionRoutine::close()
58 {
59  disp->stop();
60  delete disp;
61 }
62 
63 /************************************************************************/
64 void ReconstructionRoutine::filter(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in,pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in_filtered)
65 {
66  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_downsampled (new pcl::PointCloud<pcl::PointXYZRGB>);
67  pcl::VoxelGrid<pcl::PointXYZRGB> voxfilter;
68  voxfilter.setInputCloud (cloud_in);
69  voxfilter.setLeafSize (0.01f, 0.01f, 0.01f);
70  voxfilter.filter (*cloud_downsampled);
71  pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
72  sor.setInputCloud (cloud_downsampled);
73  sor.setMeanK (cloud_downsampled->size()/2);
74  sor.setStddevMulThresh (1.0);
75  sor.filter (*cloud_in_filtered);
76 }
77 
78 /************************************************************************/
79 pcl::PointCloud<pcl::PointXYZRGB>::Ptr ReconstructionRoutine::getPointCloud()
80 {
81  return this->cloud;
82 }
83 
84 /************************************************************************/
85 pcl::PointCloud<pcl::PointXYZRGB>::Ptr ReconstructionRoutine::getPointCloudComplete()
86 {
87  return this->cloudComplete;
88 }
89 
90 /************************************************************************/
91 void ReconstructionRoutine::resetClouds()
92 {
93  cloud->clear();
94  cloudComplete->clear();
95 }
96 
97 /************************************************************************/
98 bool ReconstructionRoutine::triangulateSinglePoint(IplImage* imgL, IplImage* imgR,
99  yarp::sig::Vector &point2D,
100  yarp::sig::Vector &point3D)
101 {
102  point3D.resize(3,0.0);
103  Mat leftIm=cvarrToMat(imgL);
104  Mat rightIm=cvarrToMat(imgR);
105  disp->setImages(leftIm,rightIm);
106  while(!disp->checkDone())
107  yarp::os::Time::delay(0.1);
108 
109  Point2f pixel(point2D[0],point2D[1]);
110 
111  Point3f point;
112  disp->triangulate(pixel,point);
113  if (point.z==0)
114  return false;
115 
116  point3D[0]=point.x;
117  point3D[1]=point.y;
118  point3D[2]=point.z;
119 
120  return true;
121 }
122 
123 /************************************************************************/
124 bool ReconstructionRoutine::reconstruct(IplImage* imgL, IplImage* imgR, Bottle& pixelList)
125 {
126  Mat leftIm=cvarrToMat(imgL);
127  Mat rightIm=cvarrToMat(imgR);
128  disp->setImages(leftIm,rightIm);
129  while(!disp->checkDone())
130  yarp::os::Time::delay(0.1);
131 
132  triangulation(imgL,cloudComplete,pixelList);
133  filter(cloudComplete,cloud);
134 
135  return true;
136 }
137 
138 /************************************************************************/
139 bool ReconstructionRoutine::updateDisparity(IplImage* imgL, IplImage* imgR)
140 {
141  Mat leftIm=cvarrToMat(imgL);
142  Mat rightIm=cvarrToMat(imgR);
143  disp->setImages(leftIm,rightIm);
144  while(!disp->checkDone())
145  yarp::os::Time::delay(0.1);
146 
147  Mat disparity;
148  disp->getDisparity(disparity);
149  IplImage disparityImg=disparity;
150  ImageOf<PixelMono> depthToDisplay;
151  depthToDisplay.wrapIplImage(&disparityImg);
152  disparityOut.prepare()=depthToDisplay;
153  disparityOut.write();
154 
155  return true;
156 }
157 
158 /************************************************************************/
159 void ReconstructionRoutine::triangulation(IplImage* imgL, pcl::PointCloud<pcl::PointXYZRGB>::Ptr input, yarp::os::Bottle& pixelList)
160 {
161  Bottle* listOfPoints=pixelList.get(0).asList();
162  int n=0;
163  for (int i=0; i<listOfPoints->size(); i++)
164  {
165  Point2f point2D;
166  Bottle* point=listOfPoints->get(i).asList();
167  point2D.x=point->get(0).asDouble();
168  point2D.y=point->get(1).asDouble();
169 
170  Point3f point3D;
171  disp->triangulate(point2D,point3D);
172  if (point3D.z==0)
173  continue;
174 
175  CvScalar color=cvGet2D(imgL,point2D.y,point2D.x);
176 
177  pcl::PointXYZRGB newPoint;
178  newPoint.x=point3D.x;
179  newPoint.y=point3D.y;
180  newPoint.z=point3D.z;
181 
182  newPoint.r=color.val[0];
183  newPoint.g=color.val[1];
184  newPoint.b=color.val[2];
185 
186  uint8_t r=color.val[0];
187  uint8_t g=color.val[1];
188  uint8_t b=color.val[2];
189 
190  newPoint.rgba = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
191 
192  input->push_back(newPoint);
193  }
194 }
195