load multi/hyperspectral images with using gdal
authoredgarriba <edgar.riba@gmail.com>
Wed, 14 Oct 2015 07:16:04 +0000 (09:16 +0200)
committeredgarriba <edgar.riba@gmail.com>
Wed, 14 Oct 2015 07:16:04 +0000 (09:16 +0200)
modules/imgcodecs/include/opencv2/imgcodecs.hpp
modules/imgcodecs/src/grfmt_gdal.cpp
modules/imgcodecs/src/loadsave.cpp

index e21db8e..04dcdb3 100644 (file)
@@ -115,6 +115,7 @@ returns an empty matrix ( Mat::data==NULL ). Currently, the following file forma
 -   TIFF files - \*.tiff, \*.tif (see the *Notes* section)
 -   OpenEXR Image files - \*.exr (see the *Notes* section)
 -   Radiance HDR - \*.hdr, \*.pic (always supported)
+-   Raster and Vector geospatial data supported by Gdal (see the *Notes* section)
 
 @note
 
@@ -128,6 +129,10 @@ returns an empty matrix ( Mat::data==NULL ). Currently, the following file forma
     codecs supplied with an OS image. Install the relevant packages (do not forget the development
     files, for example, "libjpeg-dev", in Debian\* and Ubuntu\*) to get the codec support or turn
     on the OPENCV_BUILD_3RDPARTY_LIBS flag in CMake.
