PARP Research Group University of Murcia, Spain


src/qvcore/qvimage.h

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 #ifndef QVIMAGE_H
00026 #define QVIMAGE_H
00027 
00028 #include <QMetaType>
00029 #include <qvcore/qvimagebuffer.h>
00030 #include <QVGenericImage>
00031 #include <QImage>
00032 
00033 #ifdef OPENCV
00034 #include <cv.h>
00035 #endif
00036 
00046 #define QVIMAGE_INIT_READ(TYPE, IMAGE)                                          \
00047         const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData();               \
00048         const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE);        \
00049         const uChar __qv_planes_##IMAGE##__  = IMAGE.getChannels();             \
00050         const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE.getCols(); \
00051         Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00052 
00062 #define QVIMAGE_INIT_WRITE(TYPE, IMAGE)                                         \
00063         TYPE * __qv_data_##IMAGE##__ = IMAGE.getWriteData();                    \
00064         const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE);        \
00065         const uChar __qv_planes_##IMAGE##__  = IMAGE.getChannels();             \
00066         const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE.getCols(); \
00067         Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00068 
00078 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE)                                      \
00079         const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData();              \
00080         const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE);       \
00081         const uChar __qv_planes_##IMAGE##__  = IMAGE->getChannels();            \
00082         const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE->getCols(); \
00083         Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00084 
00094 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE)                                                                             \
00095         TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData();                                                           \
00096         const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE);                                               \
00097         const uChar __qv_planes_##IMAGE##__  = IMAGE->getChannels();                                                    \
00098         const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - __qv_planes_##IMAGE##__ * IMAGE->getCols(); \
00099         Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00100 
00110 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00111         (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00112 
00122 #define QVIMAGE_PIXEL_PTR(IMAGE, Col, Row, Channel)     \
00123         (& (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)]))
00124 
00131 #define QVIMAGE_ROW_INCREMENT_PTR(IMAGE)        ( __qv_step_##IMAGE##__ )
00132 
00140 #define QVIMAGE_COL_INCREMENT_PTR(IMAGE)        ( __qv_planes_##IMAGE##__ )
00141 
00148 #define QVIMAGE_NEXT_LINE_INCREMENT_PTR(IMAGE)  ( __qv_next_line_inc_##IMAGE##__ )
00149 
00160 #include <stdio.h>
00161 #include <stdlib.h>
00162 #include <iostream>
00163 
00164 template <typename Type, int Channels = 1> class QVImage: public QVGenericImage 
00165         {
00166         protected:
00167                 uInt step_div_type_size;
00168                 QSharedDataPointer< QVImageBuffer<Type,Channels> > imageBuffer;
00169 
00170         public:
00176                 QVImage():QVGenericImage()
00177                         {
00178                         this->imageBuffer = new QVImageBuffer<Type, Channels>(1, 1);
00179                         setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00180                         setAnchor(0,0);
00181                         this->step_div_type_size = getStep()/sizeof(Type);
00182                         }
00183 
00220                 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00221                         {
00222                         this->imageBuffer = new QVImageBuffer<Type, Channels>(cols, rows, step, buffer);
00223                         setROI(0,0, cols, rows);
00224                         setAnchor(0,0);
00225                         this->step_div_type_size = getStep()/sizeof(Type);
00226                         }
00227 
00244                 QVImage(QVImage<uChar,1> const &img);
00245 
00247                 QVImage(QVImage<uChar,3> const &img);
00248 
00250                 QVImage(QVImage<uShort,1> const &img);
00251 
00253                 QVImage(QVImage<uShort,3> const &img);
00254 
00256                 QVImage(QVImage<sShort,1> const &img);
00257 
00259                 QVImage(QVImage<sShort,3> const &img);
00260 
00262                 QVImage(QVImage<sInt,1> const &img);
00263 
00265                 QVImage(QVImage<sInt,3> const &img);
00266 
00268                 QVImage(QVImage<sFloat,1> const &img);
00269 
00271                 QVImage(QVImage<sFloat,3> const &img);
00272 
00274                 QVImage(const QString &filename)
00275                         {
00276                         QImage qimg;
00277                         qimg.load(filename);
00278                         *this = QVImage<uChar, 3>(qimg);
00279                         };
00280 
00290                 QVImage(QVImage<uChar,1> const &red, QVImage<uChar,1> const &green, QVImage<uChar,1> const &blue);
00291 
00293                 QVImage(QVImage<uShort,1> const &red, QVImage<uShort,1> const &green, QVImage<uShort,1> const &blue);
00294 
00296                 QVImage(QVImage<sShort,1> const &red, QVImage<sShort,1> const &green, QVImage<sShort,1> const &blue);
00297 
00299                 QVImage(QVImage<sInt,1> const &red, QVImage<sInt,1> const &green, QVImage<sInt,1> const &blue);
00300 
00302                 QVImage(QVImage<sFloat,1> const &red, QVImage<sFloat,1> const &green, QVImage<sFloat,1> const &blue);
00303 
00304                 // Convert operators for QImage
00306                 QVImage(const QImage &qImage);
00307 
00309                 operator QImage() const;
00310 
00311                 // Convert operators for IplImage
00312                 #ifdef OPENCV
00320                 QVImage(const IplImage *iplImage);
00321 
00328                 operator IplImage *() const;
00329                 #endif
00330 
00331                 // Misc data.
00333                 const char * getTypeQString() const;
00334 
00336                 uInt getRows()          const   { return imageBuffer->getRows(); }
00337 
00339                 uInt getCols()          const   { return imageBuffer->getCols(); }
00340 
00342                 inline uInt getStep()   const   { return imageBuffer->getStep(); }
00343 
00345                 inline uInt getChannels()       const   { return imageBuffer->getChannels(); }
00346 
00348                 uInt getDataSize()      const   { return imageBuffer->getDataSize(); }
00349 
00351                 uInt getTypeSize()      const   { return imageBuffer->getTypeSize(); }
00352 
00363                 const Type * getReadData()      const   { return imageBuffer->getReadData(); }
00364 
00375                 Type * getWriteData()           { return imageBuffer->getWriteData(); }
00376 
00391                 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00392 
00393 
00400                 void resize(const int cols, const int rows)
00401                         {
00402                         if (((int)getCols()) >= cols && ((int)getRows()) >= rows)
00403                                 return;
00404 
00405                         QVImage<Type, Channels> temp(MAX(cols, (int)getCols()), MAX(rows, (int)getRows()));
00406                         Copy(*this, temp);
00407 
00408                         *this = temp;
00409                         }
00410 
00419                 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00420                         {
00421                         Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00422                         Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00423                         Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00424                         const int idx = step_div_type_size*row + Channels*col + channel;
00425                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00426                         Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00427 
00428                         return imageBuffer->getWriteData()[idx];
00429                         }
00430 
00431                 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00432                         {
00433                         Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00434                         Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00435                         Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00436                         const int idx = step_div_type_size*row + Channels*col + channel;
00437                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00438                         Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00439 
00440                         return imageBuffer->getReadData()[idx];
00441                         }
00442 
00449                 inline Type &operator()(const QPoint point, const uInt channel = 0)
00450                         {
00451                         Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00452                         Q_ASSERT_X(point.x() < getCols(),"QVImage::operator()","col further upper bound");
00453                         Q_ASSERT_X(point.y() < getRows(),"QVImage::operator()","row further upper bound");
00454                         const int idx = step_div_type_size*point.y() + Channels*point.x() + channel;
00455                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00456                         Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00457 
00458                         return imageBuffer->getWriteData()[idx];
00459                         }
00460 
00461                 inline Type operator()(const QPoint point, const uInt channel = 0) const
00462                         {
00463                         Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00464                         Q_ASSERT_X(point.x() < getCols(),"QVImage::operator()","col further upper bound");
00465                         Q_ASSERT_X(point.y() < getRows(),"QVImage::operator()","row further upper bound");
00466                         const int idx = step_div_type_size*point.y() + Channels*point.x() + channel;
00467                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00468                         Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00469 
00470                         return imageBuffer->getReadData()[idx];
00471                         }
00472 
00481                 QVImage<Type, 1> operator()(const uInt channel = 0) const;
00482 
00499                 QVImage<Type, Channels> & operator=(const QVImage<uChar, 1> &sourceImage);
00500 
00502                 QVImage<Type, Channels> & operator=(const QVImage<uChar, 3> &sourceImage);
00503 
00505                 QVImage<Type, Channels> & operator=(const QVImage<uShort, 1> &sourceImage);
00506 
00508                 QVImage<Type, Channels> & operator=(const QVImage<uShort, 3> &sourceImage);
00509 
00511                 QVImage<Type, Channels> & operator=(const QVImage<sShort, 1> &sourceImage);
00512 
00514                 QVImage<Type, Channels> & operator=(const QVImage<sShort, 3> &sourceImage);
00515 
00517                 QVImage<Type, Channels> & operator=(const QVImage<sInt, 1> &sourceImage);
00518 
00520                 QVImage<Type, Channels> & operator=(const QVImage<sInt, 3> &sourceImage);
00521 
00523                 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 1> &sourceImage);
00524 
00526                 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 3> &sourceImage);
00527 
00538                 bool operator==(const QVImage<Type, Channels> &img) const;
00539 
00553                 bool operator!=(const QVImage<Type, Channels> &img) const { return !(*this == img); }
00554 
00560                 QVImage<uChar, 1> operator<(const QVImage<uChar, Channels> &img) const;
00561 
00567                 QVImage<uChar, 1> operator<(const QVImage<uShort, Channels> &img) const;
00568 
00574                 QVImage<uChar, 1> operator<(const QVImage<sShort, Channels> &img) const;
00575 
00581                 QVImage<uChar, 1> operator<(const QVImage<sInt, Channels> &img) const;
00582 
00588                 QVImage<uChar, 1> operator<(const QVImage<sFloat, Channels> &img) const;
00589 
00595                 QVImage<uChar, 1> operator>(const QVImage<uChar, Channels> &img) const;
00596 
00602                 QVImage<uChar, 1> operator>(const QVImage<uShort, Channels> &img) const;
00603 
00609                 QVImage<uChar, 1> operator>(const QVImage<sShort, Channels> &img) const;
00610 
00616                 QVImage<uChar, 1> operator>(const QVImage<sInt, Channels> &img) const;
00617 
00623                 QVImage<uChar, 1> operator>(const QVImage<sFloat, Channels> &img) const;
00624 
00630                 QVImage<uChar, 1> operator<=(const QVImage<uChar, Channels> &img) const;
00631 
00637                 QVImage<uChar, 1> operator<=(const QVImage<uShort, Channels> &img) const;
00638 
00644                 QVImage<uChar, 1> operator<=(const QVImage<sShort, Channels> &img) const;
00645 
00651                 QVImage<uChar, 1> operator<=(const QVImage<sInt, Channels> &img) const;
00652 
00658                 QVImage<uChar, 1> operator<=(const QVImage<sFloat, Channels> &img) const;
00659 
00665                 QVImage<uChar, 1> operator>=(const QVImage<uChar, Channels> &img) const;
00666 
00672                 QVImage<uChar, 1> operator>=(const QVImage<uShort, Channels> &img) const;
00673 
00679                 QVImage<uChar, 1> operator>=(const QVImage<sShort, Channels> &img) const;
00680 
00686                 QVImage<uChar, 1> operator>=(const QVImage<sInt, Channels> &img) const;
00687 
00693                 QVImage<uChar, 1> operator>=(const QVImage<sFloat, Channels> &img) const;
00694 
00704                 QVImage<Type, Channels> operator+(const Type constant) const;
00705 
00715                 QVImage<Type, Channels> operator*(const Type constant) const;
00716 
00726                 QVImage<Type, Channels> operator-(const Type constant) const;
00727 
00737                 QVImage<Type, Channels> operator/(const Type constant) const;
00738 
00748                 QVImage<Type, Channels> operator<<(const Type constant) const;
00749 
00759                 QVImage<Type, Channels> operator>>(const Type constant) const;
00760 
00766                 QVImage<Type, Channels> operator!() const;
00767 
00774                 QVImage<Type, Channels> operator&(const Type constant) const;
00775 
00782                 QVImage<Type, Channels> operator|(const Type constant) const;
00783 
00790                 QVImage<Type, Channels> operator^(const Type constant) const;
00791 
00799                 QVImage<Type, Channels> operator+(const QVImage<Type, Channels> &img) const;
00800 
00808                 QVImage<Type, Channels> operator*(const QVImage<Type, Channels> &img) const;
00809 
00817                 QVImage<Type, Channels> operator-(const QVImage<Type, Channels> &img) const;
00818 
00826                 QVImage<Type, Channels> operator/(const QVImage<Type, Channels> &img) const;
00827         };
00828 
00829 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
00830         {
00831         Q_ASSERT_X(img.getChannels() == this->getChannels(), "QVImage::operator==", "different number of planes");
00832         if (this->getCols() != img.getCols()) return false;
00833         if (this->getRows() != img.getRows()) return false;
00834         if (this->getChannels() != img.getChannels()) return false;
00835         if (this->getROI() != img.getROI()) return false;
00836         QVIMAGE_INIT_READ(Type,img);
00837         QVIMAGE_PTR_INIT_READ(Type,this);
00838 
00839         uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y(); 
00840         uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height(); 
00841 
00842         uInt lineSize = x1 * img.getChannels();
00843         for(uInt row = y0; row < y1; row++)
00844                 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
00845                         return false;   
00846         return true;
00847         };
00848 
00849 typedef QVImage<uChar,1> QVImageUCharC1;
00850 typedef QVImage<uChar,3> QVImageUCharC3;
00851 typedef QVImage<uShort,1> QVImageUShortC1;
00852 typedef QVImage<uShort,3> QVImageUShortC3;
00853 typedef QVImage<sShort,1> QVImageSShortC1;
00854 typedef QVImage<sShort,3> QVImageSShortC3;
00855 typedef QVImage<sInt,1> QVImageSIntC1;
00856 typedef QVImage<sInt,3> QVImageSIntC3;
00857 typedef QVImage<sFloat,1> QVImageSFloatC1;
00858 typedef QVImage<sFloat,3> QVImageSFloatC3;
00859 
00860 Q_DECLARE_METATYPE(QVImageUCharC1);
00861 Q_DECLARE_METATYPE(QVImageUCharC3);
00862 Q_DECLARE_METATYPE(QVImageUShortC1);
00863 Q_DECLARE_METATYPE(QVImageUShortC3);
00864 Q_DECLARE_METATYPE(QVImageSShortC1);
00865 Q_DECLARE_METATYPE(QVImageSShortC3);
00866 Q_DECLARE_METATYPE(QVImageSIntC1);
00867 Q_DECLARE_METATYPE(QVImageSIntC3);
00868 Q_DECLARE_METATYPE(QVImageSFloatC1);
00869 Q_DECLARE_METATYPE(QVImageSFloatC3);
00870 
00871 #endif // QVIMAGE_H



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