PARP Research Group University of Murcia, Spain


src/qvgui/qvimagecanvas.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <QVImageCanvas>
00026 
00027 QVImageCanvas::QVImageCanvas(const QString name, QWidget *parent): QVCanvas(parent), QVPropertyContainer(name), _low(0.0), _high(255.0), colorCursor(0),        
00028         contentLinkedWorkers(0)
00029         {
00030         qDebug() << "QVImageCanvas::QVImageCanvas()";
00031         if (qvApp == NULL)
00032                 {
00033                 QString str = "QVImageCanvas::QVImageCanvas(): the QVPlot cannot be created before the QVApplication instance. Aborting now.";
00034                 std::cerr << qPrintable(str) << std::endl;
00035                 exit(1);
00036                 }
00037         // if its a --help call, do nothing
00038         if (qvApp->forHelp()) return;
00039 
00040 
00041         setWindowTitle("Image canvas for " + getName());
00042         addProperty<QRect>("rect select", outputFlag, QRect(), "Rectangule selected in it's image area");
00043         addProperty<QVPolyline>("poly select", outputFlag, QVPolyline(), "Poliline selected in it's image area");
00044         addProperty<QColor>("Color for selected polygon", outputFlag | internalProp, Qt::red, "Color for property poly select");        // to draw the polyline
00045         addProperty<bool>("Print tags for selected polygon", outputFlag | internalProp, false, "Print tag flag poly select");           //
00046         addProperty<TPolyMode>("Mode for selected polygon", outputFlag | internalProp, LINE, "Polyline select mode");                   //
00047         addProperty<QPoint>("Center for selected polygon", outputFlag | internalProp, QPoint(), "Polyline select center");              //
00048         addProperty<float>("Radius for selected polygon", outputFlag | internalProp, 0.0, "Polyline select radius");                    //
00049 
00050         addProperty< QVImage<uChar, 3> >("Content", outputFlag);
00051         show();
00052         };
00053 
00054 void QVImageCanvas::viewer()
00055         {
00056         qDebug() << "QVImageCanvas::viewer()";
00057 
00058         readInputProperties();
00059 
00060         // Draw other objects
00061         foreach(QString name, getPropertyList())
00062                 if (getPropertyFlags(name) & inputFlag)
00063                         {
00064                         // Draw <uChar,1> images
00065                         if (isType< QVImage<uChar,1> >(name))
00066                                 getQVPainter()->drawQVImage(&getPropertyValue<QVImage<uChar,1> >(name));
00067                         // Draw <uChar,3> images
00068                         else if (isType< QVImage<uChar,3> >(name))
00069                                 getQVPainter()->drawQVImage(&getPropertyValue<QVImage<uChar,3> >(name));
00070                         // Draw <sFloat,1> images
00071                         else if (isType< QVImage<sFloat,1> >(name))
00072                                 getQVPainter()->drawQVImage(&getPropertyValue<QVImage<sFloat,1> >(name), TRUE, _low, _high);
00073                         // Draw <sFloat,3> images
00074                         else if (isType< QVImage<sFloat,3> >(name))
00075                                 getQVPainter()->drawQVImage( &getPropertyValue<QVImage<sFloat,3> >(name), TRUE, _low, _high);
00080                         // Draw <sShort,1> images
00081                         else if (isType< QVImage<uShort,1> >(name))
00082                                 getQVPainter()->drawQVImage(&(QVImage<uChar, 1>)getPropertyValue<QVImage<uShort,1> >(name));
00083                         // Draw <sShort,3> images
00084                         else if (isType< QVImage<uShort,3> >(name))
00085                                 getQVPainter()->drawQVImage(&(QVImage<uChar, 1>)getPropertyValue<QVImage<uShort,3> >(name));
00086                         // Draw <sShort,1> images
00087                         else if (isType< QVImage<sShort,1> >(name))
00088                                 getQVPainter()->drawQVImage(&(QVImage<uChar, 1>)getPropertyValue<QVImage<sShort,1> >(name));
00089                         // Draw <sShort,3> images
00090                         else if (isType< QVImage<sShort,3> >(name))
00091                                 getQVPainter()->drawQVImage(&(QVImage<uChar, 1>)getPropertyValue<QVImage<sShort,3> >(name));
00092                         // Draw <sInt,1> images
00093                         else if (isType< QVImage<sInt,1> >(name))
00094                                 getQVPainter()->drawQVImage(&(QVImage<uChar, 1>)getPropertyValue<QVImage<sInt,1> >(name));
00095                         // Draw <sInt,3> images
00096                         else if (isType< QVImage<sInt,3> >(name))
00097                                 getQVPainter()->drawQVImage(&(QVImage<uChar, 3>)getPropertyValue<QVImage<sInt,3> >(name));
00098 
00099                         // Draw points list.
00100                         if (isType< QList<QPoint> >(name))
00101                                 draw(   getPropertyValue< QList<QPoint> >(name),
00102                                         getPropertyValue<QColor>("Color for " + name),
00103                                         getPropertyValue<bool>("Print tags for " + name),
00104                                         getPropertyValue<int>("Radius for points in " + name)
00105                                         );
00106 
00107                         // Draw floating points list.
00108                         else if (isType< QList<QPointF> >(name))
00109                                 draw(   getPropertyValue< QList<QPointF> >(name),
00110                                         getPropertyValue<QColor>("Color for " + name),
00111                                         getPropertyValue<bool>("Print tags for " + name),
00112                                         getPropertyValue<int>("Radius for points in " + name)
00113                                         );
00114 
00115                         // Draw polylines.
00116                         else if (isType< QVPolyline >(name))
00117                                 draw(   getPropertyValue< QVPolyline >(name),
00118                                         getPropertyValue<QColor>("Color for " + name),
00119                                         getPropertyValue<bool>("Print tags for " + name)
00120                                         );
00121 
00122                         // Draw float polylines.
00123                         else if (isType< QVPolylineF >(name))
00124                                 draw(   getPropertyValue< QVPolylineF >(name),
00125                                         getPropertyValue<QColor>("Color for " + name),
00126                                         getPropertyValue<bool>("Print tags for " + name)
00127                                         );
00128 
00129                         // Draw rectangles.
00130                         else if (isType< QRect >(name))
00131                                 draw(   getPropertyValue< QRect >(name),
00132                                         getPropertyValue<QColor>("Color for " + name),
00133                                         getPropertyValue<bool>("Print tags for " + name)
00134                                         );
00135 
00136                         // Draw polyline list.
00137                         else if (isType< QList<QVPolyline> >(name))
00138                                 foreach(QVPolyline polyline, getPropertyValue< QList<QVPolyline> >(name))
00139                                         draw(   polyline,
00140                                                 getPropertyValue<QColor>("Color for " + name),
00141                                                 getPropertyValue<bool>("Print tags for " + name)
00142                                                 );
00143 
00144                         // Draw float polyline list.
00145                         else if (isType< QList<QVPolylineF> >(name))
00146                                 foreach(QVPolylineF polyline, getPropertyValue< QList<QVPolylineF> >(name))
00147                                         draw(   polyline,
00148                                                 getPropertyValue<QColor>("Color for " + name),
00149                                                 getPropertyValue<bool>("Print tags for " + name)
00150                                                 );
00151 
00152                         // Draw rectangles list.
00153                         else if (isType< QList<QRect> >(name))
00154                                 foreach(QRect rectangle, getPropertyValue< QList<QRect> >(name))
00155                                         draw(   rectangle,
00156                                                 getPropertyValue<QColor>("Color for " + name),
00157                                                 getPropertyValue<bool>("Print tags for " + name)
00158                                                 );
00159                         }
00160 
00161         custom_viewer();
00162 
00165         // If an image property was linked from a worker, render it to an QVImage property.
00166         if (contentLinkedWorkers > 0)
00167                 {
00168                 QVImage<uChar, 3> image = contentImage();
00169                 std::cout << "Linked Workers = " << contentLinkedWorkers << std::endl;
00170                 std::cout << "\t dims(ImageCanvas) = " << image.getCols() << "x" << image.getRows() << std::endl;
00171                 setPropertyValue< QVImage<uChar, 3> >("Content", image);
00172                 }
00173 
00174         writeOutputProperties();
00175 
00176         qDebug() << "QVImageCanvas::viewer() <~ return";
00177         }
00178 
00180 
00181 void QVImageCanvas::draw(const QList<QPoint> &pointList, QColor color, bool printTags, int radius)
00182         {
00183         const int diameter = 2*radius;
00184         getQVPainter()->setPen(color);
00185         getQVPainter()->setBrush(QBrush(color, Qt::SolidPattern));
00186 
00187         // Paint points with a circle.
00188         for (int i = 0; i< pointList.size(); i++)
00189                 {
00190                 const QPoint point = pointList.at(i);
00191                 if (printTags)
00192                         getQVPainter()->drawText(point + QPoint(2,-2), QString("%1").arg(i));
00193 
00194                 getQVPainter()->drawEllipse(point.x()-radius, point.y()-radius, diameter, diameter);
00195                 }
00196         }
00197 
00198 void QVImageCanvas::draw(const QList<QPointF> &pointList, QColor color, bool printTags, int radius)
00199         {
00200         const int diameter = 2*radius;
00201         getQVPainter()->setPen(Qt::black);
00202         getQVPainter()->setBrush(QBrush(color, Qt::SolidPattern));
00203 
00204         // Paint points with a circle.
00205         for (int i = 0; i< pointList.size(); i++)
00206                 {
00207                 const QPointF point = pointList.at(i);
00208                 if (printTags)
00209                         getQVPainter()->drawText(point+QPointF(2,-2), QString("%1").arg(i));
00210 
00211                 getQVPainter()->drawEllipse(point.x()-radius, point.y()-radius, diameter, diameter);
00212                 }
00213         }
00214 
00216 void QVImageCanvas::draw(const QVPolyline &polyline, QColor color, bool printTags)
00217         {
00218         getQVPainter()->setPen(color);
00219 
00220         // Draw line segments between each pair of adjacent points in the polyline.
00221         for (int i = polyline.size()-1; i>0; i--)
00222                 getQVPainter()->drawLine(polyline.at(i-1)+QPointF(0.5,0.5),polyline.at(i)+QPointF(0.5,0.5));
00223 
00224         if (polyline.closed)
00225                 getQVPainter()->drawLine(polyline.at(0) + QPointF(0.5,0.5), polyline.at(polyline.size() -1) + QPointF(0.5,0.5));
00226 
00227         //getQVPainter()->drawArc(QRect(polyline.at(0) + QPoint(0,0), polyline.at(0) + QPoint(1,1)), 0, 16*360);
00228         /*getQVPainter()->drawLine(last + QPointF(0.72500,   0.88971), last + QPointF(0.27500,   0.11029));
00229         getQVPainter()->drawLine(last + QPointF(0.88971,   0.72500), last + QPointF(0.11029,   0.27500));
00230         getQVPainter()->drawLine(last + QPointF(0.88971,   0.27500), last + QPointF(0.11029,   0.72500));
00231         getQVPainter()->drawLine(last + QPointF(0.72500,   0.11029), last + QPointF(0.27500,   0.88971));*/
00232         }
00233 
00234 void QVImageCanvas::draw(const QVPolylineF &polyline, QColor color, bool printTags)
00235         {
00236         getQVPainter()->setPen(color);
00237 
00238         // Draw line segments between each pair of adjacent points in the polyline.
00239         for (int i = polyline.size()-1; i>0; i--)
00240                 getQVPainter()->drawLine(polyline.at(i-1)+QPointF(0.5,0.5),polyline.at(i)+QPointF(0.5,0.5));
00241 
00242         if (polyline.closed)
00243                 getQVPainter()->drawLine(polyline.at(0) + QPointF(0.5,0.5), polyline.at(polyline.size() -1) + QPointF(0.5,0.5));
00244 
00245         //getQVPainter()->drawArc(QRect(polyline.at(0) + QPoint(0,0), polyline.at(0) + QPoint(1,1)), 0, 16*360);
00246         /*getQVPainter()->drawLine(last + QPointF(0.72500,   0.88971), last + QPointF(0.27500,   0.11029));
00247         getQVPainter()->drawLine(last + QPointF(0.88971,   0.72500), last + QPointF(0.11029,   0.27500));
00248         getQVPainter()->drawLine(last + QPointF(0.88971,   0.27500), last + QPointF(0.11029,   0.72500));
00249         getQVPainter()->drawLine(last + QPointF(0.72500,   0.11029), last + QPointF(0.27500,   0.88971));*/
00250         }
00251 
00252 void QVImageCanvas::draw(const QRect &rectangle, QColor color, bool printTags)
00253         {
00254         getQVPainter()->setPen(color);
00255 
00256         getQVPainter()->drawLine(rectangle.topLeft(), rectangle.topRight() );
00257         getQVPainter()->drawLine(rectangle.topLeft(), rectangle.bottomLeft() );
00258         getQVPainter()->drawLine(rectangle.bottomLeft(), rectangle.bottomRight() );
00259         getQVPainter()->drawLine(rectangle.topRight(), rectangle.bottomRight() );
00260         }
00261 
00262 void QVImageCanvas::unlink()
00263         {
00264         std::cerr << "ERROR: QVImageCanvas::linkProperty(): global unlink not implemented" << std::endl;
00265         }
00266 
00267 bool QVImageCanvas::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00268         {
00269         if (linkType == SynchronousLink) {
00270                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty(): the linkType must be AsynchronousLink, the link will not be done" << std::endl;
00271                 return false;
00272         }
00273 
00274         QVWorker* worker;
00275         if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00276                 {
00277                 addPropertyFromQVariant(sourcePropName, inputFlag, worker->getPropertyQVariantValue(sourcePropName), worker->getPropertyInfo(sourcePropName));
00278 
00279                 if (    worker->isType< QList<QPoint> >(sourcePropName)         ||
00280                         worker->isType< QList<QPointF> >(sourcePropName)        ||
00281                         worker->isType< QVPolyline >(sourcePropName)            ||
00282                         worker->isType< QVPolylineF >(sourcePropName)           ||
00283                         worker->isType< QRect >(sourcePropName)                 ||
00284                         worker->isType< QList<QVPolyline> >(sourcePropName)     ||
00285                         worker->isType< QList<QVPolylineF> >(sourcePropName)    ||
00286                         worker->isType< QList<QRect> >(sourcePropName)          )
00287                         {
00288                         std::cout << "Adding property of name " << qPrintable(sourcePropName) << " with default color " << colorCursor << std::endl;
00289                         addProperty<QColor>("Color for " + sourcePropName, inputFlag, getNextColor(), QString("Color for object ") + sourcePropName);
00290                         addProperty<bool>("Print tags for " + sourcePropName, inputFlag, false, QString("Print tags for object ") + sourcePropName);
00291                         if (    sourceContainer->isType< QList<QPointF> >(sourcePropName)||
00292                                 sourceContainer->isType< QList<QPoint> >(sourcePropName)        )
00293                                 addProperty<int>(       "Radius for points in " + sourcePropName, inputFlag, 3,
00294                                                         QString("Specify a radius for the points to be displayed.") + sourcePropName);
00295                         }
00296 
00297                 bool result = worker->linkProperty(sourcePropName, this, sourcePropName ,QVWorker::AsynchronousLink);
00298                 QObject::connect(worker, SIGNAL(endIteration(uint, int)), this, SLOT(refreshImageArea()));
00299                 return result;
00300                 }
00301         else
00302                 {
00303                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty(): the sourceContainer container must be a QVWorker, the link will not be done" << std::endl;
00304                 return false;
00305                 }
00306         }
00307 
00308 bool QVImageCanvas::linkUnspecifiedOutputProperty(QVPropertyContainer *destContainer, QString destPropName, LinkType linkType)
00309         {
00310         
00311         if (linkType == SynchronousLink)
00312                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): the linkType must be AsynchronousLink, the link will not be done." << std::endl;
00313         else if (dynamic_cast<QVWorker*>(destContainer) == NULL)
00314                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): destination block is not a worker." << std::endl;
00315         else  if (!destContainer->isType< QVImage<uChar, 3> >(destPropName))
00316                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): destination property is not of type QVImage<uChar, 3>." << std::endl;
00317         else if (linkProperty("Content", destContainer, destPropName ,QVWorker::AsynchronousLink))
00318                 {
00319                 //std::cerr << "OK: QVImageCanvas::linkUnspecifiedOutputProperty(): linked image." << std::endl;
00320                 contentLinkedWorkers++;
00321                 return true;
00322                 }
00323 
00324         return false;
00325         }
00326 
00327 bool QVImageCanvas::treatUnlinkInputProperty(QString destPropName, QVPropertyContainer *sourceContainer, QString sourcePropName)
00328         {
00329         if ( (destPropName != "rect select") && (destPropName != "poly select") )
00330                 {
00331                 removeProperty(sourcePropName);
00332 
00333                 if (    sourceContainer->isType< QList<QPoint> >(sourcePropName)        ||
00334                         sourceContainer->isType< QList<QPointF> >(sourcePropName)       ||
00335                         sourceContainer->isType< QVPolyline >(sourcePropName)           ||
00336                         sourceContainer->isType< QVPolylineF >(sourcePropName)          ||
00337                         sourceContainer->isType< QRect >(sourcePropName)                ||
00338                         sourceContainer->isType< QList<QVPolyline> >(sourcePropName)    ||
00339                         sourceContainer->isType< QList<QVPolylineF> >(sourcePropName)   ||
00340                         sourceContainer->isType< QList<QRect> >(sourcePropName)         )
00341                         {
00342                         removeProperty("Color for " + sourcePropName);
00343                         removeProperty("Print tags for " + sourcePropName);
00344                         }
00345                 if (    sourceContainer->isType< QList<QPointF> >(sourcePropName)||
00346                         sourceContainer->isType< QList<QPoint> >(sourcePropName)        )
00347                         removeProperty("Radius for points in " + sourcePropName);
00348 
00349                 QVWorker* worker;
00350                 if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00351                         QObject::disconnect(worker, SIGNAL(endIteration(uint, int)), this, SLOT(refreshImageArea()));
00352                 }
00353         return true;
00354         }
00355 
00356 void QVImageCanvas::setLowHigh(float low,float high)
00357         {
00358         _low = low;
00359         _high = high;
00360         }
00361 
00362 void QVImageCanvas::rectSelectedSlot(QRect rect)
00363         {
00364         setPropertyValue<QRect>("rect select", rect);
00365         writeOutputProperties();
00366         }
00367 
00370 void QVImageCanvas::circleSelectedSlot(QPoint center, float radius)
00371         {
00372         if (radius < 1)
00373                 setPropertyValue<QVPolyline>("poly select", QVPolyline());
00374         else
00375                 setPropertyValue<QVPolyline>("poly select", QVPolyline::ellipse(static_cast<uInt>(2*PI*radius), center.x(), center.y(), radius, radius, 0.0));
00376 
00377         setPropertyValue<TPolyMode>("Mode for selected polygon", CIRCLE);
00378         setPropertyValue<QPoint>("Center for selected polygon", center);
00379         setPropertyValue<float>("Radius for selected polygon", radius);
00380         writeOutputProperties();
00381         }
00382 
00383 void QVImageCanvas::polySelectedSlot(QPoint point, bool reset, TPolyMode mode)
00384         {
00385         if (reset)
00386                 setPropertyValue<QVPolyline>("poly select", QVPolyline());
00387         else
00388                 {
00389                 QVPolyline poly = getPropertyValue<QVPolyline>("poly select");
00390                 poly.append(point);
00391                 setPropertyValue<QVPolyline>("poly select", poly);
00392                 }
00393 
00394         setPropertyValue<TPolyMode>("Mode for selected polygon", mode);
00395         writeOutputProperties();
00396         }
00397 



QVision framework. PARP research group, copyright 2007, 2008.