+-   In the case you set *WITH_GDAL* flag to true in CMake and @ref IMREAD_LOAD_GDAL to load the image,
+    then [GDAL](http://www.gdal.org) driver will be used in order to decode the image by supporting
+    the following formats: [Raster](http://www.gdal.org/formats_list.html),
+    [Vector](http://www.gdal.org/ogr_formats.html).
 
 @note In the case of color images, the decoded images will have the channels stored in B G R order.
  */
@@ -257,4 +262,4 @@ CV_EXPORTS_W bool imencode( const String& ext, InputArray img,
 
 } // cv
 
-#endif //__OPENCV_IMGCODECS_HPP__
+#endif //__OPENCV_IMGCODECS_HPP__
\ No newline at end of file
index 55dd719..9951dac 100644 (file)
@@ -107,6 +107,7 @@ int gdal2opencv( const GDALDataType& gdalType, const int& channels ){
             if( channels == 1 ){ return CV_8UC1; }
             if( channels == 3 ){ return CV_8UC3; }
             if( channels == 4 ){ return CV_8UC4; }
+            else { return CV_8UC(channels); }
             return -1;
 
         /// UInt16
@@ -114,6 +115,7 @@ int gdal2opencv( const GDALDataType& gdalType, const int& channels ){
             if( channels == 1 ){ return CV_16UC1; }
             if( channels == 3 ){ return CV_16UC3; }
             if( channels == 4 ){ return CV_16UC4; }
+            else { return CV_16UC(channels); }
             return -1;
 
         /// Int16
@@ -121,6 +123,7 @@ int gdal2opencv( const GDALDataType& gdalType, const int& channels ){
             if( channels == 1 ){ return CV_16SC1; }
             if( channels == 3 ){ return CV_16SC3; }
             if( channels == 4 ){ return CV_16SC4; }
+            else { return CV_16SC(channels); }
             return -1;
 
         /// UInt32
@@ -129,6 +132,7 @@ int gdal2opencv( const GDALDataType& gdalType, const int& channels ){
             if( channels == 1 ){ return CV_32SC1; }
             if( channels == 3 ){ return CV_32SC3; }
             if( channels == 4 ){ return CV_32SC4; }
+            else { return CV_32SC(channels); }
             return -1;
 
         default:
@@ -225,58 +229,58 @@ void write_pixel( const double& pixelValue,
 
     // input: 1 channel, output: 1 channel
     if( gdalChannels == 1 && image.channels() == 1 ){
-        if( image.depth() == CV_8U ){       image.at<uchar>(row,col)          = newValue; }
-        else if( image.depth() == CV_16U ){ image.at<unsigned short>(row,col) = newValue; }
-        else if( image.depth() == CV_16S ){ image.at<short>(row,col)          = newValue; }
-        else if( image.depth() == CV_32S ){ image.at<int>(row,col)            = newValue; }
-        else if( image.depth() == CV_32F ){ image.at<float>(row,col)          = newValue; }
-        else if( image.depth() == CV_64F ){ image.at<double>(row,col)         = newValue; }
+        if( image.depth() == CV_8U ){       image.ptr<uchar>(row)[col]          = newValue; }
+        else if( image.depth() == CV_16U ){ image.ptr<unsigned short>(row)[col] = newValue; }
+        else if( image.depth() == CV_16S ){ image.ptr<short>(row)[col]          = newValue; }
+        else if( image.depth() == CV_32S ){ image.ptr<int>(row)[col]            = newValue; }
+        else if( image.depth() == CV_32F ){ image.ptr<float>(row)[col]          = newValue; }
+        else if( image.depth() == CV_64F ){ image.ptr<double>(row)[col]         = newValue; }
         else{ throw std::runtime_error("Unknown image depth, gdal: 1, img: 1"); }
     }
 
     // input: 1 channel, output: 3 channel
     else if( gdalChannels == 1 && image.channels() == 3 ){
-        if( image.depth() == CV_8U ){   image.at<Vec3b>(row,col) = Vec3b(newValue,newValue,newValue); }
-        else if( image.depth() == CV_16U ){  image.at<Vec3s>(row,col) = Vec3s(newValue,newValue,newValue); }
-        else if( image.depth() == CV_16S ){  image.at<Vec3s>(row,col) = Vec3s(newValue,newValue,newValue); }
-        else if( image.depth() == CV_32S ){  image.at<Vec3i>(row,col) = Vec3i(newValue,newValue,newValue); }
-        else if( image.depth() == CV_32F ){  image.at<Vec3f>(row,col) = Vec3f(newValue,newValue,newValue); }
-        else if( image.depth() == CV_64F ){  image.at<Vec3d>(row,col) = Vec3d(newValue,newValue,newValue); }
+        if( image.depth() == CV_8U ){        image.ptr<Vec3b>(row)[col] = Vec3b(newValue,newValue,newValue); }
+        else if( image.depth() == CV_16U ){  image.ptr<Vec3s>(row)[col] = Vec3s(newValue,newValue,newValue); }
+        else if( image.depth() == CV_16S ){  image.ptr<Vec3s>(row)[col] = Vec3s(newValue,newValue,newValue); }
+        else if( image.depth() == CV_32S ){  image.ptr<Vec3i>(row)[col] = Vec3i(newValue,newValue,newValue); }
+        else if( image.depth() == CV_32F ){  image.ptr<Vec3f>(row)[col] = Vec3f(newValue,newValue,newValue); }
+        else if( image.depth() == CV_64F ){  image.ptr<Vec3d>(row)[col] = Vec3d(newValue,newValue,newValue); }
         else{                          throw std::runtime_error("Unknown image depth, gdal:1, img: 3"); }
     }
 
     // input: 3 channel, output: 1 channel
     else if( gdalChannels == 3 && image.channels() == 1 ){
-        if( image.depth() == CV_8U ){   image.at<uchar>(row,col) += (newValue/3.0); }
+        if( image.depth() == CV_8U ){   image.ptr<uchar>(row)[col] += (newValue/3.0); }
         else{ throw std::runtime_error("Unknown image depth, gdal:3, img: 1"); }
     }
 
     // input: 4 channel, output: 1 channel
     else if( gdalChannels == 4 && image.channels() == 1 ){
-        if( image.depth() == CV_8U ){   image.at<uchar>(row,col) = newValue;  }
+        if( image.depth() == CV_8U ){   image.ptr<uchar>(row)[col] = newValue;  }
         else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 1"); }
     }
 
     // input: 3 channel, output: 3 channel
     else if( gdalChannels == 3 && image.channels() == 3 ){
         if( image.depth() == CV_8U ){  image.at<Vec3b>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_16U ){  image.at<Vec3s>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_16S ){  image.at<Vec3s>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_32S ){  image.at<Vec3i>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_32F ){  image.at<Vec3f>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_64F ){  image.at<Vec3d>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_16U ){  image.ptr<Vec3s>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_16S ){  image.ptr<Vec3s>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_32S ){  image.ptr<Vec3i>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_32F ){  image.ptr<Vec3f>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_64F ){  image.ptr<Vec3d>(row,col)[channel] = newValue;  }
         else{ throw std::runtime_error("Unknown image depth, gdal: 3, image: 3"); }
     }
 
     // input: 4 channel, output: 3 channel
     else if( gdalChannels == 4 && image.channels() == 3 ){
         if( channel >= 4 ){ return; }
-        else if( image.depth() == CV_8U  && channel < 4  ){  image.at<Vec3b>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_16U && channel < 4 ){  image.at<Vec3s>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_16S && channel < 4 ){  image.at<Vec3s>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_32S && channel < 4 ){  image.at<Vec3i>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_32F && channel < 4 ){  image.at<Vec3f>(row,col)[channel] = newValue;  }
-        else if( image.depth() == CV_64F && channel < 4 ){  image.at<Vec3d>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_8U  && channel < 4 ){  image.ptr<Vec3b>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_16U && channel < 4 ){  image.ptr<Vec3s>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_16S && channel < 4 ){  image.ptr<Vec3s>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_32S && channel < 4 ){  image.ptr<Vec3i>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_32F && channel < 4 ){  image.ptr<Vec3f>(row,col)[channel] = newValue;  }
+        else if( image.depth() == CV_64F && channel < 4 ){  image.ptr<Vec3d>(row,col)[channel] = newValue;  }
         else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 3"); }
     }
 
@@ -286,6 +290,16 @@ void write_pixel( const double& pixelValue,
         else{ throw std::runtime_error("Unknown image depth, gdal: 4, image: 4"); }
     }
 
+    // input: > 4 channels, output: > 4 channels
+    else if( gdalChannels > 4 && image.channels() > 4 ){
+        if( image.depth() == CV_8U ){       image.ptr<uchar>(row,col)[channel]          = newValue; }
+        else if( image.depth() == CV_16U ){ image.ptr<unsigned short>(row,col)[channel] = newValue; }
+        else if( image.depth() == CV_16S ){ image.ptr<short>(row,col)[channel]          = newValue; }
+        else if( image.depth() == CV_32S ){ image.ptr<int>(row,col)[channel]            = newValue; }
+        else if( image.depth() == CV_32F ){ image.ptr<float>(row,col)[channel]          = newValue; }
+        else if( image.depth() == CV_64F ){ image.ptr<double>(row,col)[channel]         = newValue; }
+        else{ throw std::runtime_error("Unknown image depth, gdal: N, img: N"); }
+    }
     // otherwise, throw an error
     else{
         throw std::runtime_error("error: can't convert types.");
@@ -362,6 +376,7 @@ bool GdalDecoder::readData( Mat& img ){
     // iterate over each raster band
     // note that OpenCV does bgr rather than rgb
     int nChannels = m_dataset->GetRasterCount();
+
     GDALColorTable* gdalColorTable = NULL;
     if( m_dataset->GetRasterBand(1)->GetColorTable() != NULL ){
         gdalColorTable = m_dataset->GetRasterBand(1)->GetColorTable();
@@ -538,4 +553,4 @@ bool GdalDecoder::checkSignature( const String& signature )const{
 
 } /// End of cv Namespace
 
-#endif /**< End  of HAVE_GDAL Definition */
+#endif /**< End  of HAVE_GDAL Definition */
\ No newline at end of file
index a7bf46f..5df1ea2 100644 (file)
@@ -279,7 +279,7 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0, int scale_d
 
     // grab the decoded type
     int type = decoder->type();
-    if( flags != IMREAD_UNCHANGED )
+    if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
     {
         if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 )
             type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
@@ -372,7 +372,7 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
     {
         // grab the decoded type
         int type = decoder->type();
-        if (flags != IMREAD_UNCHANGED)
+        if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
         {
             if ((flags & CV_LOAD_IMAGE_ANYDEPTH) == 0)
                 type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
@@ -532,7 +532,7 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
     size.height = decoder->height();
 
     int type = decoder->type();
-    if( flags != IMREAD_UNCHANGED )
+    if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
     {
         if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 )
             type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
@@ -736,4 +736,4 @@ cvEncodeImage( const char* ext, const CvArr* arr, const int* _params )
     return _buf;
 }
 
-/* End of file. */
+/* End of file. */
\ No newline at end of file