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
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
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 }