00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 contentLinkedBlocks(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
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<QVPolylineF>("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");
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
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
00063 foreach(QString name, getPropertyList())
00064 if (getPropertyFlags(name) & inputFlag)
00065 {
00066
00067 if (isType< QVImage<uChar,1> >(name)) {
00068 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<uChar,1> >(name);
00069 getQVPainter()->drawQVImage(&imageAux);
00070 }
00071
00072 else if (isType< QVImage<uChar,3> >(name)) {
00073 QVImage<uChar,3> imageAux = getPropertyValue<QVImage<uChar,3> >(name);
00074 getQVPainter()->drawQVImage(&imageAux);
00075 }
00076
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
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
00091 else if (isType< QVImage<uShort,1> >(name)) {
00092 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<uShort,1> >(name);
00093 getQVPainter()->drawQVImage(&imageAux);
00094 }
00095
00096 else if (isType< QVImage<uShort,3> >(name)) {
00097 QVImage<uChar, 3> imageAux = getPropertyValue<QVImage<uShort,3> >(name);
00098 getQVPainter()->drawQVImage(&imageAux);
00099 }
00100
00101 else if (isType< QVImage<sShort,1> >(name)) {
00102 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<sShort,1> >(name);
00103 getQVPainter()->drawQVImage(&imageAux);
00104 }
00105
00106 else if (isType< QVImage<sShort,3> >(name)) {
00107 QVImage<uChar, 3> imageAux = getPropertyValue<QVImage<sShort,3> >(name);
00108 getQVPainter()->drawQVImage(&imageAux);
00109 }
00110
00111 else if (isType< QVImage<sInt,1> >(name)) {
00112 QVImage<uChar, 1> imageAux = getPropertyValue<QVImage<sInt,1> >(name);
00113 getQVPainter()->drawQVImage(&imageAux);
00114 }
00115
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
00123 foreach(QString name, getPropertyList())
00124 if (getPropertyFlags(name) & inputFlag)
00125 {
00126 getQVPainter()->setBrush(QBrush(Qt::NoBrush));
00127
00128
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
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
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
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
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
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
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
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
00195 if (contentLinkedBlocks > 0)
00196 {
00197 QVImage<uChar, 3> image = contentImage();
00198 std::cout << "Linked Blocks = " << contentLinkedBlocks << 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
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
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 )
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
00257
00258
00259
00260
00261 }
00262
00263 void QVImageCanvas::draw(const QVPolylineF &polyline, QColor color, bool )
00264 {
00265 getQVPainter()->setPen(color);
00266
00267
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
00275
00276
00277
00278
00279 }
00280
00281 void QVImageCanvas::draw(const QRect &rectangle, QColor color, bool )
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 QVProcessingBlock* block;
00304 if((block = dynamic_cast<QVProcessingBlock*>(sourceContainer)) != NULL)
00305 {
00306 addPropertyFromQVariant(sourcePropName, inputFlag, block->getPropertyQVariantValue(sourcePropName), block->getPropertyInfo(sourcePropName));
00307
00308 if ( block->isType< QList<QPoint> >(sourcePropName) ||
00309 block->isType< QList<QPointF> >(sourcePropName) ||
00310 block->isType< QVPolyline >(sourcePropName) ||
00311 block->isType< QVPolylineF >(sourcePropName) ||
00312 block->isType< QRect >(sourcePropName) ||
00313 block->isType< QList<QVPolyline> >(sourcePropName) ||
00314 block->isType< QList<QVPolylineF> >(sourcePropName) ||
00315 block->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 = block->linkProperty(sourcePropName, this, sourcePropName ,QVProcessingBlock::AsynchronousLink);
00327 QObject::connect(block, 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 QVProcessingBlock, 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<QVProcessingBlock*>(destContainer) == NULL)
00343 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedOutputProperty(): destination block is not a block." << 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 ,QVProcessingBlock::AsynchronousLink))
00347 {
00348
00349 contentLinkedBlocks++;
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 QVProcessingBlock* block;
00379 if((block = dynamic_cast<QVProcessingBlock*>(sourceContainer)) != NULL)
00380 QObject::disconnect(block, 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<QVPolylineF>("poly select", QVPolyline());
00403 else
00404 setPropertyValue<QVPolylineF>("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<QVPolylineF>("poly select", QVPolyline());
00416 else
00417 {
00418 QVPolyline poly = getPropertyValue<QVPolylineF>("poly select");
00419 poly.append(point);
00420 setPropertyValue<QVPolylineF>("poly select", poly);
00421 }
00422
00423 setPropertyValue<TPolyMode>("Mode for selected polygon", mode);
00424 writeOutputProperties();
00425 }
00426