-
Christof Kaufmann authoredChristof Kaufmann authored
image.cpp 100.26 KiB
#include <algorithm>
#include <numeric>
#include <type_traits>
#include <sstream>
#include "filesystem.h"
#include <gdal.h>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <gdal_utils.h>
#include <cpl_string.h>
#include "logging.h"
#include "image.h"
#include "geoinfo.h"
namespace {
template <typename Imgtype>
imagefusion::Image merge_impl(std::vector<Imgtype> const& images) {
std::vector<cv::Mat> cvImages;
cvImages.reserve(images.size());
for (auto const& i : images)
cvImages.push_back(i.cvMat()); // OpenCV shared copy
// unsigned int totalChannels = std::accumulate(images.begin(), images.end(), 0, [] (Imgtype const& i, unsigned int count) { return count + i.channels(); });
imagefusion::Image multichannel;
cv::merge(cvImages, multichannel.cvMat());
return multichannel;
}
std::string getGDALMemOptionString(imagefusion::ConstImage const& i) {
char szPtrValue[128] = { '\0' };
int nRet = CPLPrintPointer(szPtrValue,
reinterpret_cast<void*>(const_cast<uchar*>(i.cvMat().ptr())),
sizeof(szPtrValue));
szPtrValue[nRet] = 0;
std::ostringstream ss;
ss << "MEM:::DATAPOINTER=" << szPtrValue
<< ",PIXELS=" << i.width()
<< ",LINES=" << i.height()
<< ",BANDS=" << i.channels()
<< ",DATATYPE=" << GDALGetDataTypeName(toGDALDepth(i.type()))
<< ",PIXELOFFSET=" << i.cvMat().elemSize()
<< ",LINEOFFSET=" << i.cvMat().ptr(1) - i.cvMat().ptr(0)
<< ",BANDOFFSET=" << i.cvMat().elemSize1();
return ss.str();
}
} /* anonymous namespace */
namespace imagefusion {
// Implementation
GDALDataset const* ConstImage::asGDALDataset() const {
// This reads the OpenCV Mat as GDAL Dataset. See ConstImage::write for more info!
std::string optStr = getGDALMemOptionString(*this);
return (GDALDataset*) GDALOpen(optStr.c_str(), GA_ReadOnly);
}
GDALDataset* Image::asGDALDataset() {
// This reads the OpenCV Mat as GDAL Dataset. See ConstImage::write for more info!
std::string optStr = getGDALMemOptionString(*this);
return (GDALDataset*) GDALOpen(optStr.c_str(), GA_Update);
}