PARP Research Group University of Murcia, Spain


src/qvgui/qvimagecanvas.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008, 2009. 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 #include <qvmath.h>
00027 
00028 QVImageCanvas::QVImageCanvas(const QString name, QWidget *parent): QVCanvas(parent), QVPropertyContainer(name), _low(0.0), _high(255.0), colorCursor(0),
00029         contentLinkedWorkers(0)
00030         {
00031         qDebug() << "QVImageCanvas::QVImageCanvas()";
00032         if (qvApp == NULL)
00033                 {
00034                 QString str = "QVImageCanvas::QVImageCanvas(): the QVPlot cannot be created before the QVApplication instance. Aborting now.";
00035                 std::cerr << qPrintable(str) << std::endl;
00036                 exit(1);
00037                 }
00038         // if its a --help call, do nothing
00039         if (qvApp->forHelp()) return;
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         //setColor("rect select", Qt::
00051         addProperty< QVImage<uChar, 3> >("Content", outputFlag);
00052         show();
00053         };
00054 
00055 void QVImageCanvas::viewer()
00056         {
00057         qDebug() << "QVImageCanvas::viewer()";
00058         QMutexLocker locker(&qvApp->mutex);
00059 
00060         readInputProperties();
00061 
00062         // Draw images objects
00063         foreach(QString name, getPropertyList())
00064                 if (getPropertyFlags(name) & inputFlag)
00065                         {
00066                         // Draw <uChar,1> images
00067                         if (isType< QVImage<uChar,1> >(name)) {
00068                                 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<uChar,1> >(name);
00069                                 getQVPainter()->drawQVImage(&imageAux);
00070                                 }
00071                         // Draw <uChar,3> images
00072                         else if (isType< QVImage<uChar,3> >(name)) {
00073                                 QVImage<uChar,3> imageAux = getPropertyValue<QVImage<uChar,3> >(name);
00074                                 getQVPainter()->drawQVImage(&imageAux);
00075                                 }
00076                         // Draw <sFloat,1> images
00077                         else if (isType< QVImage<sFloat,1> >(name)) {
00078                                 QVImage<sFloat,1> imageAux = getPropertyValue<QVImage<sFloat,1> >(name);
00079                                 getQVPainter()->drawQVImage(&imageAux, TRUE, _low, _high);
00080                                 }
00081                         // Draw <sFloat,3> images
00082                         else if (isType< QVImage<sFloat,3> >(name)) {
00083                                 QVImage<sFloat,3> imageAux = getPropertyValue<QVImage<sFloat,3> >(name);
00084                                 getQVPainter()->drawQVImage(&imageAux, TRUE, _low, _high);
00085                                 }
00090                         // Draw <sShort,1> images
00091                         else if (isType< QVImage<uShort,1> >(name)) {
00092                                 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<uShort,1> >(name);
00093                                 getQVPainter()->drawQVImage(&imageAux);
00094                                 }
00095                         // Draw <sShort,3> images
00096                         else if (isType< QVImage<uShort,3> >(name)) {
00097                                 QVImage<uChar, 3> imageAux = getPropertyValue<QVImage<uShort,3> >(name);
00098                                 getQVPainter()->drawQVImage(&imageAux);
00099                                 }
00100                         // Draw <sShort,1> images
00101                         else if (isType< QVImage<sShort,1> >(name)) {
00102                                 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<sShort,1> >(name);
00103                                 getQVPainter()->drawQVImage(&imageAux);
00104                                 }
00105                         // Draw <sShort,3> images
00106                         else if (isType< QVImage<sShort,3> >(name)) {
00107                                 QVImage<uChar, 3> imageAux = getPropertyValue<QVImage<sShort,3> >(name);
00108                                 getQVPainter()->drawQVImage(&imageAux);
00109                                 }
00110                         // Draw <sInt,1> images
00111                         else if (isType< QVImage<sInt,1> >(name)) {
00112                                 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<sInt,1> >(name);
00113                                 getQVPainter()->drawQVImage(&imageAux);
00114                                 }
00115                         // Draw <sInt,3> images
00116                         else if (isType< QVImage<sInt,3> >(name)) {
00117                                 QVImage<uChar, 3> imageAux = getPropertyValue<QVImage<sInt,3> >(name);
00118                                 getQVPainter()->drawQVImage(&imageAux);
00119                                 }
00120                         }
00121 
00122         // Draw other objects
00123         foreach(QString name, getPropertyList())
00124                 if (getPropertyFlags(name) & inputFlag)
00125                         {
00126                         getQVPainter()->setBrush(QBrush(Qt::NoBrush));
00127 
00128                         // Draw points list.
00129                         if (isType< QList<QPoint> >(name))
00130                                 draw(   getPropertyValue< QList<QPoint> >(name),
00131                                         getPropertyValue<QColor>("Color for " + name),
00132                                         getPropertyValue<bool>("Print tags for " + name),
00133                                         getPropertyValue<int>("Radius for " + name)
00134                                         );
00135 
00136                         // Draw floating points list.
00137                         else if (isType< QList<QPointF> >(name))
00138                                 draw(   getPropertyValue< QList<QPointF> >(name),
00139                                         getPropertyValue<QColor>("Color for " + name),
00140                                         getPropertyValue<bool>("Print tags for " + name),
00141                                         getPropertyValue<int>("Radius for " + name)
00142                                         );
00143 
00144                         // Draw polylines.
00145                         else if (isType< QVPolyline >(name))
00146                                 draw(   getPropertyValue< QVPolyline >(name),
00147                                         getPropertyValue<QColor>("Color for " + name),
00148                                         getPropertyValue<bool>("Print tags for " + name)
00149                                         );
00150 
00151                         // Draw float polylines.
00152                         else if (isType< QVPolylineF >(name))
00153                                 draw(   getPropertyValue< QVPolylineF >(name),
00154                                         getPropertyValue<QColor>("Color for " + name),
00155                                         getPropertyValue<bool>("Print tags for " + name)
00156                                         );
00157 
00158                         // Draw rectangles.
00159                         else if (isType< QRect >(name))
00160                                 draw(   getPropertyValue< QRect >(name),
00161                                         getPropertyValue<QColor>("Color for " + name),
00162                                         getPropertyValue<bool>("Print tags for " + name)
00163                                         );
00164 
00165                         // Draw polyline list.
00166                         else if (isType< QList<QVPolyline> >(name))
00167                                 foreach(QVPolyline polyline, getPropertyValue< QList<QVPolyline> >(name))
00168                                         draw(   polyline,
00169                                                 getPropertyValue<QColor>("Color for " + name),
00170                                                 getPropertyValue<bool>("Print tags for " + name)
00171                                                 );
00172 
00173                         // Draw float polyline list.
00174                         else if (isType< QList<QVPolylineF> >(name))
00175                                 foreach(QVPolylineF polyline, getPropertyValue< QList<QVPolylineF> >(name))
00176                                         draw(   polyline,
00177                                                 getPropertyValue<QColor>("Color for " + name),
00178                                                 getPropertyValue<bool>("Print tags for " + name)
00179                                                 );
00180 
00181                         // Draw rectangles list.
00182                         else if (isType< QList<QRect> >(name))
00183                                 foreach(QRect rectangle, getPropertyValue< QList<QRect> >(name))
00184                                         draw(   rectangle,
00185                                                 getPropertyValue<QColor>("Color for " + name),
00186                                                 getPropertyValue<bool>("Print tags for " + name)
00187                                                 );
00188                         }
00189 
00190         custom_viewer();
00191 
00194         // If an image property was linked from a worker, render it to an QVImage property.
00195         if (contentLinkedWorkers > 0)
00196                 {
00197                 QVImage<uChar, 3> image = contentImage();
00198                 std::cout << "Linked Workers = " << contentLinkedWorkers << std::endl;
00199                 std::cout << "\t dims(ImageCanvas) = " << image.getCols() << "x" << image.getRows() << std::endl;
00200                 setPropertyValue< QVImage<uChar, 3> >("Content", image);
00201                 }
00202 
00203         writeOutputProperties();
00204 
00205         qDebug() << "QVImageCanvas::viewer() <~ return";
00206         }
00207 
00209 
00210 void QVImageCanvas::draw(const QList<QPoint> &pointList, QColor color, bool printTags, int radius)
00211         {
00212         const int diameter = 2*radius;
00213         getQVPainter()->setPen(color);
00214         getQVPainter()->setBrush(QBrush(color, Qt::SolidPattern));
00215 
00216         // Paint points with a circle.
00217         for (int i = 0; i< pointList.size(); i++)
00218                 {
00219                 const QPoint point = pointList.at(i);
00220                 if (printTags)
00221                         getQVPainter()->drawText(point + QPoint(2,-2), QString("%1").arg(i));
00222 
00223                 getQVPainter()->drawEllipse(point.x()-radius, point.y()-radius, diameter, diameter);
00224                 }
00225         }
00226 
00227 void QVImageCanvas::draw(const QList<QPointF> &pointList, QColor color, bool printTags, double radius)
00228         {
00229         const double diameter = 2*radius;
00230         getQVPainter()->setPen(Qt::black);
00231         getQVPainter()->setBrush(QBrush(color, Qt::SolidPattern));
00232 
00233         // Paint points with a circle.
00234         for (int i = 0; i< pointList.size(); i++)
00235                 {
00236                 const QPointF point = pointList.at(i);
00237                 if (printTags)
00238                         getQVPainter()->drawText(point+QPointF(2,-2), QString("%1").arg(i));
00239 
00240                 QRectF rect(point.x() - radius, point.y() - radius, diameter, diameter);
00241                 getQVPainter()->drawEllipse(rect);
00242                 }
00243         }
00244 
00246 void QVImageCanvas::draw(const QVPolyline &polyline, QColor color, bool /*printTags*/)
00247         {
00248         getQVPainter()->setPen(color);
00249 
00250         for (int i = polyline.size()-1; i>0; i--)
00251                 getQVPainter()->drawLine(polyline.at(i-1)+QPointF(0.5,0.5),polyline.at(i)+QPointF(0.5,0.5));
00252 
00253         if (polyline.closed)
00254                 getQVPainter()->drawLine(polyline.at(0) + QPointF(0.5,0.5), polyline.at(polyline.size() -1) + QPointF(0.5,0.5));
00255 
00256         //getQVPainter()->drawArc(QRect(polyline.at(0) + QPoint(0,0), polyline.at(0) + QPoint(1,1)), 0, 16*360);
00257         /*getQVPainter()->drawLine(last + QPointF(0.72500,   0.88971), last + QPointF(0.27500,   0.11029));
00258         getQVPainter()->drawLine(last + QPointF(0.88971,   0.72500), last + QPointF(0.11029,   0.27500));
00259         getQVPainter()->drawLine(last + QPointF(0.88971,   0.27500), last + QPointF(0.11029,   0.72500));
00260         getQVPainter()->drawLine(last + QPointF(0.72500,   0.11029), last + QPointF(0.27500,   0.88971));*/
00261         }
00262 
00263 void QVImageCanvas::draw(const QVPolylineF &polyline, QColor color, bool /*printTags*/)
00264         {
00265         getQVPainter()->setPen(color);
00266 
00267         // Draw line segments between each pair of adjacent points in the polyline.
00268         for (int i = polyline.size()-1; i>0; i--)
00269                 getQVPainter()->drawLine(polyline.at(i-1)+QPointF(0.5,0.5),polyline.at(i)+QPointF(0.5,0.5));
00270 
00271         if (polyline.closed)
00272                 getQVPainter()->drawLine(polyline.at(0) + QPointF(0.5,0.5), polyline.at(polyline.size() -1) + QPointF(0.5,0.5));
00273 
00274         //getQVPainter()->drawArc(QRect(polyline.at(0) + QPoint(0,0), polyline.at(0) + QPoint(1,1)), 0, 16*360);
00275         /*getQVPainter()->drawLine(last + QPointF(0.72500,   0.88971), last + QPointF(0.27500,   0.11029));
00276         getQVPainter()->drawLine(last + QPointF(0.88971,   0.72500), last + QPointF(0.11029,   0.27500));
00277         getQVPainter()->drawLine(last + QPointF(0.88971,   0.27500), last + QPointF(0.11029,   0.72500));
00278         getQVPainter()->drawLine(last + QPointF(0.72500,   0.11029), last + QPointF(0.27500,   0.88971));*/
00279         }
00280 
00281 void QVImageCanvas::draw(const QRect &rectangle, QColor color, bool /*printTags*/)
00282         {
00283         getQVPainter()->setPen(color);
00284 
00285         getQVPainter()->drawLine(rectangle.topLeft(), rectangle.topRight() );
00286         getQVPainter()->drawLine(rectangle.topLeft(), rectangle.bottomLeft() );
00287         getQVPainter()->drawLine(rectangle.bottomLeft(), rectangle.bottomRight() );
00288         getQVPainter()->drawLine(rectangle.topRight(), rectangle.bottomRight() );
00289         }
00290 
00291 void QVImageCanvas::unlink()
00292         {
00293         std::cerr << "ERROR: QVImageCanvas::linkProperty(): global unlink not implemented" << std::endl;
00294         }
00295 
00296 bool QVImageCanvas::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00297         {
00298         if (linkType == SynchronousLink) {
00299                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty(): the linkType must be AsynchronousLink, the link will not be done" << std::endl;
00300                 return false;
00301         }
00302 
00303         QVWorker* worker;
00304         if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00305                 {
00306                 addPropertyFromQVariant(sourcePropName, inputFlag, worker->getPropertyQVariantValue(sourcePropName), worker->getPropertyInfo(sourcePropName));
00307 
00308                 if (    worker->isType< QList<QPoint> >(sourcePropName)         ||
00309                         worker->isType< QList<QPointF> >(sourcePropName)        ||
00310                         worker->isType< QVPolyline >(sourcePropName)            ||
00311                         worker->isType< QVPolylineF >(sourcePropName)           ||
00312                         worker->isType< QRect >(sourcePropName)                 ||
00313                         worker->isType< QList<QVPolyline> >(sourcePropName)     ||
00314                         worker->isType< QList<QVPolylineF> >(sourcePropName)    ||
00315                         worker->isType< QList<QRect> >(sourcePropName)          )
00316                         {
00317                         std::cout << "Adding property of name " << qPrintable(sourcePropName) << " with default color " << colorCursor << std::endl;
00318                         addProperty<QColor>("Color for " + sourcePropName, inputFlag, getNextColor(), QString("Color for object ") + sourcePropName);
00319                         addProperty<bool>("Print tags for " + sourcePropName, inputFlag, false, QString("Print tags for object ") + sourcePropName);
00320                         if (    sourceContainer->isType< QList<QPointF> >(sourcePropName)||
00321                                 sourceContainer->isType< QList<QPoint> >(sourcePropName)        )
00322                                 addProperty<int>(       "Radius for " + sourcePropName, inputFlag, 3,
00323                                                         QString("Specify a radius for the points to be displayed.") + sourcePropName);
00324                         }
00325 
00326                 bool result = worker->linkProperty(sourcePropName, this, sourcePropName ,QVWorker::AsynchronousLink);
00327                 QObject::connect(worker, SIGNAL(endIteration(uint, int)), this, SLOT(refreshImageArea()));
00328                 return result;
00329                 }
00330         else
00331                 {
00332                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty(): the sourceContainer container must be a QVWorker, the link will not be done" << std::endl;
00333                 return false;
00334                 }
00335         }
00336 
00337 bool QVImageCanvas::linkUnspecifiedOutputProperty(QVPropertyContainer *destContainer, QString destPropName, LinkType linkType)
00338         {
00339         
00340         if (linkType == SynchronousLink)
00341                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): the linkType must be AsynchronousLink, the link will not be done." << std::endl;
00342         else if (dynamic_cast<QVWorker*>(destContainer) == NULL)
00343                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): destination block is not a worker." << std::endl;
00344         else  if (!destContainer->isType< QVImage<uChar, 3> >(destPropName))
00345                 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): destination property is not of type QVImage<uChar, 3>." << std::endl;
00346         else if (linkProperty("Content", destContainer, destPropName ,QVWorker::AsynchronousLink))
00347                 {
00348                 //std::cerr << "OK: QVImageCanvas::linkUnspecifiedOutputProperty(): linked image." << std::endl;
00349                 contentLinkedWorkers++;
00350                 return true;
00351                 }
00352 
00353         return false;
00354         }
00355 
00356 bool QVImageCanvas::treatUnlinkInputProperty(QString destPropName, QVPropertyContainer *sourceContainer, QString sourcePropName)
00357         {
00358         if ( (destPropName != "rect select") && (destPropName != "poly select") )
00359                 {
00360                 removeProperty(sourcePropName);
00361 
00362                 if (    sourceContainer->isType< QList<QPoint> >(sourcePropName)        ||
00363                         sourceContainer->isType< QList<QPointF> >(sourcePropName)       ||
00364                         sourceContainer->isType< QVPolyline >(sourcePropName)           ||
00365                         sourceContainer->isType< QVPolylineF >(sourcePropName)          ||
00366                         sourceContainer->isType< QRect >(sourcePropName)                ||
00367                         sourceContainer->isType< QList<QVPolyline> >(sourcePropName)    ||
00368                         sourceContainer->isType< QList<QVPolylineF> >(sourcePropName)   ||
00369                         sourceContainer->isType< QList<QRect> >(sourcePropName)         )
00370                         {
00371                         removeProperty("Color for " + sourcePropName);
00372                         removeProperty("Print tags for " + sourcePropName);
00373                         }
00374                 if (    sourceContainer->isType< QList<QPointF> >(sourcePropName)||
00375                         sourceContainer->isType< QList<QPoint> >(sourcePropName)        )
00376                         removeProperty("Radius for " + sourcePropName);
00377 
00378                 QVWorker* worker;
00379                 if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00380                         QObject::disconnect(worker, SIGNAL(endIteration(uint, int)), this, SLOT(refreshImageArea()));
00381                 }
00382         return true;
00383         }
00384 
00385 void QVImageCanvas::setSaturationRange(float low,float high)
00386         {
00387         _low = low;
00388         _high = high;
00389         }
00390 
00391 void QVImageCanvas::rectSelectedSlot(QRect rect)
00392         {
00393         setPropertyValue<QRect>("rect select", rect);
00394         writeOutputProperties();
00395         }
00396 
00399 void QVImageCanvas::circleSelectedSlot(QPoint center, float radius)
00400         {
00401         if (radius < 1)
00402                 setPropertyValue<QVPolyline>("poly select", QVPolyline());
00403         else
00404                 setPropertyValue<QVPolyline>("poly select", QVPolyline::ellipse(static_cast<uInt>(2*PI*radius), center.x(), center.y(), radius, radius, 0.0));
00405 
00406         setPropertyValue<TPolyMode>("Mode for selected polygon", CIRCLE);
00407         setPropertyValue<QPoint>("Center for selected polygon", center);
00408         setPropertyValue<float>("Radius for selected polygon", radius);
00409         writeOutputProperties();
00410         }
00411 
00412 void QVImageCanvas::polySelectedSlot(QPoint point, bool reset, TPolyMode mode)
00413         {
00414         if (reset)
00415                 setPropertyValue<QVPolyline>("poly select", QVPolyline());
00416         else
00417                 {
00418                 QVPolyline poly = getPropertyValue<QVPolyline>("poly select");
00419                 poly.append(point);
00420                 setPropertyValue<QVPolyline>("poly select", poly);
00421                 }
00422 
00423         setPropertyValue<TPolyMode>("Mode for selected polygon", mode);
00424         writeOutputProperties();
00425         }
00426 



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