Cinder

  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/CinderOpenCV.h

Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include "opencv2/opencv.hpp"
00004 
00005 #include "cinder/Cinder.h"
00006 #include "cinder/ImageIo.h"
00007 
00008 namespace cinder {
00009 
00010 class ImageTargetCvMat : public ImageTarget {
00011   public:
00012     static std::shared_ptr<ImageTargetCvMat> createRef( cv::Mat *mat ) { return std::shared_ptr<ImageTargetCvMat>( new ImageTargetCvMat( mat ) ); }
00013 
00014     virtual bool hasAlpha() const { return mMat->channels() == 4; } 
00015     virtual void*   getRowPointer( int32_t row ) { return reinterpret_cast<void*>( reinterpret_cast<uint8_t*>(mMat->data) + row * mMat->step ); }
00016     
00017   protected:
00018     ImageTargetCvMat( cv::Mat *mat );
00019     
00020     cv::Mat     *mMat;
00021 };
00022 
00023 class ImageSourceCvMat : public ImageSource {
00024   public:
00025     ImageSourceCvMat( const cv::Mat &mat )
00026         : ImageSource()
00027     {
00028         mWidth = mat.cols;
00029         mHeight = mat.rows;
00030         if( (mat.channels() == 3) || (mat.channels() == 4) ) {
00031             setColorModel( ImageIo::CM_RGB );
00032             if( mat.channels() == 4 )
00033                 setChannelOrder( ImageIo::BGRA );
00034             else
00035                 setChannelOrder( ImageIo::BGR );
00036         }
00037         else if( mat.channels() == 1 ) {
00038             setColorModel( ImageIo::CM_GRAY );
00039             setChannelOrder( ImageIo::Y );
00040         }
00041         
00042         switch( mat.depth() ) {
00043             case CV_8U: setDataType( ImageIo::UINT8 ); break;
00044             case CV_16U: setDataType( ImageIo::UINT16 ); break;
00045             case CV_32F: setDataType( ImageIo::FLOAT32 ); break;
00046             default:
00047                 throw ImageIoExceptionIllegalDataType();
00048         }
00049 
00050         mRowBytes = mat.step;
00051         mData = reinterpret_cast<const uint8_t*>( mat.data );
00052     }
00053 
00054     void load( ImageTargetRef target ) {
00055         // get a pointer to the ImageSource function appropriate for handling our data configuration
00056         ImageSource::RowFunc func = setupRowFunc( target );
00057         
00058         const uint8_t *data = mData;
00059         for( int32_t row = 0; row < mHeight; ++row ) {
00060             ((*this).*func)( target, row, data );
00061             data += mRowBytes;
00062         }
00063     }
00064     
00065     const uint8_t       *mData;
00066     int32_t             mRowBytes;
00067 };
00068 
00070 // ImageTargetCvMat
00071 inline ImageTargetCvMat::ImageTargetCvMat( cv::Mat *mat )
00072     : ImageTarget(), mMat( mat )
00073 {
00074     switch( mat->depth() ) {
00075         case CV_8U: setDataType( ImageIo::UINT8 ); break;
00076         case CV_16U: setDataType( ImageIo::UINT16 ); break;
00077         case CV_32F: setDataType( ImageIo::FLOAT32 ); break;
00078         default:
00079             throw ImageIoExceptionIllegalDataType();
00080     }
00081     
00082     switch( mat->channels() ) {
00083         case 1:
00084             setColorModel( ImageIo::CM_GRAY );
00085             setChannelOrder( ImageIo::Y );          
00086         break;
00087         case 3:
00088             setColorModel( ImageIo::CM_RGB );
00089             setChannelOrder( ImageIo::BGR );
00090         break;
00091         case 4:
00092             setColorModel( ImageIo::CM_RGB );
00093             setChannelOrder( ImageIo::BGRA );           
00094         break;
00095         default:
00096             throw ImageIoExceptionIllegalColorModel();
00097         break;
00098     }
00099 }
00100 
00101 inline cv::Mat toOcv( ci::ImageSourceRef sourceRef, int type = -1 )
00102 {
00103     if( type == -1 ) {
00104         int depth = CV_8U;
00105         if( sourceRef->getDataType() == ImageIo::UINT16 )
00106             depth = CV_16U;
00107         else if( sourceRef->getDataType() == ImageIo::FLOAT32 )
00108             depth = CV_32F;
00109         int channels = ImageIo::channelOrderNumChannels( sourceRef->getChannelOrder() );
00110         type = CV_MAKETYPE( depth, channels );
00111     }
00112     
00113     cv::Mat result( sourceRef->getHeight(), sourceRef->getWidth(), type );
00114     ImageTargetRef target = ImageTargetCvMat::createRef( &result );
00115     sourceRef->load( target );
00116     return result;
00117 }
00118 
00119 inline cv::Mat toOcvRef( Channel8u &channel )
00120 {
00121     return cv::Mat( channel.getHeight(), channel.getWidth(), CV_MAKETYPE( CV_8U, 1 ), channel.getData(), channel.getRowBytes() );
00122 }
00123 
00124 inline cv::Mat toOcvRef( Channel32f &channel )
00125 {
00126     return cv::Mat( channel.getHeight(), channel.getWidth(), CV_MAKETYPE( CV_32F, 1 ), channel.getData(), channel.getRowBytes() );
00127 }
00128 
00129 inline cv::Mat toOcvRef( Surface8u &surface )
00130 {
00131     return cv::Mat( surface.getHeight(), surface.getWidth(), CV_MAKETYPE( CV_8U, surface.hasAlpha()?4:3), surface.getData(), surface.getRowBytes() );
00132 }
00133 
00134 inline cv::Mat toOcvRef( Surface32f &surface )
00135 {
00136     return cv::Mat( surface.getHeight(), surface.getWidth(), CV_MAKETYPE( CV_32F, surface.hasAlpha()?4:3), surface.getData(), surface.getRowBytes() );
00137 }
00138 
00139 inline ImageSourceRef fromOcv( cv::Mat &mat )
00140 {
00141     return ImageSourceRef( new ImageSourceCvMat( mat ) );
00142 }
00143 
00144 inline cv::Scalar toOcv( const Color &color )
00145 {
00146     return CV_RGB( color.r * 255, color.g * 255, color.b * 255 );
00147 }
00148 
00149 inline Vec2f fromOcv( const cv::Point2f &point )
00150 {
00151     return Vec2f( point.x, point.y );
00152 }
00153 
00154 inline cv::Point2f toOcv( const Vec2f &point )
00155 {
00156     return cv::Point2f( point.x, point.y );
00157 }
00158 
00159 inline Vec2i fromOcv( const cv::Point &point )
00160 {
00161     return Vec2i( point.x, point.y );
00162 }
00163 
00164 inline cv::Point toOcv( const Vec2i &point )
00165 {
00166     return cv::Point( point.x, point.y );
00167 }
00168 
00169 inline cv::Rect toOcv( const ci::Area &r )
00170 {
00171     return cv::Rect( r.x1, r.y1, r.getWidth(), r.getHeight() );
00172 }
00173 
00174 inline ci::Area fromOcv( const cv::Rect &r )
00175 {
00176     return Area( r.x, r.y, r.x + r.width, r.y + r.height );
00177 }
00178 
00179 } // namespace cinder