00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #ifndef QVIMAGE_H
00026 #define QVIMAGE_H
00027
00028 #include <QMetaType>
00029 #include <QVGenericImage>
00030 #include <qvip/qvimagebuffer.h>
00031 #include <QImage>
00032
00033 #include <qvmath/qvmath.h>
00034
00035 #ifdef QVOPENCV
00036 #include <cv.h>
00037 #endif
00038
00039 #ifndef QVIPP
00040 #define IPP_MAX_8U std::numeric_limits<unsigned char>::max()
00041 #define IPP_MIN_8U std::numeric_limits<unsigned char>::min()
00042 #endif
00043
00055 #define QVIMAGE_INIT_READ(TYPE, IMAGE) \
00056 const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData(); \
00057 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00058 const uChar __qv_planes_##IMAGE##__ = IMAGE.getChannels(); \
00059 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE.getCols(); \
00060 Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00061
00074 #define QVIMAGE_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 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE.getCols(); \
00079 Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00080
00093 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE) \
00094 const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData(); \
00095 const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE); \
00096 const uChar __qv_planes_##IMAGE##__ = IMAGE->getChannels(); \
00097 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE->getCols(); \
00098 Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00099
00112 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE) \
00113 TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData(); \
00114 const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE); \
00115 const uChar __qv_planes_##IMAGE##__ = IMAGE->getChannels(); \
00116 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - __qv_planes_##IMAGE##__ * IMAGE->getCols(); \
00117 Q_UNUSED (__qv_next_line_inc_##IMAGE##__) ;
00118
00131 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00132 (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00133
00146 #define QVIMAGE_PIXEL_PTR(IMAGE, Col, Row, Channel) \
00147 (& (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)]))
00148
00158 #define QVIMAGE_ROW_INCREMENT_PTR(IMAGE) ( __qv_step_##IMAGE##__ )
00159
00170 #define QVIMAGE_COL_INCREMENT_PTR(IMAGE) ( __qv_planes_##IMAGE##__ )
00171
00181 #define QVIMAGE_NEXT_LINE_INCREMENT_PTR(IMAGE) ( __qv_next_line_inc_##IMAGE##__ )
00182
00183
00184 #ifndef QVIPP
00185 template <typename Type, int Channels> class QVImage;
00186
00187 void Set(const uChar value, QVImage<uChar, 1> &image);
00188 void Set(const sFloat value, QVImage<sFloat, 1> &image);
00189 void Set(const sInt value, QVImage<sInt, 1> &image);
00190 void Set(const uInt value, QVImage<uInt, 1> &image);
00191 void Set(const sShort value, QVImage<sShort, 1> &image);
00192 void Set(const uShort value, QVImage<uShort, 1> &image);
00193
00194 void Set(const uChar value[3], QVImage<uChar, 3> &image);
00195 void Set(const sFloat value[3], QVImage<sFloat, 3> &image);
00196 void Set(const sInt value[3], QVImage<sInt, 3> &image);
00197 void Set(const uInt value[3], QVImage<uInt, 3> &image);
00198 void Set(const sShort value[3], QVImage<sShort, 3> &image);
00199 void Set(const uShort value[3], QVImage<uShort, 3> &image);
00200 #endif
00201
00202
00213 #include <stdio.h>
00214 #include <stdlib.h>
00215 #include <iostream>
00216
00217 template <typename Type = uChar, int Channels = 1> class QVImage: public QVGenericImage
00218 {
00219 protected:
00220 uInt step_div_type_size;
00221 QSharedDataPointer< QVImageBuffer<Type,Channels> > imageBuffer;
00222
00223 public:
00229 QVImage():QVGenericImage()
00230 {
00231 this->imageBuffer = new QVImageBuffer<Type, Channels>(1, 1);
00232 setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00233 setAnchor(0,0);
00234 this->step_div_type_size = getStep()/sizeof(Type);
00235 }
00236
00273 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00274 {
00275 this->imageBuffer = new QVImageBuffer<Type, Channels>(cols, rows, step, buffer);
00276 setROI(0,0, cols, rows);
00277 setAnchor(0,0);
00278 this->step_div_type_size = getStep()/sizeof(Type);
00279 }
00280
00297 QVImage(QVImage<uChar,1> const &img);
00298
00300 QVImage(QVImage<uChar,3> const &img);
00301
00303 QVImage(QVImage<uShort,1> const &img);
00304
00306 QVImage(QVImage<uShort,3> const &img);
00307
00309 QVImage(QVImage<sShort,1> const &img);
00310
00312 QVImage(QVImage<sShort,3> const &img);
00313
00315 QVImage(QVImage<sInt,1> const &img);
00316
00318 QVImage(QVImage<sInt,3> const &img);
00319
00321 QVImage(QVImage<sFloat,1> const &img);
00322
00324 QVImage(QVImage<sFloat,3> const &img);
00325
00327 QVImage(const QString &filename)
00328 {
00329 QImage qimg;
00330 qimg.load(filename);
00331 *this = QVImage<uChar, 3>(qimg);
00332 };
00333
00343 QVImage(QVImage<uChar,1> const &red, QVImage<uChar,1> const &green, QVImage<uChar,1> const &blue);
00344
00346 QVImage(QVImage<uShort,1> const &red, QVImage<uShort,1> const &green, QVImage<uShort,1> const &blue);
00347
00349 QVImage(QVImage<sShort,1> const &red, QVImage<sShort,1> const &green, QVImage<sShort,1> const &blue);
00350
00352 QVImage(QVImage<sInt,1> const &red, QVImage<sInt,1> const &green, QVImage<sInt,1> const &blue);
00353
00355 QVImage(QVImage<sFloat,1> const &red, QVImage<sFloat,1> const &green, QVImage<sFloat,1> const &blue);
00356
00357
00359 QVImage(const QImage &qImage);
00360
00362 operator QImage() const;
00363
00364
00365 #ifdef QVOPENCV
00373 QVImage(const IplImage *iplImage);
00374
00381 operator IplImage *() const;
00382 #endif
00383
00384
00386 const char * getTypeQString() const;
00387
00389 uInt getRows() const { return imageBuffer->getRows(); }
00390
00392 uInt getCols() const { return imageBuffer->getCols(); }
00393
00395 inline uInt getStep() const { return imageBuffer->getStep(); }
00396
00398 inline uInt getChannels() const { return imageBuffer->getChannels(); }
00399
00401 uInt getDataSize() const { return imageBuffer->getDataSize(); }
00402
00404 uInt getTypeSize() const { return imageBuffer->getTypeSize(); }
00405
00416 const Type * getReadData() const { return imageBuffer->getReadData(); }
00417
00428 Type * getWriteData() { return imageBuffer->getWriteData(); }
00429
00444 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00445
00446
00453 void resize(const int cols, const int rows)
00454 {
00455 if (((int)getCols()) >= cols && ((int)getRows()) >= rows)
00456 return;
00457
00458 QVImage<Type, Channels> temp(MAX(cols, (int)getCols()), MAX(rows, (int)getRows()));
00459 Copy(*this, temp);
00460
00461 *this = temp;
00462 }
00463
00472 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00473 {
00474 Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00475 Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00476 Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00477 const int idx = step_div_type_size*row + Channels*col + channel;
00478 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00479 Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00480
00481 return imageBuffer->getWriteData()[idx];
00482 }
00483
00484 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00485 {
00486 Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00487 Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00488 Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00489 const int idx = step_div_type_size*row + Channels*col + channel;
00490 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00491 Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00492
00493 return imageBuffer->getReadData()[idx];
00494 }
00495
00502 inline Type &operator()(const QPoint point, const uInt channel = 0)
00503 {
00504 Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00505 Q_ASSERT_X(point.x() < getCols(),"QVImage::operator()","col further upper bound");
00506 Q_ASSERT_X(point.y() < getRows(),"QVImage::operator()","row further upper bound");
00507 const int idx = step_div_type_size*point.y() + Channels*point.x() + channel;
00508 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00509 Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00510
00511 return imageBuffer->getWriteData()[idx];
00512 }
00513
00514 inline Type operator()(const QPoint point, const uInt channel = 0) const
00515 {
00516 Q_ASSERT_X(step_div_type_size == getStep()/sizeof(Type), "QVImage::operator()", "step/size(Type) incorrect");
00517 Q_ASSERT_X(point.x() < getCols(),"QVImage::operator()","col further upper bound");
00518 Q_ASSERT_X(point.y() < getRows(),"QVImage::operator()","row further upper bound");
00519 const int idx = step_div_type_size*point.y() + Channels*point.x() + channel;
00520 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00521 Q_ASSERT_X((uint)idx < getDataSize(),"QVImage::operator()","accessing above data");
00522
00523 return imageBuffer->getReadData()[idx];
00524 }
00525
00534 QVImage<Type, 1> operator()(const uInt channel = 0) const;
00535
00552 QVImage<Type, Channels> & operator=(const QVImage<uChar, 1> &sourceImage);
00553
00555 QVImage<Type, Channels> & operator=(const QVImage<uChar, 3> &sourceImage);
00556
00558 QVImage<Type, Channels> & operator=(const QVImage<uShort, 1> &sourceImage);
00559
00561 QVImage<Type, Channels> & operator=(const QVImage<uShort, 3> &sourceImage);
00562
00564 QVImage<Type, Channels> & operator=(const QVImage<sShort, 1> &sourceImage);
00565
00567 QVImage<Type, Channels> & operator=(const QVImage<sShort, 3> &sourceImage);
00568
00570 QVImage<Type, Channels> & operator=(const QVImage<sInt, 1> &sourceImage);
00571
00573 QVImage<Type, Channels> & operator=(const QVImage<sInt, 3> &sourceImage);
00574
00576 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 1> &sourceImage);
00577
00579 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 3> &sourceImage);
00580
00591 bool operator==(const QVImage<Type, Channels> &img) const;
00592
00606 bool operator!=(const QVImage<Type, Channels> &img) const { return !(*this == img); }
00607
00608 #ifdef QVIPP
00617 QVImage<uChar, 1> operator<(const QVImage<uChar, Channels> &img) const;
00618
00627 QVImage<uChar, 1> operator<(const QVImage<uShort, Channels> &img) const;
00628
00637 QVImage<uChar, 1> operator<(const QVImage<sShort, Channels> &img) const;
00638
00647 QVImage<uChar, 1> operator<(const QVImage<sInt, Channels> &img) const;
00648
00657 QVImage<uChar, 1> operator<(const QVImage<sFloat, Channels> &img) const;
00658
00667 QVImage<uChar, 1> operator>(const QVImage<uChar, Channels> &img) const;
00668
00677 QVImage<uChar, 1> operator>(const QVImage<uShort, Channels> &img) const;
00678
00687 QVImage<uChar, 1> operator>(const QVImage<sShort, Channels> &img) const;
00688
00697 QVImage<uChar, 1> operator>(const QVImage<sInt, Channels> &img) const;
00698
00707 QVImage<uChar, 1> operator>(const QVImage<sFloat, Channels> &img) const;
00708
00717 QVImage<uChar, 1> operator<=(const QVImage<uChar, Channels> &img) const;
00718
00727 QVImage<uChar, 1> operator<=(const QVImage<uShort, Channels> &img) const;
00728
00737 QVImage<uChar, 1> operator<=(const QVImage<sShort, Channels> &img) const;
00738
00747 QVImage<uChar, 1> operator<=(const QVImage<sInt, Channels> &img) const;
00748
00757 QVImage<uChar, 1> operator<=(const QVImage<sFloat, Channels> &img) const;
00758
00767 QVImage<uChar, 1> operator>=(const QVImage<uChar, Channels> &img) const;
00768
00777 QVImage<uChar, 1> operator>=(const QVImage<uShort, Channels> &img) const;
00778
00787 QVImage<uChar, 1> operator>=(const QVImage<sShort, Channels> &img) const;
00788
00797 QVImage<uChar, 1> operator>=(const QVImage<sInt, Channels> &img) const;
00798
00807 QVImage<uChar, 1> operator>=(const QVImage<sFloat, Channels> &img) const;
00808
00821 QVImage<Type, Channels> operator+(const Type constant) const;
00822
00835 QVImage<Type, Channels> operator*(const Type constant) const;
00836
00849 QVImage<Type, Channels> operator-(const Type constant) const;
00850
00863 QVImage<Type, Channels> operator/(const Type constant) const;
00864
00877 QVImage<Type, Channels> operator<<(const Type constant) const;
00878
00891 QVImage<Type, Channels> operator>>(const Type constant) const;
00892
00901 QVImage<Type, Channels> operator!() const;
00902
00912 QVImage<Type, Channels> operator&(const Type constant) const;
00913
00923 QVImage<Type, Channels> operator|(const Type constant) const;
00924
00934 QVImage<Type, Channels> operator^(const Type constant) const;
00935
00946 QVImage<Type, Channels> operator+(const QVImage<Type, Channels> &img) const;
00947
00958 QVImage<Type, Channels> operator*(const QVImage<Type, Channels> &img) const;
00959
00970 QVImage<Type, Channels> operator-(const QVImage<Type, Channels> &img) const;
00971
00982 QVImage<Type, Channels> operator/(const QVImage<Type, Channels> &img) const;
00983 #endif
00984 };
00985
00990 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
00991 {
00992 Q_ASSERT_X(img.getChannels() == this->getChannels(), "QVImage::operator==", "different number of planes");
00993 if (this->getCols() != img.getCols()) return false;
00994 if (this->getRows() != img.getRows()) return false;
00995 if (this->getChannels() != img.getChannels()) return false;
00996 if (this->getROI() != img.getROI()) return false;
00997 QVIMAGE_INIT_READ(Type,img);
00998 QVIMAGE_PTR_INIT_READ(Type,this);
00999
01000 uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y();
01001 uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height();
01002
01003 uInt lineSize = x1 * img.getChannels();
01004 for(uInt row = y0; row < y1; row++)
01005 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
01006 return false;
01007 return true;
01008 };
01009
01010 typedef QVImage<uChar,1> QVImageUCharC1;
01011 typedef QVImage<uChar,3> QVImageUCharC3;
01012 typedef QVImage<uShort,1> QVImageUShortC1;
01013 typedef QVImage<uShort,3> QVImageUShortC3;
01014 typedef QVImage<sShort,1> QVImageSShortC1;
01015 typedef QVImage<sShort,3> QVImageSShortC3;
01016 typedef QVImage<sInt,1> QVImageSIntC1;
01017 typedef QVImage<sInt,3> QVImageSIntC3;
01018 typedef QVImage<sFloat,1> QVImageSFloatC1;
01019 typedef QVImage<sFloat,3> QVImageSFloatC3;
01020
01021 Q_DECLARE_METATYPE(QVImageUCharC1);
01022 Q_DECLARE_METATYPE(QVImageUCharC3);
01023 Q_DECLARE_METATYPE(QVImageUShortC1);
01024 Q_DECLARE_METATYPE(QVImageUShortC3);
01025 Q_DECLARE_METATYPE(QVImageSShortC1);
01026 Q_DECLARE_METATYPE(QVImageSShortC3);
01027 Q_DECLARE_METATYPE(QVImageSIntC1);
01028 Q_DECLARE_METATYPE(QVImageSIntC3);
01029 Q_DECLARE_METATYPE(QVImageSFloatC1);
01030 Q_DECLARE_METATYPE(QVImageSFloatC3);
01031
01032 #endif // QVIMAGE_H