From 420ccf85f759a2e8ebd42b37906ac214dc53229a Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Wed, 28 Oct 2020 18:26:12 -0400 Subject: [PATCH 01/25] Started adding 16bit and 32bit support for tiff --- libs/IO/Image.cpp | 4 ++++ libs/IO/Image.h | 19 ++++++++++++++++++ libs/IO/ImageTIFF.cpp | 46 +++++++++++++++++++++++++++++-------------- libs/IO/ImageTIFF.h | 7 +++++++ 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 3d3e1cecb..1e16a9bae 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -194,6 +194,8 @@ CImage::Size CImage::GetStride(PIXELFORMAT pixFormat) { case PF_A8: case PF_GRAY8: + case PF_GRAYU16: + case PF_GRAYF32: return 1; case PF_R5G6B5: return 2; @@ -237,6 +239,8 @@ bool CImage::FormatHasAlpha(PIXELFORMAT format) case PF_DXT5: return true; case PF_GRAY8: + case PF_GRAYU16: + case PF_GRAYF32: case PF_R5G6B5: case PF_B8G8R8: case PF_R8G8B8: diff --git a/libs/IO/Image.h b/libs/IO/Image.h index 44acd5616..95360f192 100644 --- a/libs/IO/Image.h +++ b/libs/IO/Image.h @@ -32,6 +32,8 @@ typedef enum PIXELFORMAT_TYPE { // gray PF_A8, PF_GRAY8, + PF_GRAYU16, // unsigned 16 + PF_GRAYF32, // float 32 // uncompressed RGB PF_R5G6B5, PF_R8G8B8, @@ -107,6 +109,22 @@ class IO_API CImage #endif protected: + template + void findMinMax(void *data, Size size, T* min, T* max){ + if (size == 0){ + *min = *max = 0; + return; + } + + T *p = reinterpret_cast(data); + *min = *max = p[0]; + + for (Size i = 1; i < size; i++){ + if (p[i] > *max) *max = p[i]; + if (p[i] < *min) *min = p[i]; + } + } + IOSTREAMPTR m_pStream; // stream used to read/write the image data CAutoPtrArr m_data; // image's data buffer Size m_width; // image width in pixels @@ -125,4 +143,5 @@ typedef CSharedPtr IMAGEPTR; } // namespace SEACAVE + #endif // __SEACAVE_IMAGE_H__ diff --git a/libs/IO/ImageTIFF.cpp b/libs/IO/ImageTIFF.cpp index bfdd7e177..ad236478e 100644 --- a/libs/IO/ImageTIFF.cpp +++ b/libs/IO/ImageTIFF.cpp @@ -393,14 +393,16 @@ HRESULT CImageTIFF::ReadHeader() TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &m_height) && TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { - uint16 bpp=8, ncn = photometric > 1 ? 3 : 1; + uint16 bpp=8, ncn = photometric > 1 ? 3 : 1, sampleFormat = 1; TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn); + TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat); m_dataWidth = m_width; m_dataHeight= m_height; m_numLevels = 0; m_level = 0; + m_stride = ncn; if ((bpp == 32 && ncn == 3) || photometric == PHOTOMETRIC_LOGLUV) { // this is HDR format with 3 floats per pixel @@ -413,27 +415,34 @@ HRESULT CImageTIFF::ReadHeader() ((photometric != 2 && photometric != 1) || (ncn != 1 && ncn != 3 && ncn != 4))) bpp = 8; - switch (bpp) { + + bool implemented = true; + + switch (bpp){ case 8: - m_stride = 4; - m_format = PF_B8G8R8A8; + if (ncn == 4) m_format = PF_B8G8R8A8; + else if (ncn == 3) m_format = PF_B8G8R8; + else m_format = PF_GRAY8; break; - //case 16: - // m_type = CV_MAKETYPE(CV_16U, photometric > 1 ? 3 : 1); - // break; - //case 32: - // m_type = CV_MAKETYPE(CV_32F, photometric > 1 ? 3 : 1); - // break; - //case 64: - // m_type = CV_MAKETYPE(CV_64F, photometric > 1 ? 3 : 1); - // break; + case 16: + m_format = PF_GRAYU16; + if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_UINT) implemented = false; + break; + case 32: + m_format = PF_GRAYF32; + if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) implemented = false; + break; default: - //TODO: implement + // TODO: implement support for more + implemented = false; + } + + if (!implemented){ ASSERT("error: not implemented" == NULL); LOG(LT_IMAGE, "error: unsupported TIFF image"); Close(); return _INVALIDFILE; - } + } m_lineWidth = m_width * m_stride; return _OK; @@ -460,6 +469,7 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, if (dst_bpp == 8) { char errmsg[1024]; if (!TIFFRGBAImageOK(tif, errmsg)) { + std::cerr << "IMAGE NOT OK!" << std::endl; // TODO: REMOVE Close(); return _INVALIDFILE; } @@ -494,6 +504,10 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, CLISTDEF0(uint8_t) _buffer(buffer_size); uint8_t* buffer = _buffer.Begin(); + // TODO: rewrite this http://web.mit.edu/Graphics/src/tiff-v3.6.1/html/man/TIFFReadRGBAStrip.3t.html + // TIFFReadRGBAImage + // TIFFReadRGBATile + for (uint32_t y = 0; y < m_height; y += tile_height0, data += lineWidth*tile_height0) { uint32_t tile_height = tile_height0; if (y + tile_height > m_height) @@ -509,6 +523,8 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, case 8: { uint8_t* bstart = buffer; + + if (m_format ) if (!is_tiled) ok = TIFFReadRGBAStrip(tif, y, (uint32_t*)buffer); else { diff --git a/libs/IO/ImageTIFF.h b/libs/IO/ImageTIFF.h index f3eb743a5..733f8898c 100644 --- a/libs/IO/ImageTIFF.h +++ b/libs/IO/ImageTIFF.h @@ -21,6 +21,13 @@ namespace SEACAVE { // S T R U C T S /////////////////////////////////////////////////// +// https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html +enum TIFF_SAMPLEFORMAT_TYPE { + TIFF_SAMPLEFORMAT_UINT = 1, + TIFF_SAMPLEFORMAT_INT = 2, + TIFF_SAMPLEFORMAT_IEEEFP = 3 +}; + class IO_API CImageTIFF : public CImage { public: From 80a783ddb1e5021a410e95bb77bf35d0817f3635 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Fri, 30 Oct 2020 14:15:36 +0000 Subject: [PATCH 02/25] Read TIFF refactoring --- libs/IO/ImageTIFF.cpp | 118 +++++++++++------------------------------- 1 file changed, 29 insertions(+), 89 deletions(-) diff --git a/libs/IO/ImageTIFF.cpp b/libs/IO/ImageTIFF.cpp index ad236478e..fe1a7d616 100644 --- a/libs/IO/ImageTIFF.cpp +++ b/libs/IO/ImageTIFF.cpp @@ -6,7 +6,7 @@ // (See http://www.boost.org/LICENSE_1_0.txt) #include "Common.h" - +#define _IMAGE_TIFF 1 // TODO REMOVE #ifdef _IMAGE_TIFF #include "ImageTIFF.h" @@ -420,16 +420,24 @@ HRESULT CImageTIFF::ReadHeader() switch (bpp){ case 8: - if (ncn == 4) m_format = PF_B8G8R8A8; - else if (ncn == 3) m_format = PF_B8G8R8; - else m_format = PF_GRAY8; + if (ncn >= 3){ + m_format = PF_B8G8R8A8; + m_stride = 4; + }else if (ncn == 1){ + m_format = PF_GRAY8; + m_stride = 1; + }else{ + implemented = false; + } break; case 16: m_format = PF_GRAYU16; + m_stride = 1; if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_UINT) implemented = false; break; case 32: m_format = PF_GRAYF32; + m_stride = 1; if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) implemented = false; break; default: @@ -457,8 +465,6 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, { if (m_state && m_width && m_height) { TIFF* tif = (TIFF*)m_state; - uint32_t tile_width0 = m_width, tile_height0 = 0; - int is_tiled = TIFFIsTiled(tif); uint16 photometric; TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric); uint16 bpp = 8, ncn = photometric > 1 ? 3 : 1; @@ -475,90 +481,24 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, } } - if ((!is_tiled) || - (is_tiled && - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width0) && - TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height0))) - { - if (!is_tiled) - TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &tile_height0); - - if (tile_width0 <= 0) - tile_width0 = m_width; - - if (tile_height0 <= 0 || - (!is_tiled && tile_height0 == std::numeric_limits::max())) - tile_height0 = m_height; - - uint8_t* data = (uint8_t*)pData; - if (!is_tiled && tile_height0 == 1 && dataFormat == m_format && nStride == m_stride) { - // read image directly to the data buffer - for (Size j=0; j m_height) - tile_height = m_height - y; - - for (uint32_t x = 0; x < m_width; x += tile_width0) { - uint32_t tile_width = tile_width0; - if (x + tile_width > m_width) - tile_width = m_width - x; - - int ok; - switch (dst_bpp) { - case 8: - { - uint8_t* bstart = buffer; - - if (m_format ) - if (!is_tiled) - ok = TIFFReadRGBAStrip(tif, y, (uint32_t*)buffer); - else { - ok = TIFFReadRGBATile(tif, x, y, (uint32_t*)buffer); - //Tiles fill the buffer from the bottom up - bstart += (tile_height0 - tile_height) * tile_width0 * 4; - } - if (!ok) { - Close(); - return _INVALIDFILE; - } - - for (uint32_t i = 0; i < tile_height; ++i) { - uint8_t* dst = data + x*3 + lineWidth*(tile_height - i - 1); - uint8_t* src = bstart + i*tile_width0*4; - if (!FilterFormat(dst, dataFormat, nStride, src, m_format, m_stride, tile_width)) { - Close(); - return _FAIL; - } - } - break; - } - default: - { - Close(); - return _INVALIDFILE; - } - } - } - } - } + uint8_t* data = (uint8_t*)pData; - return _OK; - } + // read image to a buffer and convert it + const size_t buffer_size = m_stride * m_width * m_height; + CLISTDEF0(uint8_t) _buffer(buffer_size); + uint8_t* buffer = _buffer.Begin(); + + if (!TIFFReadRGBAImage(tif, m_width, m_height, (uint32*)buffer, 0)){ + Close(); + return _INVALIDFILE; + } + + if (!FilterFormat(data, dataFormat, nStride, buffer, m_format, m_stride, m_width * m_height)) { + Close(); + return _FAIL; + } + + return _OK; } Close(); From 638cbfa6afd306faca00bc3bfe7eb1e6be0294e9 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Fri, 30 Oct 2020 20:07:54 +0000 Subject: [PATCH 03/25] Reading grayscale 16bit tiffs --- libs/IO/Image.cpp | 14 ++++++++++++++ libs/IO/ImageTIFF.cpp | 34 +++++++++++++++++++++++----------- libs/MVS/Scene.cpp | 1 + 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 1e16a9bae..082ea6601 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -413,6 +413,20 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con ((uint8_t*)pDst)[2] = ((uint8_t*)pSrc)[1]; } return true; + + case PF_GRAYU16: + // from PF_GRAYU16 to PF_R8G8B8 + + for (Size i=0; i Date: Mon, 2 Nov 2020 20:31:57 +0000 Subject: [PATCH 04/25] Percentile min/max scaling, fixes --- libs/IO/Image.cpp | 14 +++++++++----- libs/IO/Image.h | 35 +++++++++++++++++++++++++++++++---- libs/MVS/Scene.cpp | 1 - 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 082ea6601..8a583bda4 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -417,13 +417,17 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con case PF_GRAYU16: // from PF_GRAYU16 to PF_R8G8B8 + uint16_t min, max; + uint16_t *pData = (uint16_t*)pSrc; + findMinMaxPercentile(pData, nSzize, &min, &max); + for (Size i=0; i - void findMinMax(void *data, Size size, T* min, T* max){ + static void findMinMaxPercentile(void *data, Size size, T* min, T* max){ if (size == 0){ *min = *max = 0; return; } + // Find min/max T *p = reinterpret_cast(data); - *min = *max = p[0]; + T aMin = p[0]; + T aMax = p[0]; for (Size i = 1; i < size; i++){ - if (p[i] > *max) *max = p[i]; - if (p[i] < *min) *min = p[i]; + if (p[i] > aMax) aMax = p[i]; + if (p[i] < aMin) aMin = p[i]; + } + + double range = static_cast(aMax - aMin); + if (range == 0){ + *min = *max = 0; + return; + } + + double closestMinP = 9999.0; + double closestMaxP = 9999.0; + + // Get min/max values at the 10th and 90th percentile + for (Size i = 0; i < size; i++){ + double percentile = (static_cast(p[i]) - static_cast(aMin)) / range; + double minP = abs(percentile - 0.1); + double maxP = abs(percentile - 0.9); + + if (minP < closestMinP){ + *min = p[i]; + closestMinP = minP; + } + if (maxP < closestMaxP){ + *max = p[i]; + closestMaxP = maxP; + } } } diff --git a/libs/MVS/Scene.cpp b/libs/MVS/Scene.cpp index 517e8bb1e..4943cf4af 100644 --- a/libs/MVS/Scene.cpp +++ b/libs/MVS/Scene.cpp @@ -926,7 +926,6 @@ bool Scene::SelectNeighborViews(uint32_t ID, IndexArr& points, unsigned nMinView } #endif } - std::cerr << nMinViews << " , " << neighbors.size() << std::endl; if (points.size() <= 3 || neighbors.size() < MINF(nMinViews,nCalibratedImages-1)) { DEBUG_EXTRA("error: reference image %3u has not enough images in view", ID); return false; From ba552d57dce8cd9a161ba5a08944957d75fbc0c8 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 2 Nov 2020 20:45:29 +0000 Subject: [PATCH 05/25] Support for 32bit float TIFFs --- libs/IO/Image.cpp | 53 +++++++++++----- libs/IO/ImageTIFF.cpp | 136 ++++++++++++++++++++---------------------- 2 files changed, 103 insertions(+), 86 deletions(-) diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 8a583bda4..09e55f6ae 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -194,8 +194,8 @@ CImage::Size CImage::GetStride(PIXELFORMAT pixFormat) { case PF_A8: case PF_GRAY8: - case PF_GRAYU16: - case PF_GRAYF32: + case PF_GRAYU16: + case PF_GRAYF32: return 1; case PF_R5G6B5: return 2; @@ -239,8 +239,8 @@ bool CImage::FormatHasAlpha(PIXELFORMAT format) case PF_DXT5: return true; case PF_GRAY8: - case PF_GRAYU16: - case PF_GRAYF32: + case PF_GRAYU16: + case PF_GRAYF32: case PF_R5G6B5: case PF_B8G8R8: case PF_R8G8B8: @@ -414,24 +414,45 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con } return true; - case PF_GRAYU16: - // from PF_GRAYU16 to PF_R8G8B8 - - uint16_t min, max; - uint16_t *pData = (uint16_t*)pSrc; - findMinMaxPercentile(pData, nSzize, &min, &max); + case PF_GRAYU16:{ + // from PF_GRAYU16 to PF_R8G8B8 + + uint16_t min, max; + uint16_t *pData = (uint16_t*)pSrc; + findMinMaxPercentile(pData, nSzize, &min, &max); for (Size i=0; i 1 ? 3 : 1, sampleFormat = 1; TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat); + TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat); m_dataWidth = m_width; m_dataHeight= m_height; m_numLevels = 0; m_level = 0; - m_stride = ncn; + m_stride = ncn; if ((bpp == 32 && ncn == 3) || photometric == PHOTOMETRIC_LOGLUV) { // this is HDR format with 3 floats per pixel @@ -416,41 +416,41 @@ HRESULT CImageTIFF::ReadHeader() (ncn != 1 && ncn != 3 && ncn != 4))) bpp = 8; - bool implemented = true; + bool implemented = true; switch (bpp){ case 8: - if (ncn >= 3){ - m_format = PF_B8G8R8A8; - m_stride = 4; - }else if (ncn == 1){ - m_format = PF_GRAY8; - m_stride = 1; - }else{ - implemented = false; - } + if (ncn >= 3){ + m_format = PF_B8G8R8A8; + m_stride = 4; + }else if (ncn == 1){ + m_format = PF_GRAY8; + m_stride = 1; + }else{ + implemented = false; + } + break; + case 16: + m_format = PF_GRAYU16; + m_stride = 2; + if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_UINT) implemented = false; + break; + case 32: + m_format = PF_GRAYF32; + m_stride = 4; + if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) implemented = false; break; - case 16: - m_format = PF_GRAYU16; - m_stride = 2; - if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_UINT) implemented = false; - break; - case 32: - m_format = PF_GRAYF32; - m_stride = 4; - if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) implemented = false; - break; default: - // TODO: implement support for more - implemented = false; + // TODO: implement support for more + implemented = false; } - if (!implemented){ + if (!implemented){ ASSERT("error: not implemented" == NULL); LOG(LT_IMAGE, "error: unsupported TIFF image"); Close(); return _INVALIDFILE; - } + } m_lineWidth = m_width * m_stride; return _OK; @@ -470,47 +470,43 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, uint16 bpp = 8, ncn = photometric > 1 ? 3 : 1; TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bpp); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn); - const int bitsPerByte = 8; - int dst_bpp = (int)(1 * bitsPerByte); - if (dst_bpp == 8) { + + const size_t buffer_size = m_stride * m_width * m_height; + CLISTDEF0(uint8_t) _buffer(buffer_size); + uint8_t* buffer = _buffer.Begin(); + + if (m_format == PF_B8G8R8A8 || m_format == PF_GRAY8){ char errmsg[1024]; if (!TIFFRGBAImageOK(tif, errmsg)) { - std::cerr << "IMAGE NOT OK!" << std::endl; // TODO: REMOVE Close(); return _INVALIDFILE; } + + // Simplified + if (!TIFFReadRGBAImageOriented(tif, m_width, m_height, (uint32*)buffer, ORIENTATION_TOPLEFT, 0)){ + Close(); + return _INVALIDFILE; + } + }else if (m_format == PF_GRAYU16 || m_format == PF_GRAYF32){ + for (uint32 y = 0; y < m_height; y++, buffer += m_lineWidth){ + if (!TIFFReadScanline(tif, buffer, y, 0)){ + Close(); + return _INVALIDFILE; + } + } + + buffer = _buffer.Begin(); } - const size_t buffer_size = m_stride * m_width * m_height; - CLISTDEF0(uint8_t) _buffer(buffer_size); - uint8_t* buffer = _buffer.Begin(); - - if (m_format == PF_B8G8R8A8 || m_format == PF_GRAY8){ - // Simplified - if (!TIFFReadRGBAImageOriented(tif, m_width, m_height, (uint32*)buffer, ORIENTATION_TOPLEFT, 0)){ - Close(); - return _INVALIDFILE; - } - }else if (m_format == PF_GRAYU16){ - for (uint32 y = 0; y < m_height; y++, buffer += m_lineWidth){ - if (!TIFFReadScanline(tif, buffer, y, 0)){ - Close(); - return _INVALIDFILE; - } - } - - buffer = _buffer.Begin(); - } - - // Data not in the format we need? - if (dataFormat != m_format || nStride != m_stride){ - if (!FilterFormat(pData, dataFormat, nStride, buffer, m_format, m_stride, m_width * m_height)) { - Close(); - return _FAIL; - } - } - - return _OK; + // Data not in the format we need? + if (dataFormat != m_format || nStride != m_stride){ + if (!FilterFormat(pData, dataFormat, nStride, buffer, m_format, m_stride, m_width * m_height)) { + Close(); + return _FAIL; + } + } + + return _OK; } Close(); From cee37b053837981cd05a974dff2a53c592e8588c Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 2 Nov 2020 20:49:16 +0000 Subject: [PATCH 06/25] Fix tabs --- libs/IO/ImageTIFF.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/libs/IO/ImageTIFF.cpp b/libs/IO/ImageTIFF.cpp index 57f91830e..4f971af41 100644 --- a/libs/IO/ImageTIFF.cpp +++ b/libs/IO/ImageTIFF.cpp @@ -29,40 +29,30 @@ using namespace SEACAVE; /* ISO C++ uses a 'std::streamsize' type to define counts. This makes it similar to, (but perhaps not the same as) size_t. - The std::ios::pos_type is used to represent stream positions as used by tellg(), tellp(), seekg(), and seekp(). This makes it similar to (but perhaps not the same as) 'off_t'. The std::ios::streampos type is used for character streams, but is documented to not be an integral type anymore, so it should *not* be assigned to an integral type. - The std::ios::off_type is used to specify relative offsets needed by the variants of seekg() and seekp() which accept a relative offset argument. - Useful prototype knowledge: - Obtain read position ios::pos_type basic_istream::tellg() - Set read position basic_istream& basic_istream::seekg(ios::pos_type) basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir) - Read data basic_istream& istream::read(char *str, streamsize count) - Number of characters read in last unformatted read streamsize istream::gcount(); - Obtain write position ios::pos_type basic_ostream::tellp() - Set write position basic_ostream& basic_ostream::seekp(ios::pos_type) basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir) - Write data basic_ostream& ostream::write(const char *str, streamsize count) */ From d52d68176358f7de24fabf3d0567cad898da6de0 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 3 Nov 2020 15:41:52 +0000 Subject: [PATCH 07/25] Refactoring --- libs/Common/Util.h | 44 +++++++++++++++++++++++++++++++++++++++++++ libs/IO/Image.cpp | 10 ++++++---- libs/IO/Image.h | 43 ------------------------------------------ libs/IO/ImageTIFF.cpp | 7 +++++++ libs/IO/ImageTIFF.h | 7 ------- 5 files changed, 57 insertions(+), 54 deletions(-) diff --git a/libs/Common/Util.h b/libs/Common/Util.h index 871f92835..d2d378f70 100644 --- a/libs/Common/Util.h +++ b/libs/Common/Util.h @@ -824,6 +824,50 @@ class GENERAL_API Util lastMsgLen = msgLen; } }; + + template + static std::pair ComputePercentileMinMax(void *data, size_t size){ + if (size == 0) + return std::make_pair(0, 0); + + // Find min/max + T *p = reinterpret_cast(data); + T aMin = p[0]; + T aMax = p[0]; + + for (size_t i = 1; i < size; i++) { + if (p[i] > aMax) aMax = p[i]; + if (p[i] < aMin) aMin = p[i]; + } + + float range = static_cast(aMax - aMin); + if (range == 0) + return std::make_pair(0, 0); + + float closestMinP = 9999.0; + float closestMaxP = 9999.0; + + T min = 0; + T max = 0; + + // Get min/max values at the 10th and 90th percentile + for (size_t i = 0; i < size; i++) { + float percentile = (static_cast(p[i]) - static_cast(aMin)) / range; + float minP = abs(percentile - 0.1); + float maxP = abs(percentile - 0.9); + + if (minP < closestMinP) { + min = p[i]; + closestMinP = minP; + } + if (maxP < closestMaxP) { + max = p[i]; + closestMaxP = maxP; + } + } + + return std::make_pair(min, max); + } }; /*----------------------------------------------------------------*/ diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 09e55f6ae..b81ce720a 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -417,9 +417,10 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con case PF_GRAYU16:{ // from PF_GRAYU16 to PF_R8G8B8 - uint16_t min, max; uint16_t *pData = (uint16_t*)pSrc; - findMinMaxPercentile(pData, nSzize, &min, &max); + std::pair mm = Util::ComputePercentileMinMax(pData, nSzize); + uint16_t min = mm.first; + uint16_t max = mm.second; for (Size i=0; i mm = Util::ComputePercentileMinMax(pData, nSzize); + float min = mm.first; + float max = mm.second; for (Size i=0; i - static void findMinMaxPercentile(void *data, Size size, T* min, T* max){ - if (size == 0){ - *min = *max = 0; - return; - } - - // Find min/max - T *p = reinterpret_cast(data); - T aMin = p[0]; - T aMax = p[0]; - - for (Size i = 1; i < size; i++){ - if (p[i] > aMax) aMax = p[i]; - if (p[i] < aMin) aMin = p[i]; - } - - double range = static_cast(aMax - aMin); - if (range == 0){ - *min = *max = 0; - return; - } - - double closestMinP = 9999.0; - double closestMaxP = 9999.0; - - // Get min/max values at the 10th and 90th percentile - for (Size i = 0; i < size; i++){ - double percentile = (static_cast(p[i]) - static_cast(aMin)) / range; - double minP = abs(percentile - 0.1); - double maxP = abs(percentile - 0.9); - - if (minP < closestMinP){ - *min = p[i]; - closestMinP = minP; - } - if (maxP < closestMaxP){ - *max = p[i]; - closestMaxP = maxP; - } - } - } - IOSTREAMPTR m_pStream; // stream used to read/write the image data CAutoPtrArr m_data; // image's data buffer Size m_width; // image width in pixels diff --git a/libs/IO/ImageTIFF.cpp b/libs/IO/ImageTIFF.cpp index 4f971af41..119b4cc76 100644 --- a/libs/IO/ImageTIFF.cpp +++ b/libs/IO/ImageTIFF.cpp @@ -57,6 +57,13 @@ using namespace SEACAVE; basic_ostream& ostream::write(const char *str, streamsize count) */ +// https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html +enum TIFF_SAMPLEFORMAT_TYPE { + TIFF_SAMPLEFORMAT_UINT = 1, + TIFF_SAMPLEFORMAT_INT = 2, + TIFF_SAMPLEFORMAT_IEEEFP = 3 +}; + struct tiffis_data; struct tiffos_data; diff --git a/libs/IO/ImageTIFF.h b/libs/IO/ImageTIFF.h index 733f8898c..f3eb743a5 100644 --- a/libs/IO/ImageTIFF.h +++ b/libs/IO/ImageTIFF.h @@ -21,13 +21,6 @@ namespace SEACAVE { // S T R U C T S /////////////////////////////////////////////////// -// https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html -enum TIFF_SAMPLEFORMAT_TYPE { - TIFF_SAMPLEFORMAT_UINT = 1, - TIFF_SAMPLEFORMAT_INT = 2, - TIFF_SAMPLEFORMAT_IEEEFP = 3 -}; - class IO_API CImageTIFF : public CImage { public: From 6d8337dafaee28a8636133df8e1246f3684c36bf Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 3 Nov 2020 16:18:22 +0000 Subject: [PATCH 08/25] Fix ComputePercentileMinMax edge case --- libs/Common/Util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/Common/Util.h b/libs/Common/Util.h index d2d378f70..6f169ba37 100644 --- a/libs/Common/Util.h +++ b/libs/Common/Util.h @@ -842,7 +842,7 @@ class GENERAL_API Util float range = static_cast(aMax - aMin); if (range == 0) - return std::make_pair(0, 0); + return std::make_pair(aMin, aMax); float closestMinP = 9999.0; float closestMaxP = 9999.0; From 76340667dcafa54080cf42ba53e3d93cbb2497d6 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 3 Nov 2020 17:24:26 +0000 Subject: [PATCH 09/25] Fix style --- libs/Common/Util.h | 29 ++++++++++++++--------------- libs/IO/Image.cpp | 4 ++-- libs/IO/Image.h | 4 ++-- libs/IO/ImageTIFF.cpp | 14 ++++++++------ 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/libs/Common/Util.h b/libs/Common/Util.h index 6f169ba37..db2976ac5 100644 --- a/libs/Common/Util.h +++ b/libs/Common/Util.h @@ -826,42 +826,41 @@ class GENERAL_API Util }; template - static std::pair ComputePercentileMinMax(void *data, size_t size){ + static std::pair ComputePercentileMinMax(const T *data, size_t size){ if (size == 0) return std::make_pair(0, 0); // Find min/max - T *p = reinterpret_cast(data); - T aMin = p[0]; - T aMax = p[0]; + T aMin = data[0]; + T aMax = data[0]; for (size_t i = 1; i < size; i++) { - if (p[i] > aMax) aMax = p[i]; - if (p[i] < aMin) aMin = p[i]; + if (data[i] > aMax) aMax = data[i]; + if (data[i] < aMin) aMin = data[i]; } - float range = static_cast(aMax - aMin); - if (range == 0) + const float range = static_cast(aMax - aMin); + if (range == 0.0f) return std::make_pair(aMin, aMax); - float closestMinP = 9999.0; - float closestMaxP = 9999.0; + float closestMinP = 9999.0f; + float closestMaxP = 9999.0f; T min = 0; T max = 0; // Get min/max values at the 10th and 90th percentile for (size_t i = 0; i < size; i++) { - float percentile = (static_cast(p[i]) - static_cast(aMin)) / range; - float minP = abs(percentile - 0.1); - float maxP = abs(percentile - 0.9); + const float percentile = (static_cast(data[i]) - static_cast(aMin)) / range; + const float minP = abs(percentile - 0.1f); + const float maxP = abs(percentile - 0.9f); if (minP < closestMinP) { - min = p[i]; + min = data[i]; closestMinP = minP; } if (maxP < closestMaxP) { - max = p[i]; + max = data[i]; closestMaxP = maxP; } } diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index b81ce720a..5ae483c5c 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -419,8 +419,8 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con uint16_t *pData = (uint16_t*)pSrc; std::pair mm = Util::ComputePercentileMinMax(pData, nSzize); - uint16_t min = mm.first; - uint16_t max = mm.second; + uint16_t min = mm.first; + uint16_t max = mm.second; for (Size i=0; i= 3){ + if (ncn >= 3) { m_format = PF_B8G8R8A8; m_stride = 4; - }else if (ncn == 1){ + } else if (ncn == 1) { m_format = PF_GRAY8; m_stride = 1; - }else{ + } else { implemented = false; } break; case 16: m_format = PF_GRAYU16; m_stride = 2; - if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_UINT) implemented = false; + if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_UINT) + implemented = false; break; case 32: m_format = PF_GRAYF32; m_stride = 4; - if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) implemented = false; + if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) + implemented = false; break; default: // TODO: implement support for more implemented = false; } - if (!implemented){ + if (!implemented) { ASSERT("error: not implemented" == NULL); LOG(LT_IMAGE, "error: unsupported TIFF image"); Close(); From f0accc6c84d2228fb72f4a8b1d7867f0a1c449d1 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Sat, 5 Dec 2020 15:13:40 -0500 Subject: [PATCH 10/25] Remove file logging --- apps/DensifyPointCloud/DensifyPointCloud.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/DensifyPointCloud/DensifyPointCloud.cpp b/apps/DensifyPointCloud/DensifyPointCloud.cpp index cde482a86..1635ef80f 100644 --- a/apps/DensifyPointCloud/DensifyPointCloud.cpp +++ b/apps/DensifyPointCloud/DensifyPointCloud.cpp @@ -196,7 +196,7 @@ bool Initialize(size_t argc, LPCTSTR* argv) } // initialize the log file - OPEN_LOGFILE(MAKE_PATH(APPNAME _T("-")+Util::getUniqueName(0)+_T(".log")).c_str()); + //OPEN_LOGFILE(MAKE_PATH(APPNAME _T("-")+Util::getUniqueName(0)+_T(".log")).c_str()); // print application details: version and command line Util::LogBuild(); From ec3c5479bdcaeb9a78863dd5f82c48e27383c702 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 12 Jan 2021 14:28:08 -0500 Subject: [PATCH 11/25] Export num views in PLY --- libs/MVS/PointCloud.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/MVS/PointCloud.cpp b/libs/MVS/PointCloud.cpp index c62920961..cd7d946c8 100644 --- a/libs/MVS/PointCloud.cpp +++ b/libs/MVS/PointCloud.cpp @@ -438,7 +438,7 @@ bool PointCloud::SaveNViews(const String& fileName, uint32_t minViews, bool bLeg } } else { // describe what properties go into the vertex elements - ply.describe_property(BasicPLY::elem_names[0], 9, BasicPLY::Vertex::props); + ply.describe_property(BasicPLY::elem_names[0], 10, BasicPLY::Vertex::props); // export the array of 3D points FOREACH(i, points) { @@ -448,6 +448,7 @@ bool PointCloud::SaveNViews(const String& fileName, uint32_t minViews, bool bLeg vertex.p = points[i]; vertex.n = normals[i]; vertex.c = colors.empty() ? Pixel8U::WHITE : colors[i]; + vertex.views.num = pointViews[i].size(); ply.put_element(&vertex); } } From b8594872bb53d5a2337cb397e3872b9086ea649d Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Sat, 15 May 2021 14:29:40 -0400 Subject: [PATCH 12/25] Do not write log --- apps/ReconstructMesh/ReconstructMesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ReconstructMesh/ReconstructMesh.cpp b/apps/ReconstructMesh/ReconstructMesh.cpp index 24a74b945..c19ebeb62 100644 --- a/apps/ReconstructMesh/ReconstructMesh.cpp +++ b/apps/ReconstructMesh/ReconstructMesh.cpp @@ -177,7 +177,7 @@ bool Initialize(size_t argc, LPCTSTR* argv) } // initialize the log file - OPEN_LOGFILE(MAKE_PATH(APPNAME _T("-")+Util::getUniqueName(0)+_T(".log")).c_str()); + // OPEN_LOGFILE(MAKE_PATH(APPNAME _T("-")+Util::getUniqueName(0)+_T(".log")).c_str()); // print application details: version and command line Util::LogBuild(); From 1f525ebdd49fced83448d32bb2493f2b98160d50 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 26 May 2022 20:45:33 -0400 Subject: [PATCH 13/25] add mock cuda-device opt --- apps/DensifyPointCloud/DensifyPointCloud.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/DensifyPointCloud/DensifyPointCloud.cpp b/apps/DensifyPointCloud/DensifyPointCloud.cpp index 1635ef80f..f8531d7e2 100644 --- a/apps/DensifyPointCloud/DensifyPointCloud.cpp +++ b/apps/DensifyPointCloud/DensifyPointCloud.cpp @@ -70,6 +70,7 @@ int nExportNumViews; int nArchiveType; int nProcessPriority; unsigned nMaxThreads; +int mockCudaDevice; String strConfigFileName; boost::program_options::variables_map vm; } // namespace OPT @@ -101,6 +102,8 @@ bool Initialize(size_t argc, LPCTSTR* argv) #endif #ifdef _USE_CUDA ("cuda-device", boost::program_options::value(&CUDA::desiredDeviceID)->default_value(-1), "CUDA device number to be used for depth-map estimation (-2 - CPU processing, -1 - best GPU, >=0 - device index)") + #else + ("cuda-device", boost::program_options::value(&OPT::mockCudaDevice)->default_value(-1), "Just a placeholder (not a CUDA build)") #endif ; From e1f48b8fbb1fdb3b780b152277753b1097bb194a Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 6 Jun 2022 13:52:12 -0400 Subject: [PATCH 14/25] Do not precompile headers on Windows --- apps/Viewer/CMakeLists.txt | 4 +++- libs/Common/CMakeLists.txt | 4 +++- libs/IO/CMakeLists.txt | 4 +++- libs/MVS/CMakeLists.txt | 4 +++- libs/Math/CMakeLists.txt | 4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/Viewer/CMakeLists.txt b/apps/Viewer/CMakeLists.txt index fe0920242..e9dab43ca 100644 --- a/apps/Viewer/CMakeLists.txt +++ b/apps/Viewer/CMakeLists.txt @@ -38,7 +38,9 @@ cxx_executable_with_flags(${VIEWER_NAME} "Apps" "${cxx_default}" "MVS;${OPENGL_L # Manually set Common.h as the precompiled header IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) - TARGET_PRECOMPILE_HEADERS(${VIEWER_NAME} PRIVATE "Common.h") + if(NOT WIN32) # Smaller but slower build on Windows + TARGET_PRECOMPILE_HEADERS(${VIEWER_NAME} PRIVATE "Common.h") + endif() endif() # Install diff --git a/libs/Common/CMakeLists.txt b/libs/Common/CMakeLists.txt index 18899afde..2008665ff 100644 --- a/libs/Common/CMakeLists.txt +++ b/libs/Common/CMakeLists.txt @@ -8,7 +8,9 @@ cxx_library_with_type(Common "Libs" "" "${cxx_default}" # Manually set Common.h as the precompiled header IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) - TARGET_PRECOMPILE_HEADERS(Common PRIVATE "Common.h") + if(NOT WIN32) # Smaller but slower build on Windows + TARGET_PRECOMPILE_HEADERS(Common PRIVATE "Common.h") + endif() endif() # Link its dependencies diff --git a/libs/IO/CMakeLists.txt b/libs/IO/CMakeLists.txt index 0f0595194..0c71cb97f 100644 --- a/libs/IO/CMakeLists.txt +++ b/libs/IO/CMakeLists.txt @@ -34,7 +34,9 @@ cxx_library_with_type(IO "Libs" "" "${cxx_default}" # Manually set Common.h as the precompiled header IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) - TARGET_PRECOMPILE_HEADERS(IO PRIVATE "Common.h") + if(NOT WIN32) # Smaller but slower build on Windows + TARGET_PRECOMPILE_HEADERS(IO PRIVATE "Common.h") + endif() endif() # Link its dependencies diff --git a/libs/MVS/CMakeLists.txt b/libs/MVS/CMakeLists.txt index 853386508..60dccaf6a 100644 --- a/libs/MVS/CMakeLists.txt +++ b/libs/MVS/CMakeLists.txt @@ -41,7 +41,9 @@ cxx_library_with_type(MVS "Libs" "" "${cxx_default}" # Manually set Common.h as the precompiled header IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) - TARGET_PRECOMPILE_HEADERS(MVS PRIVATE "Common.h") + if(NOT WIN32) + TARGET_PRECOMPILE_HEADERS(MVS PRIVATE "Common.h") + endif() endif() # Link its dependencies diff --git a/libs/Math/CMakeLists.txt b/libs/Math/CMakeLists.txt index 407e2e403..89f2a9801 100644 --- a/libs/Math/CMakeLists.txt +++ b/libs/Math/CMakeLists.txt @@ -25,7 +25,9 @@ cxx_library_with_type(Math "Libs" "" "${cxx_default}" # Manually set Common.h as the precompiled header IF(CMAKE_VERSION VERSION_GREATER_EQUAL 3.16.0) - TARGET_PRECOMPILE_HEADERS(Math PRIVATE "Common.h") + if(NOT WIN32) + TARGET_PRECOMPILE_HEADERS(Math PRIVATE "Common.h") + endif() endif() # Link its dependencies From 05fee286caa1a000a19ae972ad5198c9448bf71e Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 26 Jul 2022 14:52:54 -0400 Subject: [PATCH 15/25] Add support for PF_R32G32B32 inputs --- libs/IO/Image.cpp | 28 +++++++++++++++++++++++++--- libs/IO/Image.h | 1 + libs/IO/ImageTIFF.cpp | 22 ++++++++++------------ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 5ae483c5c..58eade1f5 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -438,9 +438,9 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con // from PF_GRAYF32 to PF_R8G8B8 float *pData = (float*)pSrc; - std::pair mm = Util::ComputePercentileMinMax(pData, nSzize); - float min = mm.first; - float max = mm.second; + std::pair mm = Util::ComputePercentileMinMax(pData, nSzize); + float min = mm.first; + float max = mm.second; for (Size i=0; i mm = Util::ComputePercentileMinMax(pData, nSzize); + float min = mm.first; + float max = mm.second; + + for (Size i=0; i 8 && ((photometric != 2 && photometric != 1) || (ncn != 1 && ncn != 3 && ncn != 4))) @@ -434,10 +427,16 @@ HRESULT CImageTIFF::ReadHeader() implemented = false; break; case 32: - m_format = PF_GRAYF32; - m_stride = 4; - if (ncn != 1 || sampleFormat != TIFF_SAMPLEFORMAT_IEEEFP) + if (ncn == 1 && sampleFormat == TIFF_SAMPLEFORMAT_IEEEFP){ + m_format = PF_GRAYF32; + m_stride = 4; + }else if (ncn == 3 && sampleFormat == TIFF_SAMPLEFORMAT_IEEEFP){ + m_stride = 12; + m_format = PF_R32G32B32; + }else{ implemented = false; + } + break; default: // TODO: implement support for more @@ -486,14 +485,13 @@ HRESULT CImageTIFF::ReadData(void* pData, PIXELFORMAT dataFormat, Size nStride, Close(); return _INVALIDFILE; } - }else if (m_format == PF_GRAYU16 || m_format == PF_GRAYF32){ + }else if (m_format == PF_GRAYU16 || m_format == PF_GRAYF32 || m_format == PF_R32G32B32){ for (uint32 y = 0; y < m_height; y++, buffer += m_lineWidth){ if (!TIFFReadScanline(tif, buffer, y, 0)){ Close(); return _INVALIDFILE; } } - buffer = _buffer.Begin(); } From 6952ade729c60c0aef5707d960e9f248e3a9d5fa Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 19 Sep 2022 18:17:41 -0400 Subject: [PATCH 16/25] Fix ignore mask on GPU, remove disk space info --- libs/Common/Util.cpp | 10 +++++----- libs/MVS/PatchMatchCUDA.cpp | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libs/Common/Util.cpp b/libs/Common/Util.cpp index 1ae22cb66..523664914 100644 --- a/libs/Common/Util.cpp +++ b/libs/Common/Util.cpp @@ -434,16 +434,16 @@ String Util::GetOSInfo() String Util::GetDiskInfo(const String& path) { - #if defined(_SUPPORT_CPP17) && (!defined(__GNUC__) || (__GNUC__ > 7)) + // #if defined(_SUPPORT_CPP17) && (!defined(__GNUC__) || (__GNUC__ > 8)) - const std::filesystem::space_info si = std::filesystem::space(path.c_str()); - return String::FormatString("%s (%s) space", formatBytes(si.available).c_str(), formatBytes(si.capacity).c_str()); + // const std::filesystem::space_info si = std::filesystem::space(path.c_str()); + // return String::FormatString("%s (%s) space", formatBytes(si.available).c_str(), formatBytes(si.capacity).c_str()); - #else + // #else return String(); - #endif // _SUPPORT_CPP17 + // #endif // _SUPPORT_CPP17 } /*----------------------------------------------------------------*/ diff --git a/libs/MVS/PatchMatchCUDA.cpp b/libs/MVS/PatchMatchCUDA.cpp index 1a6c95f99..92d4ea95c 100644 --- a/libs/MVS/PatchMatchCUDA.cpp +++ b/libs/MVS/PatchMatchCUDA.cpp @@ -297,6 +297,7 @@ void PatchMatchCUDA::EstimateDepthMap(DepthData& depthData) cv::resize(depthMap, depthMap, image.size(), 0, 0, cv::INTER_LINEAR); CUDA::checkCudaCall(cudaMemcpy2DToArray(cudaDepthArrays[i-1], 0, 0, depthMap.ptr(), depthMap.step[0], sizeof(float) * depthMap.cols, depthMap.rows, cudaMemcpyHostToDevice)); } + images[i] = std::move(image); cameras[i] = std::move(camera); } @@ -398,6 +399,15 @@ void PatchMatchCUDA::EstimateDepthMap(DepthData& depthData) lowResNormalMap = depthData.normalMap; lowResViewsMap = depthData.viewsMap; } + + // Apply ignore mask + if (OPTDENSE::nIgnoreMaskLabel >= 0) { + const DepthData::ViewData& view = depthData.GetView(); + + BitMatrix mask; + if (OPTDENSE::nIgnoreMaskLabel >= 0 && DepthEstimator::ImportIgnoreMask(*view.pImageData, depthData.depthMap.size(), mask, (uint16_t)OPTDENSE::nIgnoreMaskLabel)) + depthData.ApplyIgnoreMask(mask); + } } // apply ignore mask From 8dd92231f8a8bdb4121670421f5d855fcf8f44d2 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 20 Sep 2022 10:26:22 -0400 Subject: [PATCH 17/25] Ignore masks in outer scope --- libs/MVS/PatchMatchCUDA.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/MVS/PatchMatchCUDA.cpp b/libs/MVS/PatchMatchCUDA.cpp index 92d4ea95c..8b2eecf58 100644 --- a/libs/MVS/PatchMatchCUDA.cpp +++ b/libs/MVS/PatchMatchCUDA.cpp @@ -400,14 +400,14 @@ void PatchMatchCUDA::EstimateDepthMap(DepthData& depthData) lowResViewsMap = depthData.viewsMap; } - // Apply ignore mask - if (OPTDENSE::nIgnoreMaskLabel >= 0) { - const DepthData::ViewData& view = depthData.GetView(); - - BitMatrix mask; - if (OPTDENSE::nIgnoreMaskLabel >= 0 && DepthEstimator::ImportIgnoreMask(*view.pImageData, depthData.depthMap.size(), mask, (uint16_t)OPTDENSE::nIgnoreMaskLabel)) - depthData.ApplyIgnoreMask(mask); - } + } + + // apply ignore mask + if (OPTDENSE::nIgnoreMaskLabel >= 0) { + const DepthData::ViewData& view = depthData.GetView(); + BitMatrix mask; + if (DepthEstimator::ImportIgnoreMask(*view.pImageData, depthData.depthMap.size(), mask, (uint16_t)OPTDENSE::nIgnoreMaskLabel)) + depthData.ApplyIgnoreMask(mask); } // apply ignore mask From 8ecc0f8e811f16ef2b19752d5b5db438fb38029a Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 1 Dec 2022 17:43:19 +0000 Subject: [PATCH 18/25] Remove vcpkg manifest mode --- vcpkg.json | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 vcpkg.json diff --git a/vcpkg.json b/vcpkg.json deleted file mode 100644 index 0c1542b1a..000000000 --- a/vcpkg.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "openmvs", - "version": "2.2.0", - "description": "OpenMVS: open Multi-View Stereo reconstruction library", - "homepage": "https://cdcseacave.github.io/openMVS", - "dependencies": [ - "boost-iostreams", - "boost-program-options", - "boost-serialization", - "boost-system", - "boost-throw-exception", - { - "name": "cgal", - "default-features": false - }, - "eigen3", - "glew", - "glfw3", - "libpng", - { - "name": "opencv", - "features": [ - "eigen", - "openexr" - ] - }, - "opencv", - "opengl", - "tiff", - "vcglib", - "zlib" - ], - "features": { - "python": { - "description": "Python bindings for OpenMVS", - "dependencies": [ - "boost-python" - ] - }, - "cuda": { - "description": "CUDA support for OpenMVS", - "dependencies": [ - "cuda" - ] - }, - "openmp": { - "description": "OpenMP support for OpenMVS" - } - } -} From 59a027514e41710204eba094da94d98ed2d78c1e Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Fri, 26 May 2023 14:02:33 -0400 Subject: [PATCH 19/25] Fix merge, add support for PF_R16G16B16 --- libs/IO/Image.cpp | 22 ++++++++++++++++++++++ libs/IO/Image.h | 1 + libs/IO/ImageTIFF.cpp | 14 ++++++++++---- libs/MVS/PatchMatchCUDA.cpp | 8 -------- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/libs/IO/Image.cpp b/libs/IO/Image.cpp index 58eade1f5..b046f8bff 100644 --- a/libs/IO/Image.cpp +++ b/libs/IO/Image.cpp @@ -454,6 +454,28 @@ bool CImage::FilterFormat(void* pDst, PIXELFORMAT formatDst, Size strideDst, con return true; } + case PF_R16G16B16:{ + // from PF_R16G16B16 to PF_R8G8B8 + uint16_t *pData = (uint16_t*)pSrc; + std::pair mm = Util::ComputePercentileMinMax(pData, nSzize); + uint16_t min = mm.first; + uint16_t max = mm.second; + + for (Size i=0; i= 0) { - const DepthData::ViewData& view = depthData.GetView(); - BitMatrix mask; - if (DepthEstimator::ImportIgnoreMask(*view.pImageData, depthData.depthMap.size(), mask, (uint16_t)OPTDENSE::nIgnoreMaskLabel)) - depthData.ApplyIgnoreMask(mask); - } // apply ignore mask if (OPTDENSE::nIgnoreMaskLabel >= 0) { From f0fe7352bf256043a84656b0f254c1c519859eed Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 21 Aug 2023 18:57:56 +0000 Subject: [PATCH 20/25] Disable CMP0127 and SSE optimizations for ARM From merge e2f3c4b from Piero Toffanin --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f0221349f..a42acd8b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,8 +50,8 @@ ENDIF() # ${OpenMVS_BINARY_DIR}. PROJECT(OpenMVS) -cmake_policy(SET CMP0127 NEW) -cmake_dependent_option(OpenMVS_USE_SSE "Enable SSE optimizations" ON "NOT CMAKE_SYSTEM_PROCESSOR MATCHES \"^(arm|ARM|aarch64|AARCH64).\"" OFF) +# cmake_policy(SET CMP0127 NEW) +# cmake_dependent_option(OpenMVS_USE_SSE "Enable SSE optimizations" ON "NOT CMAKE_SYSTEM_PROCESSOR MATCHES \"^(arm|ARM|aarch64|AARCH64).\"" OFF) SET(OpenMVS_MAJOR_VERSION 2) SET(OpenMVS_MINOR_VERSION 2) From ff2d81d44d01654f0de6ca3a2e2d4d8f233d30ed Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 21 Aug 2023 18:57:56 +0000 Subject: [PATCH 21/25] Disable builds for unused projects. From Merge e2f3c4b from Piero Toffanin --- apps/CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 3bb00c6c6..e7c788f99 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -1,14 +1,14 @@ # Add applications -ADD_SUBDIRECTORY(InterfaceCOLMAP) -ADD_SUBDIRECTORY(InterfaceMetashape) -ADD_SUBDIRECTORY(InterfaceMVSNet) -ADD_SUBDIRECTORY(InterfacePolycam) +#ADD_SUBDIRECTORY(InterfaceCOLMAP) +#ADD_SUBDIRECTORY(InterfaceMetashape) +#ADD_SUBDIRECTORY(InterfaceMVSNet) +#ADD_SUBDIRECTORY(InterfacePolycam) ADD_SUBDIRECTORY(DensifyPointCloud) ADD_SUBDIRECTORY(ReconstructMesh) ADD_SUBDIRECTORY(RefineMesh) -ADD_SUBDIRECTORY(TextureMesh) -ADD_SUBDIRECTORY(TransformScene) -ADD_SUBDIRECTORY(Viewer) +#ADD_SUBDIRECTORY(TextureMesh) +#ADD_SUBDIRECTORY(TransformScene) +#ADD_SUBDIRECTORY(Viewer) if(OpenMVS_ENABLE_TESTS) ADD_SUBDIRECTORY(Tests) endif() From 1117ce71fc4e1e5f7c154de4b17bb8a8e065c8ee Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 21 Aug 2023 18:57:56 +0000 Subject: [PATCH 22/25] Adapt PLY Properties FPCFilter From Merge e2f3c4b from Piero Toffanin --- libs/MVS/PointCloud.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/libs/MVS/PointCloud.cpp b/libs/MVS/PointCloud.cpp index cd7d946c8..59dccb653 100644 --- a/libs/MVS/PointCloud.cpp +++ b/libs/MVS/PointCloud.cpp @@ -272,18 +272,18 @@ namespace BasicPLY { ply.describe_property(elem_names[0], 3, props+6); if (bViews) ply.describe_property(elem_names[0], props[9]); - if (bWeights) - ply.describe_property(elem_names[0], props[10]); - if (bConfidence) - ply.describe_property(elem_names[0], props[11]); - if (bScale) - ply.describe_property(elem_names[0], props[12]); + // if (bWeights) + // ply.describe_property(elem_names[0], props[10]); + // if (bConfidence) + // ply.describe_property(elem_names[0], props[11]); + // if (bScale) + // ply.describe_property(elem_names[0], props[12]); if (elem_count) ply.element_count(elem_names[0], elem_count); } - static const PLY::PlyProperty props[16]; + static const PLY::PlyProperty props[10]; }; - const PLY::PlyProperty Vertex::props[16] = { + const PLY::PlyProperty Vertex::props[10] = { {"x", PLY::Float32, PLY::Float32, offsetof(Vertex,p.x), 0, 0, 0, 0}, {"y", PLY::Float32, PLY::Float32, offsetof(Vertex,p.y), 0, 0, 0, 0}, {"z", PLY::Float32, PLY::Float32, offsetof(Vertex,p.z), 0, 0, 0, 0}, @@ -293,14 +293,15 @@ namespace BasicPLY { {"nx", PLY::Float32, PLY::Float32, offsetof(Vertex,n.x), 0, 0, 0, 0}, {"ny", PLY::Float32, PLY::Float32, offsetof(Vertex,n.y), 0, 0, 0, 0}, {"nz", PLY::Float32, PLY::Float32, offsetof(Vertex,n.z), 0, 0, 0, 0}, - {"view_indices", PLY::Uint32, PLY::Uint32, offsetof(Vertex,views.pIndices), 1, PLY::Uint8, PLY::Uint8, offsetof(Vertex,views.num)}, - {"view_weights", PLY::Float32, PLY::Float32, offsetof(Vertex,views.pWeights), 1, PLY::Uint8, PLY::Uint8, offsetof(Vertex,views.num)}, - {"confidence", PLY::Float32, PLY::Float32, offsetof(Vertex,confidence), 0, 0, 0, 0}, - {"value", PLY::Float32, PLY::Float32, offsetof(Vertex,scale), 0, 0, 0, 0}, + {"views", PLY::Uint8, PLY::Uint8, offsetof(Vertex,views.num), 0, 0, 0, 0} + //{"view_indices", PLY::Uint32, PLY::Uint32, offsetof(Vertex,views.pIndices), 1, PLY::Uint8, PLY::Uint8, offsetof(Vertex,views.num)}, + //{"view_weights", PLY::Float32, PLY::Float32, offsetof(Vertex,views.pWeights), 1, PLY::Uint8, PLY::Uint8, offsetof(Vertex,views.num)}, + //{"confidence", PLY::Float32, PLY::Float32, offsetof(Vertex,confidence), 0, 0, 0, 0}, + //{"value", PLY::Float32, PLY::Float32, offsetof(Vertex,scale), 0, 0, 0, 0}, // duplicates - {"diffuse_red", PLY::Uint8, PLY::Uint8, offsetof(Vertex,c.r), 0, 0, 0, 0}, - {"diffuse_green", PLY::Uint8, PLY::Uint8, offsetof(Vertex,c.g), 0, 0, 0, 0}, - {"diffuse_blue", PLY::Uint8, PLY::Uint8, offsetof(Vertex,c.b), 0, 0, 0, 0} + //{"diffuse_red", PLY::Uint8, PLY::Uint8, offsetof(Vertex,c.r), 0, 0, 0, 0}, + //{"diffuse_green", PLY::Uint8, PLY::Uint8, offsetof(Vertex,c.g), 0, 0, 0, 0}, + //{"diffuse_blue", PLY::Uint8, PLY::Uint8, offsetof(Vertex,c.b), 0, 0, 0, 0} }; } // namespace BasicPLY } // namespace PointCloudInternal From 59ed51361b1cd2d1c8aa4501b6cc534fdf70dd26 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 21 Aug 2023 15:41:55 -0400 Subject: [PATCH 23/25] Export views field in PLY --- libs/MVS/PointCloud.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/MVS/PointCloud.cpp b/libs/MVS/PointCloud.cpp index 59dccb653..dd33bb291 100644 --- a/libs/MVS/PointCloud.cpp +++ b/libs/MVS/PointCloud.cpp @@ -270,7 +270,7 @@ namespace BasicPLY { ply.describe_property(elem_names[0], 3, props+3); if (bNormals) ply.describe_property(elem_names[0], 3, props+6); - if (bViews) + // if (bViews) // ODM: always output "views" in PLY ply.describe_property(elem_names[0], props[9]); // if (bWeights) // ply.describe_property(elem_names[0], props[10]); From b0b814b58c94feb1ecf5f9e6950b09d98c405737 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Mon, 24 Feb 2025 14:24:25 -0500 Subject: [PATCH 24/25] Add read permissions to GO --- libs/Common/File.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/Common/File.h b/libs/Common/File.h index 2e431bccd..166779c47 100644 --- a/libs/Common/File.h +++ b/libs/Common/File.h @@ -468,7 +468,7 @@ class GENERAL_API File : public IOStream { if (flags & NOBUFFER) m |= O_DIRECT; #endif - h = ::open(aFileName, m, S_IRUSR | S_IWUSR); + h = ::open(aFileName, m, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); } virtual void close() { From 8bedb23c3b39bc7dab0cb2d7dd18fd4ae1a08d9c Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Fri, 15 May 2026 23:56:57 -0400 Subject: [PATCH 25/25] Allow disabling subdirectory on install Cherry-pick of https://github.com/cdcseacave/openMVS/pull/1272 --- build/Utils.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/Utils.cmake b/build/Utils.cmake index 9c2430faa..1854f92ee 100644 --- a/build/Utils.cmake +++ b/build/Utils.cmake @@ -17,6 +17,7 @@ OPTION(BUILD_RTTI_ENABLED "Enable support run-time type information" ON) OPTION(BUILD_STATIC_RUNTIME "Link staticaly the run-time library" OFF) OPTION(CMAKE_SUPPRESS_REGENERATION "This will cause CMake to not put in the rules that re-run CMake. This might be useful if you want to use the generated build files on another machine" OFF) OPTION(CMAKE_USE_RELATIVE_PATHS "Try to use relative paths in generated projects" OFF) +OPTION(INSTALL_USE_SUBDIR "Install into /OpenMVS subdirectories" ON) # Organize projects into folders SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON) @@ -817,7 +818,11 @@ macro(ConfigLibrary) else() set(${varp} "${CMAKE_INSTALL_PREFIX}/${${var}}") endif() - set(${var} "${${varp}}/${PROJECT_NAME}") + if(INSTALL_USE_SUBDIR) + set(${var} "${${varp}}/${PROJECT_NAME}") + else() + set(${var} "${${varp}}") + endif() endforeach() endmacro()