src/qvcore/qvimage.h

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. 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 
00038 #define QVIMAGE_INIT_READ(TYPE, IMAGE)                                          \
00039         const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData();               \
00040         const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE);        \
00041         const uChar __qv_planes_##IMAGE##__  = IMAGE.getChannels();
00042 
00050 #define QVIMAGE_INIT_WRITE(TYPE, IMAGE)                                         \
00051         TYPE * __qv_data_##IMAGE##__ = IMAGE.getWriteData();                    \
00052         const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE);        \
00053         const uChar __qv_planes_##IMAGE##__  = IMAGE.getChannels();
00054 
00062 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE)                                      \
00063         const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData();              \
00064         const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE);       \
00065         const uChar __qv_planes_##IMAGE##__  = IMAGE->getChannels();
00066 
00074 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE)                                     \
00075         TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData();                   \
00076         const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE);       \
00077         const uChar __qv_planes_##IMAGE##__  = IMAGE->getChannels();
00078 
00087 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00088         (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00089 
00121 class QVGenericImage
00122         {
00123         public:
00127                 QVGenericImage (): roi(0,0,0,0), anchor(QPoint(0,0))                                    { }
00128 
00132                 QVGenericImage(QVGenericImage const &img): roi(img.getROI()), anchor(img.getAnchor())   { }
00133 
00135                 virtual ~QVGenericImage ()                                                              { };
00136 
00140                 virtual uInt    getCols()               const   = 0;
00141 
00145                 virtual uInt    getRows()               const   = 0;
00146 
00155                 virtual uInt    getStep()               const   = 0;
00156 
00163                 virtual uInt    getChannels()           const   = 0;
00164 
00171                 virtual uInt    getTypeSize()           const   = 0;
00172 
00179                 virtual uInt    getDataSize()           const   = 0;
00180 
00187                 const QRect &   getROI()                const   { return roi; }
00188 
00195                 const QPoint &  getAnchor()             const   { return anchor; }
00196 
00197                 // ROI operations
00206                 void resetROI()                         { setROI(0,0,getCols(), getRows()); }
00207 
00217                 void erodeROI(uInt cols, uInt rows)
00218                         { setROI(getROI().x()+cols, getROI().y()+rows, getROI().width()-2*cols, getROI().height()-2*rows); }
00219 
00229                 void dilateROI(uInt cols, uInt rows)
00230                         { setROI(getROI().x()-cols, getROI().y()-rows, getROI().width()+2*cols, getROI().height()+2*rows); }
00231 
00244                 void setROI(int x, int y, uInt w, uInt h) { setROI(QRect(x,y,w,h)); }
00245 
00249                 void setMarginROI(int margin)
00250                         { setROI(margin, margin, getCols() - 2*margin, getRows() -2*margin); }
00251 
00255                 void setROI(const QRect &rect)
00256                         {
00257                         Q_ASSERT_X(rect.x() >= 0,"QVGenericImage::setROI()","QRect.x() is less than zero");
00258                         Q_ASSERT_X(rect.y() >= 0,"QVGenericImage::setROI()","QRect.y() is less than zero");
00259                         Q_ASSERT_X(rect.width() > 0,"QVGenericImage::setROI()","QRect.width() is less or equal to zero");
00260                         Q_ASSERT_X(rect.height() > 0,"QVGenericImage::setROI()","QRect.height() is less or equal to zero");
00261                         Q_ASSERT_X(rect.x()+rect.width() <= (int) getCols(),"QVGenericImage::setROI()","x + width > columns");
00262                         Q_ASSERT_X(rect.y()+rect.height() <= (int) getRows(),"QVGenericImage::setROI()","y + height > rows");
00263                         roi = rect;
00264                         }
00265 
00266                 // Anchor operations
00269                 void resetAnchor()                      { setAnchor(0,0); }
00270 
00275                 void setAnchor(int col, int row)        { setAnchor(QPoint(col,row)); }
00276 
00280                 void setAnchor(const QPoint &point)
00281                         {
00282                         Q_ASSERT_X(point.x()>=0,"QVGenericImage::setAnchor()","horizontal value for anchor is less than zero");
00283                         Q_ASSERT_X(point.y()>=0,"QVGenericImage::setAnchor()","vertical value for anchor is less than zero");
00284                         Q_ASSERT_X(point.x() < (int) getCols(),"QVGenericImage::setAnchor()","horizontal value exceeds cols");
00285                         Q_ASSERT_X(point.y() < (int) getRows(),"QVGenericImage::setAnchor()","vertical value exceeds rows");
00286                         anchor = point;
00287                         }
00288 
00293                 virtual const char * getTypeQString() const = 0;
00294 
00323                 bool isCompatibleWith(const char *qvImageClassName) const
00324                         {
00325                         Q_ASSERT_X(qvImageClassName!= NULL,"QVGenericImage::isCompatibleWith()","class name string is NULL");
00326                         return (0 == strcmp(this->getTypeQString(),qvImageClassName));
00327                         }
00328 
00339                 bool isCompatibleWith(const QVGenericImage *image) const
00340                         {
00341                         Q_ASSERT_X(image!= NULL,"QVGenericImage::isCompatibleWith()","NULL pointer");
00342                         return this->isCompatibleWith(image->getTypeQString());
00343                         }
00344 
00345         protected:
00346                 QRect roi;
00347                 QPoint anchor;
00348         };
00349 
00507 template <typename Type, int Channels = 1> class QVImage: public QVGenericImage 
00508         {
00509         public:
00515                 QVImage():QVGenericImage()
00516                         {
00517                         this->imageBuffer = new QVImageBuffer<Type, Channels>(1, 1);
00518                         setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00519                         setAnchor(0,0);
00520                         }
00521 
00558                 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00559                         {
00560                         this->imageBuffer = new QVImageBuffer<Type, Channels>(cols, rows, step, buffer);
00561                         setROI(0,0, cols, rows);
00562                         setAnchor(0,0);
00563                         }
00564 
00581                 QVImage(QVImage<uChar,1> const &img);
00582 
00584                 QVImage(QVImage<uChar,3> const &img);
00585 
00587                 QVImage(QVImage<uShort,1> const &img);
00588 
00590                 QVImage(QVImage<uShort,3> const &img);
00591 
00593                 QVImage(QVImage<sShort,1> const &img);
00594 
00596                 QVImage(QVImage<sShort,3> const &img);
00597 
00599                 QVImage(QVImage<sInt,1> const &img);
00600 
00602                 QVImage(QVImage<sInt,3> const &img);
00603 
00605                 QVImage(QVImage<sFloat,1> const &img);
00606 
00608                 QVImage(QVImage<sFloat,3> const &img);
00609 
00619                 QVImage(QVImage<uChar,1> const &red, QVImage<uChar,1> const &green, QVImage<uChar,1> const &blue);
00620 
00622                 QVImage(QVImage<uShort,1> const &red, QVImage<uShort,1> const &green, QVImage<uShort,1> const &blue);
00623 
00625                 QVImage(QVImage<sShort,1> const &red, QVImage<sShort,1> const &green, QVImage<sShort,1> const &blue);
00626 
00628                 QVImage(QVImage<sInt,1> const &red, QVImage<sInt,1> const &green, QVImage<sInt,1> const &blue);
00629 
00631                 QVImage(QVImage<sFloat,1> const &red, QVImage<sFloat,1> const &green, QVImage<sFloat,1> const &blue);
00632 
00633 
00635                 const char * getTypeQString() const;
00636 
00638                 uInt getRows()          const   { return imageBuffer->getRows(); }
00639 
00641                 uInt getCols()          const   { return imageBuffer->getCols(); }
00642 
00644                 inline uInt getStep()   const   { return imageBuffer->getStep(); }
00645 
00647                 inline uInt getChannels()       const   { return imageBuffer->getChannels(); }
00648 
00650                 uInt getDataSize()      const   { return imageBuffer->getDataSize(); }
00651 
00653                 uInt getTypeSize()      const   { return imageBuffer->getTypeSize(); }
00654 
00665                 const Type * getReadData()      const   { return imageBuffer->getReadData(); }
00666 
00677                 Type * getWriteData()           { return imageBuffer->getWriteData(); }
00678 
00693                 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00694 
00703                 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00704                         {
00705                         Type * data = imageBuffer->getWriteData();
00706                         uInt step = getStep();
00707 
00708                         Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00709                         Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00710                         int idx = row*step/sizeof(Type) + Channels*col+channel;
00711                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00712                         Q_ASSERT_X(idx < imageBuffer->getDataSize(),"QVImage::operator()","accessing above data");
00713                         return data[idx];
00714                         }
00715 
00716                 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00717                         {
00718                         Type const * data = imageBuffer->getReadData();
00719                         uInt cols = getCols(), rows = getRows();
00720                         uInt step = getStep();
00721                         int dataSize = getDataSize();
00722 
00723                         Q_ASSERT_X(col < cols,"QVImage::operator()","row out of upper bound");
00724                         Q_ASSERT_X(row < rows,"QVImage::operator()","row out of upper bound");
00725                         int idx = row*step/sizeof(Type) + Channels*col+channel;
00726                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00727                         Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00728                         return data[idx];
00729                         }
00730 
00737                 inline Type &operator()(const QPoint point, const uInt channel = 0)
00738                         {
00739                         Type * data = imageBuffer->getWriteData();
00740                         uInt cols = getCols(), rows = getRows(), step = getStep();
00741                         int dataSize = getDataSize();
00742 
00743                         Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","col further upper bound");
00744                         Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row further upper bound");
00745                         int idx = point.y()*step/sizeof(Type) + Channels*point.x()+channel;
00746                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00747                         Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00748                         return data[idx];
00749                         }
00750 
00751                 inline Type operator()(const QPoint point, const uInt channel = 0) const
00752                         {
00753                         Type const * data = imageBuffer->getReadData();
00754                         uInt cols = getCols(), rows = getRows(), step = getStep();
00755                         int dataSize = getDataSize();
00756 
00757                         Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","row out of upper bound");
00758                         Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row out of upper bound");
00759                         int idx = point.y()*step/sizeof(Type) + Channels*point.x()+channel;
00760                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00761                         Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00762                         return data[idx];
00763                         }
00764 
00773                 QVImage<Type, 1> operator()(const uInt channel = 0) const;
00774 
00791                 QVImage<Type, Channels> & operator=(const QVImage<uChar, 1> &sourceImage);
00792 
00794                 QVImage<Type, Channels> & operator=(const QVImage<uChar, 3> &sourceImage);
00795 
00797                 QVImage<Type, Channels> & operator=(const QVImage<uShort, 1> &sourceImage);
00798 
00800                 QVImage<Type, Channels> & operator=(const QVImage<uShort, 3> &sourceImage);
00801 
00803                 QVImage<Type, Channels> & operator=(const QVImage<sShort, 1> &sourceImage);
00804 
00806                 QVImage<Type, Channels> & operator=(const QVImage<sShort, 3> &sourceImage);
00807 
00809                 QVImage<Type, Channels> & operator=(const QVImage<sInt, 1> &sourceImage);
00810 
00812                 QVImage<Type, Channels> & operator=(const QVImage<sInt, 3> &sourceImage);
00813 
00815                 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 1> &sourceImage);
00816 
00818                 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 3> &sourceImage);
00819 
00830                 bool operator==(const QVImage<Type, Channels> &img) const;
00831 
00845                 bool operator!=(const QVImage<Type, Channels> &img) const { return !(*this == img); }
00846 
00852                 QVImage<uChar, 1> operator<(const QVImage<uChar, Channels> &img) const;
00853 
00859                 QVImage<uChar, 1> operator<(const QVImage<uShort, Channels> &img) const;
00860 
00866                 QVImage<uChar, 1> operator<(const QVImage<sShort, Channels> &img) const;
00867 
00873                 QVImage<uChar, 1> operator<(const QVImage<sInt, Channels> &img) const;
00874 
00880                 QVImage<uChar, 1> operator<(const QVImage<sFloat, Channels> &img) const;
00881 
00887                 QVImage<uChar, 1> operator>(const QVImage<uChar, Channels> &img) const;
00888 
00894                 QVImage<uChar, 1> operator>(const QVImage<uShort, Channels> &img) const;
00895 
00901                 QVImage<uChar, 1> operator>(const QVImage<sShort, Channels> &img) const;
00902 
00908                 QVImage<uChar, 1> operator>(const QVImage<sInt, Channels> &img) const;
00909 
00915                 QVImage<uChar, 1> operator>(const QVImage<sFloat, Channels> &img) const;
00916 
00922                 QVImage<uChar, 1> operator<=(const QVImage<uChar, Channels> &img) const;
00923 
00929                 QVImage<uChar, 1> operator<=(const QVImage<uShort, Channels> &img) const;
00930 
00936                 QVImage<uChar, 1> operator<=(const QVImage<sShort, Channels> &img) const;
00937 
00943                 QVImage<uChar, 1> operator<=(const QVImage<sInt, Channels> &img) const;
00944 
00950                 QVImage<uChar, 1> operator<=(const QVImage<sFloat, Channels> &img) const;
00951 
00957                 QVImage<uChar, 1> operator>=(const QVImage<uChar, Channels> &img) const;
00958 
00964                 QVImage<uChar, 1> operator>=(const QVImage<uShort, Channels> &img) const;
00965 
00971                 QVImage<uChar, 1> operator>=(const QVImage<sShort, Channels> &img) const;
00972 
00978                 QVImage<uChar, 1> operator>=(const QVImage<sInt, Channels> &img) const;
00979 
00985                 QVImage<uChar, 1> operator>=(const QVImage<sFloat, Channels> &img) const;
00986 
00996                 QVImage<Type, Channels> operator+(const Type constant) const;
00997 
01007                 QVImage<Type, Channels> operator*(const Type constant) const;
01008 
01018                 QVImage<Type, Channels> operator-(const Type constant) const;
01019 
01029                 QVImage<Type, Channels> operator/(const Type constant) const;
01030 
01040                 QVImage<Type, Channels> operator<<(const Type constant) const;
01041 
01051                 QVImage<Type, Channels> operator>>(const Type constant) const;
01052 
01058                 QVImage<Type, Channels> operator!() const;
01059 
01066                 QVImage<Type, Channels> operator&(const Type constant) const;
01067 
01074                 QVImage<Type, Channels> operator|(const Type constant) const;
01075 
01082                 QVImage<Type, Channels> operator^(const Type constant) const;
01083 
01091                 QVImage<Type, Channels> operator+(const QVImage<Type, Channels> &img) const;
01092 
01100                 QVImage<Type, Channels> operator*(const QVImage<Type, Channels> &img) const;
01101 
01109                 QVImage<Type, Channels> operator-(const QVImage<Type, Channels> &img) const;
01110 
01118                 QVImage<Type, Channels> operator/(const QVImage<Type, Channels> &img) const;
01119 
01120         protected:
01121                 QSharedDataPointer< QVImageBuffer<Type,Channels> > imageBuffer;
01122         };
01123 
01124 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
01125         {
01126         Q_ASSERT_X(img.getChannels() == this->getChannels(), "QVImage::operator==", "different number of planes");
01127         if (this->getCols() != img.getCols()) return false;
01128         if (this->getRows() != img.getRows()) return false;
01129         if (this->getChannels() != img.getChannels()) return false;
01130         if (this->getROI() != img.getROI()) return false;
01131         QVIMAGE_INIT_READ(Type,img);
01132         QVIMAGE_PTR_INIT_READ(Type,this);
01133 
01134         uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y(); 
01135         uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height(); 
01136 
01137         uInt lineSize = x1 * img.getChannels();
01138         for(uInt row = y0; row < y1; row++)
01139                 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
01140                         return false;   
01141         return true;
01142         };
01143 
01144 
01145 typedef QVImage<uChar,1> QVImageUCharC1;
01146 typedef QVImage<uChar,3> QVImageUCharC3;
01147 typedef QVImage<uShort,1> QVImageUShortC1;
01148 typedef QVImage<uShort,3> QVImageUShortC3;
01149 typedef QVImage<sShort,1> QVImageSShortC1;
01150 typedef QVImage<sShort,3> QVImageSShortC3;
01151 typedef QVImage<sInt,1> QVImageSIntC1;
01152 typedef QVImage<sInt,3> QVImageSIntC3;
01153 typedef QVImage<sFloat,1> QVImageSFloatC1;
01154 typedef QVImage<sFloat,3> QVImageSFloatC3;
01155 
01156 Q_DECLARE_METATYPE(QVImageUCharC1);
01157 Q_DECLARE_METATYPE(QVImageUCharC3);
01158 Q_DECLARE_METATYPE(QVImageUShortC1);
01159 Q_DECLARE_METATYPE(QVImageUShortC3);
01160 Q_DECLARE_METATYPE(QVImageSShortC1);
01161 Q_DECLARE_METATYPE(QVImageSShortC3);
01162 Q_DECLARE_METATYPE(QVImageSIntC1);
01163 Q_DECLARE_METATYPE(QVImageSIntC3);
01164 Q_DECLARE_METATYPE(QVImageSFloatC1);
01165 Q_DECLARE_METATYPE(QVImageSFloatC3);
01166 
01167 #endif // QVIMAGE_H

Generated on Thu Jul 17 17:23:27 2008 for QVision by  doxygen 1.5.3