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 
00031 #define QVIMAGE_INIT_READ(TYPE, IMAGE)                                  \
00032         const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData();       \
00033         const uInt __qv_step_##IMAGE##__ = IMAGE.getStep();             \
00034         const uChar     __qv_size_##IMAGE##__ = sizeof(TYPE),           \
00035                         __qv_planes_##IMAGE##__  = IMAGE.getPlanes();
00036 
00037 #define QVIMAGE_INIT_WRITE(TYPE, IMAGE)                                 \
00038         TYPE * __qv_data_##IMAGE##__ = IMAGE.getWriteData();            \
00039         const uInt __qv_step_##IMAGE##__ = IMAGE.getStep();             \
00040         const uChar     __qv_size_##IMAGE##__ = sizeof(TYPE),           \
00041                         __qv_planes_##IMAGE##__  = IMAGE.getPlanes();
00042 
00043 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE)                              \
00044         const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData();      \
00045         const uInt __qv_step_##IMAGE##__ = IMAGE->getStep();            \
00046         const uChar     __qv_size_##IMAGE##__ = sizeof(TYPE),           \
00047                         __qv_planes_##IMAGE##__  = IMAGE->getPlanes();
00048 
00049 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE)                             \
00050         TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData();           \
00051         const uInt __qv_step_##IMAGE##__ = IMAGE->getStep();            \
00052         const uChar     __qv_size_##IMAGE##__ = sizeof(TYPE),           \
00053                         __qv_planes_##IMAGE##__  = IMAGE->getPlanes();
00054 
00055 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00056         (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ /__qv_size_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00057 
00067 class QVGenericImage
00068         {
00069         public:
00073                 QVGenericImage (): roi(0,0,0,0), anchor(QPoint(0,0))                                    { }
00074 
00078                 QVGenericImage(QVGenericImage const &img): roi(img.getROI()), anchor(img.getAnchor())   { }
00079 
00081                 virtual ~QVGenericImage ()                                                              { };
00082 
00086                 virtual uInt    getCols()               const   = 0;
00087 
00091                 virtual uInt    getRows()               const   = 0;
00092 
00101                 virtual uInt    getStep()               const   = 0;
00102 
00109                 virtual uInt    getPlanes()             const   = 0;
00110 
00117                 virtual uInt    getTypeSize()           const   = 0;
00118 
00125                 virtual uInt    getDataSize()           const   = 0;
00126 
00133                 const QRect &   getROI()                const   { return roi; }
00134 
00141                 const QPoint &  getAnchor()             const   { return anchor; }
00142 
00143                 // ROI operations
00152                 void resetROI()                         { setROI(0,0,getCols(), getRows()); }
00153 
00163                 void erodeROI(uInt cols, uInt rows)
00164                         { setROI(getROI().x()+cols, getROI().y()+rows, getROI().width()-2*cols, getROI().height()-2*rows); }
00165 
00175                 void dilateROI(uInt cols, uInt rows)
00176                         { setROI(getROI().x()-cols, getROI().y()-rows, getROI().width()+2*cols, getROI().height()+2*rows); }
00177 
00190                 void setROI(int x, int y, uInt w, uInt h) { setROI(QRect(x,y,w,h)); }
00191 
00195                 void setMarginROI(int margin)
00196                         { setROI(margin, margin, getCols() - 2*margin, getRows() -2*margin); }
00197 
00201                 void setROI(const QRect &rect)
00202                         {
00203                         Q_ASSERT_X(rect.x() >= 0,"QVGenericImage::setROI()","QRect.x() is less than zero");
00204                         Q_ASSERT_X(rect.y() >= 0,"QVGenericImage::setROI()","QRect.y() is less than zero");
00205                         Q_ASSERT_X(rect.width() > 0,"QVGenericImage::setROI()","QRect.width() is less or equal to zero");
00206                         Q_ASSERT_X(rect.height() > 0,"QVGenericImage::setROI()","QRect.height() is less or equal to zero");
00207                         Q_ASSERT_X(rect.x()+rect.width() <= (int) getCols(),"QVGenericImage::setROI()","x + width > columns");
00208                         Q_ASSERT_X(rect.x()+rect.height() <= (int) getRows(),"QVGenericImage::setROI()","y + height > rows");
00209                         roi = rect;
00210                         }
00211 
00212                 // Anchor operations
00215                 void resetAnchor()                      { setAnchor(0,0); }
00216 
00221                 void setAnchor(int col, int row)        { setAnchor(QPoint(col,row)); }
00222 
00226                 void setAnchor(const QPoint &point)
00227                         {
00228                         Q_ASSERT_X(point.x()>=0,"QVGenericImage::setAnchor()","horizontal value for anchor is less than zero");
00229                         Q_ASSERT_X(point.y()>=0,"QVGenericImage::setAnchor()","vertical value for anchor is less than zero");
00230                         Q_ASSERT_X(point.x() < (int) getCols(),"QVGenericImage::setAnchor()","horizontal value exceeds cols");
00231                         Q_ASSERT_X(point.y() < (int) getRows(),"QVGenericImage::setAnchor()","vertical value exceeds rows");
00232                         anchor = point;
00233                         }
00234 
00239                 virtual const char * getTypeQString() const = 0;
00240 
00269                 bool isCompatibleWith(const char *qvImageClassName) const
00270                         {
00271                         Q_ASSERT_X(qvImageClassName!= NULL,"QVGenericImage::isCompatibleWith()","class name string is NULL");
00272                         return (0 == strcmp(this->getTypeQString(),qvImageClassName));
00273                         }
00274 
00285                 bool isCompatibleWith(const QVGenericImage *image) const
00286                         {
00287                         Q_ASSERT_X(image!= NULL,"QVGenericImage::isCompatibleWith()","NULL pointer");
00288                         return this->isCompatibleWith(image->getTypeQString());
00289                         }
00290 
00291         protected:
00292                 QRect roi;
00293                 QPoint anchor;
00294         };
00295 
00302 template <typename Type, int Planes = 1> class QVImage: public QVGenericImage 
00303         {
00304         public:
00310                 QVImage():QVGenericImage()
00311                         {
00312                         this->imageBuffer = new QVImageBuffer<Type, Planes>(1, 1);
00313                         setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00314                         setAnchor(0,0);
00315                         }
00316 
00330                 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00331                         {
00332                         this->imageBuffer = new QVImageBuffer<Type, Planes>(cols, rows, step, buffer);
00333                         setROI(0,0, cols, rows);
00334                         setAnchor(0,0);
00335                         }
00336 
00353                 QVImage(QVImage<uChar,1> const &img);
00354 
00356                 QVImage(QVImage<uChar,3> const &img);
00357 
00359                 QVImage(QVImage<sShort,1> const &img);
00360 
00362                 QVImage(QVImage<sShort,3> const &img);
00363 
00365                 QVImage(QVImage<sFloat,1> const &img);
00366 
00368                 QVImage(QVImage<sFloat,3> const &img);
00369                 
00371                 const char * getTypeQString() const;
00372 
00374                 uInt getRows()          const   { return imageBuffer->getRows(); }
00375 
00377                 uInt getCols()          const   { return imageBuffer->getCols(); }
00378 
00380                 inline uInt getStep()   const   { return imageBuffer->getStep(); }
00381 
00383                 inline uInt getPlanes() const   { return imageBuffer->getPlanes(); }
00384 
00386                 uInt getDataSize()      const   { return imageBuffer->getDataSize(); }
00387 
00389                 uInt getTypeSize()      const   { return imageBuffer->getTypeSize(); }
00390 
00401                 const Type * getReadData()      const   { return imageBuffer->getReadData(); }
00402 
00413                 Type * getWriteData()           { return imageBuffer->getWriteData(); }
00414 
00429                 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00430 
00439                 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00440                         {
00441                         Type * data = imageBuffer->getWriteData();
00442                         uInt step = getStep();
00443                         //int dataSize = imageBuffer->getDataSize();
00444 
00445                         Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00446                         Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00447                         int idx = row*step/sizeof(Type) + Planes*col+channel;
00448                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00449                         Q_ASSERT_X(idx < imageBuffer->getDataSize(),"QVImage::operator()","accessing above data");
00450                         return data[idx];
00451                         }
00452 
00453                 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00454                         {
00455                         Type const * data = imageBuffer->getReadData();
00456                         uInt cols = getCols(), rows = getRows();
00457                         uInt step = getStep();
00458                         int dataSize = getDataSize();
00459 
00460                         Q_ASSERT_X(col < cols,"QVImage::operator()","row out of upper bound");
00461                         Q_ASSERT_X(row < rows,"QVImage::operator()","row out of upper bound");
00462                         int idx = row*step/sizeof(Type) + Planes*col+channel;
00463                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00464                         Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00465                         return data[idx];
00466                         }
00467 
00474                 inline Type &operator()(const QPoint point, const uInt channel = 0)
00475                         {
00476                         Type * data = imageBuffer->getWriteData();
00477                         uInt cols = getCols(), rows = getRows(), step = getStep();
00478                         int dataSize = getDataSize();
00479 
00480                         Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","col further upper bound");
00481                         Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row further upper bound");
00482                         int idx = point.y()*step/sizeof(Type) + Planes*point.x()+channel;
00483                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00484                         Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00485                         return data[idx];
00486                         }
00487 
00488                 inline Type operator()(const QPoint point, const uInt channel = 0) const
00489                         {
00490                         Type const * data = imageBuffer->getReadData();
00491                         uInt cols = getCols(), rows = getRows(), step = getStep();
00492                         int dataSize = getDataSize();
00493 
00494                         Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","row out of upper bound");
00495                         Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row out of upper bound");
00496                         int idx = point.y()*step/sizeof(Type) + Planes*point.x()+channel;
00497                         Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00498                         Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00499                         return data[idx];
00500                         }
00501 
00518                 QVImage<Type, Planes> & operator=(const QVImage<uChar, 1> &sourceImage);
00519 
00521                 QVImage<Type, Planes> & operator=(const QVImage<uChar, 3> &sourceImage);
00522 
00524                 QVImage<Type, Planes> & operator=(const QVImage<sShort, 1> &sourceImage);
00525 
00527                 QVImage<Type, Planes> & operator=(const QVImage<sShort, 3> &sourceImage);
00528 
00530                 QVImage<Type, Planes> & operator=(const QVImage<sFloat, 1> &sourceImage);
00531 
00533                 QVImage<Type, Planes> & operator=(const QVImage<sFloat, 3> &sourceImage);
00534                 
00545                 bool operator==(const QVImage<Type, Planes> &img) const;
00546 
00561                 bool operator!=(const QVImage<Type, Planes> &img) const { return !(*this == img); }
00562 
00568                 QVImage<uChar> operator<(const QVImage<Type, Planes> &img) const;
00569 
00575                 QVImage<uChar> operator>(const QVImage<Type, Planes> &img) const;
00576 
00582                 QVImage<uChar> operator<=(const QVImage<Type, Planes> &img) const;
00583 
00589                 QVImage<uChar> operator>=(const QVImage<Type, Planes> &img) const;
00590 
00600                 QVImage<Type, Planes> operator+(const Type constant) const;
00601 
00611                 QVImage<Type, Planes> operator*(const Type constant) const;
00612 
00622                 QVImage<Type, Planes> operator-(const Type constant) const;
00623 
00633                 QVImage<Type, Planes> operator/(const Type constant) const;
00634 
00644                 QVImage<Type, Planes> operator<<(const Type constant) const;
00645 
00655                 QVImage<Type, Planes> operator>>(const Type constant) const;
00656 
00662                 QVImage<Type, Planes> operator!() const;
00663 
00670                 QVImage<Type, Planes> operator&(const Type constant) const;
00671 
00678                 QVImage<Type, Planes> operator|(const Type constant) const;
00679 
00686                 QVImage<Type, Planes> operator^(const Type constant) const;
00687 
00695                 QVImage<Type, Planes> operator+(const QVImage<Type, Planes> &img) const;
00696 
00704                 QVImage<Type, Planes> operator*(const QVImage<Type, Planes> &img) const;
00705 
00713                 QVImage<Type, Planes> operator-(const QVImage<Type, Planes> &img) const;
00714 
00722                 QVImage<Type, Planes> operator/(const QVImage<Type, Planes> &img) const;
00723 
00724         protected:
00725                 QSharedDataPointer< QVImageBuffer<Type,Planes> > imageBuffer;
00726         };
00727 
00728 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
00729         {
00730         Q_ASSERT_X(img.getPlanes() == this->getPlanes(), "QVImage::operator==", "different number of planes");
00731         if (this->getCols() != img.getCols()) return false;
00732         if (this->getRows() != img.getRows()) return false;
00733         if (this->getPlanes() != img.getPlanes()) return false;
00734         if (this->getROI() != img.getROI()) return false;
00735         QVIMAGE_INIT_READ(Type,img);
00736         QVIMAGE_PTR_INIT_READ(Type,this);
00737 
00738         uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y(); 
00739         uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height(); 
00740 
00741         uInt lineSize = x1 * img.getPlanes();
00742         for(uInt row = y0; row < y1; row++)
00743                 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
00744                         return false;   
00745         return true;
00746         };
00747 
00748 
00749 typedef QVImage<uChar,1> QVImageUCharC1;
00750 typedef QVImage<uChar,3> QVImageUCharC3;
00751 typedef QVImage<sFloat,1> QVImageSFloatC1;
00752 typedef QVImage<sFloat,3> QVImageSFloatC3;
00753 typedef QVImage<sShort,1> QVImageSShortC1;
00754 typedef QVImage<sShort,3> QVImageSShortC3;
00755 
00756 //Q_DECLARE_METATYPE(QVGenericImage);
00757 Q_DECLARE_METATYPE(QVImageUCharC1);
00758 Q_DECLARE_METATYPE(QVImageUCharC3);
00759 Q_DECLARE_METATYPE(QVImageSFloatC1);
00760 Q_DECLARE_METATYPE(QVImageSFloatC3);
00761 Q_DECLARE_METATYPE(QVImageSShortC1);
00762 Q_DECLARE_METATYPE(QVImageSShortC3);
00763 
00764 #endif // QVIMAGE_H

Generated on Fri Dec 7 12:20:59 2007 for QVision by  doxygen 1.5.3