diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index e21db8e1e5..04dcdb3c9e 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -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 diff --git a/modules/imgcodecs/src/grfmt_gdal.cpp b/modules/imgcodecs/src/grfmt_gdal.cpp index 55dd7192f6..9951dac573 100644 --- a/modules/imgcodecs/src/grfmt_gdal.cpp +++ b/modules/imgcodecs/src/grfmt_gdal.cpp @@ -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(row,col) = newValue; } - else if( image.depth() == CV_16U ){ image.at(row,col) = newValue; } - else if( image.depth() == CV_16S ){ image.at(row,col) = newValue; } - else if( image.depth() == CV_32S ){ image.at(row,col) = newValue; } - else if( image.depth() == CV_32F ){ image.at(row,col) = newValue; } - else if( image.depth() == CV_64F ){ image.at(row,col) = newValue; } + if( image.depth() == CV_8U ){ image.ptr(row)[col] = newValue; } + else if( image.depth() == CV_16U ){ image.ptr(row)[col] = newValue; } + else if( image.depth() == CV_16S ){ image.ptr(row)[col] = newValue; } + else if( image.depth() == CV_32S ){ image.ptr(row)[col] = newValue; } + else if( image.depth() == CV_32F ){ image.ptr(row)[col] = newValue; } + else if( image.depth() == CV_64F ){ image.ptr(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(row,col) = Vec3b(newValue,newValue,newValue); } - else if( image.depth() == CV_16U ){ image.at(row,col) = Vec3s(newValue,newValue,newValue); } - else if( image.depth() == CV_16S ){ image.at(row,col) = Vec3s(newValue,newValue,newValue); } - else if( image.depth() == CV_32S ){ image.at(row,col) = Vec3i(newValue,newValue,newValue); } - else if( image.depth() == CV_32F ){ image.at(row,col) = Vec3f(newValue,newValue,newValue); } - else if( image.depth() == CV_64F ){ image.at(row,col) = Vec3d(newValue,newValue,newValue); } + if( image.depth() == CV_8U ){ image.ptr(row)[col] = Vec3b(newValue,newValue,newValue); } + else if( image.depth() == CV_16U ){ image.ptr(row)[col] = Vec3s(newValue,newValue,newValue); } + else if( image.depth() == CV_16S ){ image.ptr(row)[col] = Vec3s(newValue,newValue,newValue); } + else if( image.depth() == CV_32S ){ image.ptr(row)[col] = Vec3i(newValue,newValue,newValue); } + else if( image.depth() == CV_32F ){ image.ptr(row)[col] = Vec3f(newValue,newValue,newValue); } + else if( image.depth() == CV_64F ){ image.ptr(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(row,col) += (newValue/3.0); } + if( image.depth() == CV_8U ){ image.ptr(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(row,col) = newValue; } + if( image.depth() == CV_8U ){ image.ptr(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(row,col)[channel] = newValue; } - else if( image.depth() == CV_16U ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_16S ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_32S ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_32F ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_64F ){ image.at(row,col)[channel] = newValue; } + else if( image.depth() == CV_16U ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_16S ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_32S ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_32F ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_64F ){ image.ptr(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(row,col)[channel] = newValue; } - else if( image.depth() == CV_16U && channel < 4 ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_16S && channel < 4 ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_32S && channel < 4 ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_32F && channel < 4 ){ image.at(row,col)[channel] = newValue; } - else if( image.depth() == CV_64F && channel < 4 ){ image.at(row,col)[channel] = newValue; } + else if( image.depth() == CV_8U && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_16U && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_16S && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_32S && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_32F && channel < 4 ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_64F && channel < 4 ){ image.ptr(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(row,col)[channel] = newValue; } + else if( image.depth() == CV_16U ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_16S ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_32S ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_32F ){ image.ptr(row,col)[channel] = newValue; } + else if( image.depth() == CV_64F ){ image.ptr(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 diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index a7bf46f427..5df1ea2148 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -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& 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