17 #include <iCub/data3D/private/helpers.h> 18 #include <iCub/data3D/minBoundBox.h> 27 void buildRotMat2(
const double &theta,yarp::sig::Matrix &rot)
37 void buildRotMat3(
const double &alpha,
const double &beta,
const double &gamma,yarp::sig::Matrix &rot)
40 rot(0,0)=cos(beta)*cos(gamma);
41 rot(0,1)=-cos(beta)*sin(gamma);
43 rot(1,0)=sin(alpha)*sin(beta)*cos(gamma)+cos(alpha)*sin(gamma);
44 rot(1,1)=-sin(alpha)*sin(beta)*sin(gamma)+cos(alpha)*cos(gamma);
45 rot(1,2)=-sin(alpha)*cos(beta);
46 rot(2,0)=-cos(alpha)*sin(beta)*cos(gamma)+sin(alpha)*sin(gamma);
47 rot(2,1)=cos(alpha)*sin(beta)*sin(gamma)+sin(alpha)*cos(gamma);
48 rot(2,2)=cos(alpha)*cos(beta);
52 void findRotation2D(
const Matrix &xy, Matrix &rot2)
54 yarp::sig::Vector edgeangles;
56 for (
int j=0; j<xy.rows()-1; j++)
58 double val=atan2(xy(j+1,1)-xy(j,1),xy(j+1,0)-xy(j,0));
60 for (
int k=0; k<edgeangles.size(); k++)
62 if (edgeangles[k]==Helpers::mod(val,M_PI/2))
70 edgeangles.push_back(Helpers::mod(val,M_PI/2));
72 buildRotMat2(-Helpers::mod(val,M_PI/2),rot_i);
74 yarp::sig::Vector minimum;
75 Helpers::min(xyr,minimum);
76 yarp::sig::Vector maximum;
77 Helpers::max(xyr,maximum);
78 yarp::sig::Vector diff=maximum-minimum;
79 double prod=diff[0]*diff[1];
90 void findRotation(
const Matrix &xyz_i, Matrix &rot2)
92 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_on_plane(
new pcl::PointCloud<pcl::PointXYZ>);
94 for (
int j=0; j<xyz_i.rows(); j++)
100 cloud_on_plane->push_back(point);
103 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull2D (
new pcl::PointCloud<pcl::PointXYZ>);
104 pcl::ConvexHull<pcl::PointXYZ> chull2D;
105 chull2D.setInputCloud (cloud_on_plane);
106 chull2D.setDimension(2);
107 chull2D.reconstruct (*cloud_hull2D);
109 Matrix xy(cloud_hull2D->size(),2);
110 for (
int j=0; j<cloud_hull2D->size()-1; j++)
112 xy(j,0)=cloud_hull2D->at(j).x;
113 xy(j,1)=cloud_hull2D->at(j).y;
116 findRotation2D(xy,rot2);
120 void assignCorners(
const Matrix &minmax, Matrix &cornerpoints)
122 cornerpoints(0,0)=minmax(0,0);
123 cornerpoints(0,1)=minmax(0,1);
124 cornerpoints(0,2)=minmax(0,2);
125 cornerpoints(1,0)=minmax(1,0);
126 cornerpoints(1,1)=minmax(0,1);
127 cornerpoints(1,2)=minmax(0,2);
128 cornerpoints(2,0)=minmax(1,0);
129 cornerpoints(2,1)=minmax(1,1);
130 cornerpoints(2,2)=minmax(0,2);
131 cornerpoints(3,0)=minmax(0,0);
132 cornerpoints(3,1)=minmax(1,1);
133 cornerpoints(3,2)=minmax(0,2);
134 cornerpoints(4,0)=minmax(0,0);
135 cornerpoints(4,1)=minmax(0,1);
136 cornerpoints(4,2)=minmax(1,2);
137 cornerpoints(5,0)=minmax(1,0);
138 cornerpoints(5,1)=minmax(0,1);
139 cornerpoints(5,2)=minmax(1,2);
140 cornerpoints(6,0)=minmax(1,0);
141 cornerpoints(6,1)=minmax(1,1);
142 cornerpoints(6,2)=minmax(1,2);
143 cornerpoints(7,0)=minmax(0,0);
144 cornerpoints(7,1)=minmax(1,1);
145 cornerpoints(7,2)=minmax(1,2);
149 void eulerAngles(
const std::vector<yarp::sig::Vector> &edges1,
const std::vector<yarp::sig::Vector> &edges2,
const std::vector<yarp::sig::Vector> &crossProduct,yarp::sig::Vector &alpha,yarp::sig::Vector &beta,yarp::sig::Vector &gamma)
152 alpha.resize(crossProduct.size(),0.0);
153 beta.resize(crossProduct.size(),0.0);
154 gamma.resize(crossProduct.size(),0.0);
155 for (
int i=0; i<crossProduct.size(); i++)
157 double value=crossProduct.at(i)[0];
158 beta[i]=asin(std::min(abs(value),1.0)*Helpers::sign(value));
160 alpha[i]=asin(Helpers::sign(edges2.at(i)[2])*std::min(1.0,abs(edges2.at(i)[2])));
163 double tmp=crossProduct.at(i)[2]/cos(beta[i]);
164 alpha[i]=acos(Helpers::sign(tmp)*std::min(1.0,abs(tmp)));
165 if (Helpers::sign(crossProduct.at(i)[1])!=Helpers::sign(-sin(alpha[i])*cos(beta[i])))
167 singamma=-edges2.at(i)[0]/cos(beta[i]);
168 if (edges1.at(i)[0]>=0)
169 gamma[i]=asin(Helpers::sign(singamma)*std::min(1.0,abs(singamma)));
171 gamma[i]=-M_PI-asin(Helpers::sign(singamma)*std::min(1.0,abs(singamma)));
177 void retrieveEdges2(
const yarp::sig::Vector &vx,
const yarp::sig::Vector &vy,
const yarp::sig::Vector &vz,
const std::vector<yarp::sig::Vector> &edges1, std::vector<yarp::sig::Vector> &edges)
179 for (
int i=0; i<vx.size(); i++)
181 yarp::sig::Vector vect(3);
185 double dotprod=dot(edges1.at(i),vect);
186 vect=vect-dotprod*edges1.at(i);
187 double normvect=norm(vect);
189 edges.push_back(vect);
194 void retrieveEdges(
const yarp::sig::Vector &vx,
const yarp::sig::Vector &vy,
const yarp::sig::Vector &vz, std::vector<yarp::sig::Vector> &edges)
196 yarp::sig::Vector vxSquare=vx*vx;
197 yarp::sig::Vector vySquare=vy*vy;
198 yarp::sig::Vector vzSquare=vz*vz;
199 yarp::sig::Vector sum=vxSquare+vySquare+vzSquare;
201 for (
int i=0; i<sum.size(); i++)
203 yarp::sig::Vector vect(3);
204 vect[0]=vx[i]/(sqrt(sum[i]));
205 vect[1]=vy[i]/(sqrt(sum[i]));
206 vect[2]=vz[i]/(sqrt(sum[i]));
207 edges.push_back(vect);
212 BoundingBox MinimumBoundingBox::getMinimumBoundingBox(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud)
215 std::vector< pcl::Vertices > polygons;
216 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_hull (
new pcl::PointCloud<pcl::PointXYZRGB>);
217 pcl::ConvexHull<pcl::PointXYZRGB> chull;
218 chull.setInputCloud (cloud);
219 chull.setDimension(3);
220 chull.reconstruct (*cloud_hull,polygons);
222 yarp::sig::Vector x1;
223 yarp::sig::Vector x2;
224 yarp::sig::Vector x3;
225 yarp::sig::Vector y1;
226 yarp::sig::Vector y2;
227 yarp::sig::Vector y3;
228 yarp::sig::Vector z1;
229 yarp::sig::Vector z2;
230 yarp::sig::Vector z3;
232 for (
int i=0; i<polygons.size(); i++)
234 pcl::Vertices vertex=polygons.at(i);
235 x1.push_back(cloud_hull->at(vertex.vertices[0]).x);
236 x2.push_back(cloud_hull->at(vertex.vertices[1]).x);
237 x3.push_back(cloud_hull->at(vertex.vertices[2]).x);
238 y1.push_back(cloud_hull->at(vertex.vertices[0]).y);
239 y2.push_back(cloud_hull->at(vertex.vertices[1]).y);
240 y3.push_back(cloud_hull->at(vertex.vertices[2]).y);
241 z1.push_back(cloud_hull->at(vertex.vertices[0]).z);
242 z2.push_back(cloud_hull->at(vertex.vertices[1]).z);
243 z3.push_back(cloud_hull->at(vertex.vertices[2]).z);
246 Matrix pointCloud(cloud_hull->size(),3);
247 for (
int i=0; i<cloud_hull->size(); i++)
249 pointCloud(i,0)=cloud_hull->at(i).x;
250 pointCloud(i,1)=cloud_hull->at(i).y;
251 pointCloud(i,2)=cloud_hull->at(i).z;
254 yarp::sig::Vector v1x=x2-x1;
255 yarp::sig::Vector v1y=y2-y1;
256 yarp::sig::Vector v1z=z2-z1;
257 std::vector<yarp::sig::Vector> edges1;
259 retrieveEdges(v1x,v1y,v1z,edges1);
261 yarp::sig::Vector v2x=x3-x1;
262 yarp::sig::Vector v2y=y3-y1;
263 yarp::sig::Vector v2z=z3-z1;
264 std::vector<yarp::sig::Vector> edges2;
266 retrieveEdges2(v2x,v2y,v2z,edges1,edges2);
268 std::vector<yarp::sig::Vector> crossProduct;
269 for (
int i=0; i<edges1.size(); i++)
271 yarp::sig::Vector vect=cross(edges1.at(i),edges2.at(i));
272 crossProduct.push_back(vect);
275 yarp::sig::Vector alpha;
276 yarp::sig::Vector beta;
277 yarp::sig::Vector gamma;
278 eulerAngles(edges1, edges2, crossProduct, alpha, beta, gamma);
281 double minVol=100000;
284 for (
int i=0; i<alpha.size(); i++)
287 buildRotMat3(alpha[i],beta[i],gamma[i],rot);
288 Matrix xyz_i=pointCloud*rot;
289 findRotation(xyz_i,rot2);
291 Matrix rot3dim=eye(3,3);
292 rot3dim.setSubmatrix(rot2,0,0);
293 Matrix rotation=rot*rot3dim;
295 xyz_i=pointCloud*rotation;
296 yarp::sig::Vector minimum;
297 Helpers::min(xyz_i,minimum);
298 yarp::sig::Vector maximum;
299 Helpers::max(xyz_i,maximum);
300 yarp::sig::Vector h=maximum-minimum;
302 double prod=h[0]*h[1]*h[2];
307 minmax.setRow(0,minimum);
308 minmax.setRow(1,maximum);
311 Matrix cornerpointsTmp(8,3);
312 assignCorners(minmax,cornerpointsTmp);
313 Matrix cornerpoints=cornerpointsTmp*(bb.
getOrientation().transposed());
315 std::vector<iCub::data3D::PointXYZ> corners;
316 for (
unsigned int i=0; i<cornerpoints.rows(); i++)
317 corners.push_back(PointXYZ(cornerpoints(i,0),cornerpoints(i,1),cornerpoints(i,2)));
The Definition of the BoundingBox class.
yarp::sig::Matrix getOrientation()
Return the orientation of the Box3D structure.
void setCorners(const std::vector< iCub::data3D::PointXYZ > &corners)
Set the corners of the bounding box.
void setOrientation(const yarp::sig::Matrix &orientation)
Modify the orientation of the bounding box.