libalvision
2.0.6.8
|
00001 00010 #ifndef LIBALVISION_ALVISION_ALIMAGE_OPENCV_H_ 00011 #define LIBALVISION_ALVISION_ALIMAGE_OPENCV_H_ 00012 00013 #include <cstring> // for std::memcpy 00014 #include <opencv2/core/core.hpp> 00015 00016 #include <alerror/alerror.h> 00017 00018 #include "alimage.h" 00019 #include "alvisiondefinitions.h" 00020 00021 namespace AL 00022 { 00029 static inline cv::Mat aLImageToCvMat(const AL::ALImage & al_image, int cv_type = -1) 00030 { 00031 // OpenCV does not take a const void* because the object could be modified later. This pointer will only be used 00032 // in a tmp local cv::Mat so it's fine 00033 unsigned char *data = const_cast<unsigned char*>(al_image.getData()); 00034 00035 if (cv_type >= 0) 00036 return cv::Mat(al_image.getHeight(), al_image.getWidth(), cv_type, data); 00037 00038 // Check the types 00039 int n_layers = AL::getNumLayersInColorSpace(al_image.getColorSpace()); 00040 int n_channels = AL::getNumChannelsInColorSpace(al_image.getColorSpace()); 00041 if ((n_layers < 0) || (n_channels < 0)) { 00042 std::stringstream ss; 00043 ss << "Color space \"" << al_image.getColorSpace() << "\" not supported"; 00044 throw AL::ALError("ALVision", "aLImageToCvMat", ss.str()); 00045 } 00046 int cv_depth; 00047 switch (n_layers / n_channels) 00048 { 00049 case 4: 00050 cv_depth = CV_32F; 00051 break; 00052 case 2: 00053 cv_depth = CV_16U; 00054 break; 00055 case 1: 00056 cv_depth = CV_8U; 00057 break; 00058 default: 00059 std::stringstream ss; 00060 ss << "Depth \"" << (n_layers / n_channels) << "\" not supported"; 00061 throw AL::ALError("ALVision", "aLImageToCvMat", ss.str()); 00062 } 00063 00064 return cv::Mat(al_image.getHeight(), al_image.getWidth(), 00065 CV_MAKETYPE(cv_depth, n_channels), data); 00066 } 00067 00074 static inline AL::ALImage* cvMatToALImage(const cv::Mat & img, int colorSpace, 00075 float pLeftAngle = 0.0f, float pTopAngle = 0.0f, 00076 float pRightAngle = 0.0f, float pBottomAngle = 0.0f) 00077 { 00078 // Check the number of channels 00079 if (AL::getNumChannelsInColorSpace(colorSpace) != img.channels()) 00080 throw AL::ALError("ALVision", "cvMatToALImage", 00081 "Channel number incompatibility between cv::Mat and colorSpace"); 00082 00083 // Check the type 00084 switch (img.depth()) 00085 { 00086 case CV_8U: 00087 case CV_16U: 00088 case CV_32F: 00089 break; 00090 default: 00091 throw AL::ALError("ALVision", "cvMatToALImage", 00092 "Type incompatibility between cv::Mat and colorSpace"); 00093 } 00094 00095 // Create an ALImage with the buffer 00096 AL::ALImage *al_image = new AL::ALImage(img.cols, img.rows, colorSpace, true, 00097 pLeftAngle, pTopAngle, pRightAngle, pBottomAngle); 00098 al_image->setData(img.data); 00099 00100 return al_image; 00101 } 00102 00108 static inline AL::ALImage* cvMatToALImageCopy(const cv::Mat & img, 00109 int colorSpace, 00110 float pLeftAngle = 0.0f, float pTopAngle = 0.0f, 00111 float pRightAngle = 0.0f, float pBottomAngle = 0.0f) 00112 { 00113 // Check the number of channels 00114 if (AL::getNumChannelsInColorSpace(colorSpace) != img.channels()) 00115 throw AL::ALError("ALVision", "cvMatToALImage", 00116 "Channel number incompatibility between cv::Mat and colorSpace"); 00117 00118 // Check the type 00119 switch (img.type()) 00120 { 00121 case CV_8U: 00122 case CV_16U: 00123 case CV_32F: 00124 break; 00125 default: 00126 throw AL::ALError("ALVision", "cvMatToALImage", 00127 "Type incompatibility between cv::Mat and colorSpace"); 00128 } 00129 00130 // Copy the image data in a buffer 00131 size_t data_size = img.cols * img.rows * img.elemSize(); 00132 unsigned char *data = new unsigned char[data_size]; 00133 std::memcpy(data, img.data, data_size); 00134 00135 // Create an ALImage with the buffer 00136 AL::ALImage *al_image = new AL::ALImage(img.cols, img.rows, colorSpace, false, 00137 pLeftAngle, pTopAngle, pRightAngle, pBottomAngle); 00138 al_image->setData(data); 00139 00140 return al_image; 00141 } 00142 } 00143 00144 #endif /* LIBALVISION_ALVISION_ALIMAGE_OPENCV_H_ */