00001 #include "Outline2ToQImage.h"
00002 #include <wrap/qt/col_qt_convert.h>
00003 using namespace vcg;
00004 using namespace std;
00005
00006 void Outline2Dumper::rectSetToOutline2Vec(vector< Box2f > &rectVec, vector< vector<Point2f> > &outline2Vec)
00007 {
00008 outline2Vec.clear();
00009 for(size_t i=0;i<rectVec.size();++i)
00010 {
00011 Box2f &b=rectVec[i];
00012 outline2Vec.resize(outline2Vec.size()+1);
00013 outline2Vec.back().push_back(b.min);
00014 outline2Vec.back().push_back(Point2f(b.max[0],b.min[1]));
00015 outline2Vec.back().push_back(b.max);
00016 outline2Vec.back().push_back(Point2f(b.min[0],b.max[1]));
00017 }
00018 }
00019
00020
00021 void Outline2Dumper::multiRectSetToSingleOutline2Vec(vector< Box2f > &rectVec,
00022 vector<Similarity2f> &trVec, vector<int> &indVec,
00023 int ind, vector< vector<Point2f> > &outline2Vec,
00024 vector<Similarity2f> &trOutline2Vec)
00025 {
00026 outline2Vec.clear();
00027 trOutline2Vec.clear();
00028
00029 for(size_t i=0;i<rectVec.size();++i)
00030 if(indVec[i]==ind)
00031 {
00032 trOutline2Vec.push_back(trVec[i]);
00033 Box2f &b=rectVec[i];
00034 outline2Vec.resize(outline2Vec.size()+1);
00035 outline2Vec.back().push_back(b.min);
00036 outline2Vec.back().push_back(Point2f(b.max[0],b.min[1]));
00037 outline2Vec.back().push_back(b.max);
00038 outline2Vec.back().push_back(Point2f(b.min[0],b.max[1]));
00039 }
00040 }
00041
00042 void Outline2Dumper::multiOutline2VecToSingleOutline2Vec(const std::vector< std::vector<Point2f> > &multiPolyVec,
00043 const std::vector<Similarity2f> &multiTrVec,
00044 const std::vector<int> &indVec, int ind,
00045 std::vector< std::vector<Point2f> > &singlePolyVec,
00046 std::vector<Similarity2f> &singleTrVec)
00047 {
00048 singlePolyVec.clear();
00049 singleTrVec.clear();
00050
00051 for(size_t i=0;i<multiPolyVec.size();++i)
00052 if(indVec[i]==ind)
00053 {
00054 singleTrVec.push_back(multiTrVec[i]);
00055 singlePolyVec.resize(singlePolyVec.size()+1);
00056 singlePolyVec.back()=multiPolyVec[i];
00057 }
00058 }
00059
00060
00061 void Outline2Dumper::dumpOutline2VecSVG(const char * imageName,
00062 vector< vector<Point2f> > &outline2Vec,
00063 vector<Similarity2f> &trVec,
00064 Outline2Dumper::Param &pp)
00065 {
00066 vector< vector< vector<Point2f> > > outline2VecVec(outline2Vec.size());
00067 for(size_t i=0;i<outline2Vec.size();++i)
00068 {
00069 outline2VecVec[i].resize(1);
00070 outline2VecVec[i][0]=outline2Vec[i];
00071 }
00072 dumpOutline2VecSVG(imageName,outline2VecVec,trVec,pp);
00073 }
00074
00075 void Outline2Dumper::dumpOutline2VecPNG(const char * imageName, vector< vector<Point2f> > &polyVec, vector<Similarity2f> &trVec, Outline2Dumper::Param &pp)
00076 {
00077 vector< vector< vector<Point2f> > > polyVecVec(polyVec.size());
00078 for(size_t i=0;i<polyVec.size();++i)
00079 {
00080 polyVecVec[i].resize(1);
00081 polyVecVec[i][0]=polyVec[i];
00082 }
00083 dumpOutline2VecPNG(imageName,polyVecVec,trVec,pp);
00084 }
00085
00086 void Outline2Dumper::dumpOutline2VecPNG(const char * imageName, vector< vector< vector<Point2f> > > &polyVecVec, vector<Similarity2f> &trVec, Outline2Dumper::Param &pp)
00087 {
00088 vector<string> labelVec;
00089 dumpOutline2VecPNG(imageName,polyVecVec,trVec,labelVec,pp);
00090 }
00091
00092 void Outline2Dumper::dumpOutline2VecSVG(const char * imageName, vector< vector< vector<Point2f> > > &polyVecVec, vector<Similarity2f> &trVec, Outline2Dumper::Param &pp)
00093 {
00094 vector<string> labelVec(polyVecVec.size());
00095 dumpOutline2VecSVG(imageName,polyVecVec,trVec,labelVec,pp);
00096 }
00097
00100 void Outline2Dumper::DrawPolygonMask(const vector< vector<Point2f> > &polyVec,
00101 QImage &img,
00102 Similarity2f &ret,
00103 const Similarity2f &trans)
00104 {
00105
00107 QPainter painter;
00108 painter.begin(&img);
00109 QBrush bb;
00110 bb.setStyle(Qt::SolidPattern);
00111
00112 int resolution=img.width();
00113
00114 QPen qp;
00115 qp.setWidthF(0);
00117 vcg::Box2f bbox;
00118 for(size_t i=0;i<polyVec.size();++i)
00119 for(size_t j=0;j<polyVec[i].size();++j)
00120 {
00121 Point2f pp=polyVec[i][j];
00122 pp.Rotate(trans.rotRad);
00123 bbox.Add(pp);
00124 }
00125 vcg::Point2f pos=bbox.Center();
00126 float scaleFact=(resolution/bbox.Diag());
00127
00129 painter.resetTransform();
00130 painter.translate(resolution/2,resolution/2);
00131 painter.rotate(math::ToDeg(trans.rotRad));
00132 painter.scale(scaleFact,scaleFact);
00133 painter.translate(-pos.V(0),-pos.V(1));
00134
00136 ret.rotRad=0;
00137 ret.sca=scaleFact;
00138 ret.tra[0]=-pos.V(0)*scaleFact + resolution/2;
00139 ret.tra[1]=-pos.V(1)*scaleFact + resolution/2;
00140
00142 QPainterPath QPP;
00143 for(size_t i=0;i<polyVec.size();++i)
00144 {
00145 QVector<QPointF> ppQ;
00146 for(size_t j=0;j<polyVec[i].size();++j)
00147 {
00148 Point2f pp=polyVec[i][j];
00149
00150 ppQ.push_back(QPointF(pp[0],pp[1]));
00151 }
00152 ppQ.push_back(QPointF(polyVec[i][0][0],polyVec[i][0][1]));
00153 QPP.addPolygon(QPolygonF(ppQ));
00154 }
00155
00156 painter.setBrush(bb);
00157 painter.setPen(qp);
00158 painter.drawPath(QPP);
00159 painter.end();
00160
00161 }
00162
00165 int Outline2Dumper::getMaxMaskRadius(int x,int y,QImage &img)
00166 {
00167 int sizeY=img.size().height();
00168 int sizeX=img.size().width();
00169 int Max_radiusX=std::min(abs(x-sizeX),x);
00170 int Max_radiusY=std::min(abs(y-sizeY),y);
00171 int Max_radius=std::min(Max_radiusX,Max_radiusY);
00172 int val=qGray(img.pixel(x,y));
00174 assert(val!=255);
00175
00176 int curr_radius=1;
00177 while (curr_radius<Max_radius)
00178 {
00179 vcg::Box2i currBB=vcg::Box2i(vcg::Point2i(x,y),vcg::Point2i(x,y));
00180 vcg::Box2i InsideBB=currBB;
00181 currBB.Offset(curr_radius);
00182 InsideBB.Offset(curr_radius-1);
00183
00185 for (int x0=currBB.min.X();x0<=currBB.max.X();x0++)
00186 for (int y0=currBB.min.Y();y0<=currBB.max.Y();y0++)
00187 {
00188 if (InsideBB.IsIn(vcg::Point2i(x0,y0)))continue;
00189 int val=qGray(img.pixel(x0,y0));
00191 if (val==255)
00192 return curr_radius;
00193 }
00194 curr_radius++;
00195 }
00196 return curr_radius;
00197 }
00198
00201 vcg::Point2f Outline2Dumper::GetIncenter(const vector< vector<Point2f> > &polyVec,
00202 const Similarity2f &tra1,
00203 float &radius,
00204 int resolution)
00205 {
00207 QImage img(resolution,resolution,QImage::Format_RGB32);
00208 img.fill(vcg::ColorConverter::ToQColor(vcg::Color4b::White));
00209 Similarity2f tra0;
00211 DrawPolygonMask(polyVec,img,tra0,tra1);
00212
00213
00215 float Maxradius=-1;
00216 int sizeY=img.size().height();
00217 int sizeX=img.size().width();
00218 vcg::Point2i incenter=vcg::Point2i(sizeX/2,sizeY/2);
00220 for (int x=0;x<sizeX;x++)
00221 for (int y=0;y<sizeY;y++)
00222 {
00225 int val=qGray(img.pixel(x,y));
00227 if (val==255)continue;
00228 int curr_radius=getMaxMaskRadius(x,y,img);
00229 if (curr_radius>Maxradius)
00230 {
00231 Maxradius=curr_radius;
00232 incenter=vcg::Point2i(x,y);
00233 }
00234 }
00235
00236 vcg::Point2f incenterf;
00237 incenterf.Import(incenter);
00238
00239
00240
00241
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 incenterf.X()-=tra0.tra[0];
00253 incenterf.Y()-=tra0.tra[1];
00254 incenterf*=1.0/tra0.sca;
00255 incenterf*=tra1.sca;
00256
00258 assert(Maxradius>0);
00259 radius=Maxradius;
00260 return incenterf;
00261 }
00262
00263
00267 void Outline2Dumper::dumpOutline2VecPNG(const char * imageName,
00268 vector< vector< vector<Point2f> > > &polyVecVec,
00269 vector<Similarity2f> &trVec,
00270 vector<string> &labelVec,
00271 Param &pp)
00272 {
00274 assert(polyVecVec.size() == trVec.size());
00275 int fontSize=ceil(std::max(pp.width,pp.height)/100.0);
00276 QFont qf("courier",fontSize);
00277
00279 QImage img(pp.width,pp.height,QImage::Format_RGB32);
00280 img.fill(vcg::ColorConverter::ToQColor( pp.backgroundColor).rgb());
00281
00283 QPainter painter;
00284 painter.begin(&img);
00285 QBrush bb;
00286 if (pp.fill)
00287 bb.setStyle(Qt::SolidPattern);
00288 QPen qp;
00289 qp.setWidthF(0);
00290
00291 for(size_t i=0;i<polyVecVec.size();++i)
00292 {
00294 painter.resetTransform();
00295 painter.translate(trVec[i].tra[0],trVec[i].tra[1]);
00296 painter.rotate(math::ToDeg(trVec[i].rotRad));
00297 painter.scale(trVec[i].sca,trVec[i].sca);
00298 QPainterPath QPP;
00299
00300 for(size_t jj=0;jj<polyVecVec[i].size();++jj)
00301 {
00302 QVector<QPointF> ppQ;
00303 for(size_t j=0;j<polyVecVec[i][jj].size();++j)
00304 {
00305 Point2f pp=polyVecVec[i][jj][j];
00306 ppQ.push_back(QPointF(pp[0],pp[1]));
00307 }
00308 ppQ.push_back(QPointF(polyVecVec[i][jj][0][0],polyVecVec[i][jj][0][1]));
00309 QPP.addPolygon(QPolygonF(ppQ));
00310 }
00311
00312 if (pp.randomColor)
00313 bb.setColor(vcg::ColorConverter::ToQColor(Color4b::Scatter(polyVecVec.size(),i)));
00314 else
00315 bb.setColor(vcg::ColorConverter::ToQColor(pp.FillColor));
00316
00317 painter.setBrush(bb);
00318 painter.setPen(qp);
00319 painter.drawPath(QPP);
00320 if(!labelVec.empty())
00321 {
00323 float radius;
00324 Point2f bc=GetIncenter(polyVecVec[i],trVec[i],radius,10);
00326 painter.setFont(qf);
00327 painter.resetTransform();
00328 painter.translate(trVec[i].tra[0],trVec[i].tra[1]);
00329 painter.drawText(bc[0]-radius,bc[1]-radius,radius*2,radius*2,Qt::AlignHCenter|Qt::AlignCenter,QString(labelVec[i].c_str()));
00330 }
00331 }
00332 painter.end();
00333 img.save(imageName);
00334 }
00335
00336
00340 void Outline2Dumper::dumpOutline2VecSVG(const char * imageName,
00341 vector< vector< vector<Point2f> > > &outline2VecVec,
00342 vector<Similarity2f> &trVec,
00343 vector< vector< string> > &labelVecVec,
00344 vector< vector<Similarity2f> > &labelTrVecVec,
00345 vector<vector<float> >&labelRadVecVec,
00346 Outline2Dumper::Param &pp)
00347 {
00348 assert(outline2VecVec.size() == trVec.size());
00349
00350
00352 int fontSize;
00353 if(pp.fontSize==0) fontSize=ceil(std::max(pp.width,pp.height)/200.0);
00354 else fontSize=pp.fontSize;
00355 QFont qf("courier",fontSize);
00356 QSvgGenerator svg;
00357 svg.setFileName(imageName);
00358
00360 svg.setSize(QSize(pp.width,pp.height));
00361 svg.setViewBox(QRect(0, 0, pp.width,pp.height));
00362 svg.setResolution(int(pp.dpi));
00363
00365 QPainter painter;
00366 painter.begin(&svg);
00367 QBrush bb;
00368 if (pp.fill)
00369 bb.setStyle(Qt::SolidPattern);
00370
00371 QPen qp;
00373 for(size_t i=0;i<outline2VecVec.size();++i)
00374 {
00375
00376 float scalingFactorforPenWidth=1.f/(float)trVec[i].sca;
00377 qp.setWidthF(pp.penWidth*scalingFactorforPenWidth);
00378 qp.setColor(vcg::ColorConverter::ToQColor(pp.lineColor));
00380 painter.resetTransform();
00381 painter.translate(trVec[i].tra[0],trVec[i].tra[1]);
00382 painter.rotate(math::ToDeg(trVec[i].rotRad));
00383 painter.scale(trVec[i].sca,trVec[i].sca);
00384 QPainterPath QPP;
00385
00386 for(size_t jj=0;jj<outline2VecVec[i].size();++jj)
00387 {
00388 QVector<QPointF> ppQ;
00389 for(size_t j=0;j<outline2VecVec[i][jj].size();++j)
00390 {
00391 Point2f pp=outline2VecVec[i][jj][j];
00392 ppQ.push_back(QPointF(pp[0],pp[1]));
00393 }
00394 ppQ.push_back(QPointF(outline2VecVec[i][jj][0][0],outline2VecVec[i][jj][0][1]));
00395 QPP.addPolygon(QPolygonF(ppQ));
00396 }
00398
00399 if (pp.randomColor)
00400 bb.setColor(vcg::ColorConverter::ToQColor(Color4b::Scatter(outline2VecVec.size(),i)));
00401 else
00402 bb.setColor(vcg::ColorConverter::ToQColor(pp.FillColor));
00403
00405 painter.setBrush(bb);
00406 painter.setPen(qp);
00407 painter.drawPath(QPP);
00408
00410 painter.setFont(qf);
00411 float radius;
00412
00413 Point2f bc;
00414
00415 if(labelTrVecVec.empty()) bc=GetIncenter(outline2VecVec[i],trVec[i],radius);
00416
00417 for(size_t labelInd=0;labelInd<labelVecVec[i].size();++labelInd)
00418 {
00419 if(!labelTrVecVec.empty())
00420 {
00421 bc = labelTrVecVec[i][labelInd].tra;
00422 bc.Rotate(trVec[i].rotRad);
00423 bc *= trVec[i].sca;
00424 radius=labelRadVecVec[i][labelInd];
00425 radius *= trVec[i].sca;
00426 }
00427 painter.resetTransform();
00428 painter.translate(trVec[i].tra[0],trVec[i].tra[1]);
00429 qp.setColor(vcg::ColorConverter::ToQColor(pp.labelColor));
00430 painter.setPen(qp);
00431 painter.drawText(bc[0]-radius,bc[1]-radius,radius*2,radius*2,Qt::AlignHCenter|Qt::AlignCenter,QString(labelVecVec[i][labelInd].c_str()));
00432 }
00433 }
00434 painter.end();
00435 }
00436
00437 void Outline2Dumper::dumpOutline2VecSVG(const char * imageName,
00438 vector< vector< vector<Point2f> > > &polyVecVec,
00439 vector<Similarity2f> &trVec,
00440 vector< string > &labelVec,
00441 Outline2Dumper::Param &pp)
00442 {
00443 vector< vector< string> > labelVecVec(labelVec.size());
00444 vector< vector<Similarity2f> > labelTrVec;
00445 vector< vector<float> >labelRadVec;
00446 for(size_t i=0;i<labelVec.size();++i)
00447 {
00448 labelVecVec[i].push_back(labelVec[i]);
00449 }
00450 dumpOutline2VecSVG(imageName,polyVecVec,trVec,labelVecVec,labelTrVec,labelRadVec,pp);
00451 }
00452