From ca98d6010d52b8376bd4fc99762f152b78a3c7cf Mon Sep 17 00:00:00 2001 From: Erik Smistad Date: Wed, 27 Nov 2024 14:21:29 +0100 Subject: [PATCH] Fixed issue with incorrect black areas when using setBlankPatch and propagating patches upwards --- .../FAST/Data/Access/ImagePyramidAccess.cpp | 29 +++++++++++-------- .../FAST/Data/Access/ImagePyramidAccess.hpp | 3 +- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/source/FAST/Data/Access/ImagePyramidAccess.cpp b/source/FAST/Data/Access/ImagePyramidAccess.cpp index 6f1699f38..16fedb82f 100644 --- a/source/FAST/Data/Access/ImagePyramidAccess.cpp +++ b/source/FAST/Data/Access/ImagePyramidAccess.cpp @@ -60,7 +60,7 @@ std::unique_ptr ImagePyramidAccess::getPatchDataChar(int level, int x, if(!isPatchInitialized(level, x, y)) { // Tile has not be initialized, fill with zeros and return.. // TODO Do not try render these patches.. - std::memset(data.get(), 0, width*height*channels); + std::memset(data.get(), channels > 1 ? 255 : 0, width*height*channels); return data; } std::lock_guard lock(m_readMutex); @@ -117,7 +117,7 @@ std::unique_ptr ImagePyramidAccess::getPatchDataChar(int level, int x, const int fullTileBufferWidth = totalTilesX*tileWidth; for(int i = 0; i < totalTilesX; ++i) { for(int j = 0; j < totalTilesY; ++j) { - auto tileData = std::make_unique(tileWidth*tileHeight*bytesPerPixel); + auto tileData = make_uninitialized_unique(tileWidth*tileHeight*bytesPerPixel); int tileX = i*tileWidth; int tileY = j*tileHeight; int bytesRead = readTileFromTIFF((void *) tileData.get(), firstTileX*tileWidth+tileX, firstTileY*tileHeight+tileY, level); @@ -421,8 +421,11 @@ void ImagePyramidAccess::setPatch(int level, int x, int y, Image::pointer patch, m_image->setDirtyPatch(level, patchIdX, patchIdY); // Propagate upwards - if(!propagate) - return; + if(propagate) + propagatePatch(patch, level, x, y); +} + +void ImagePyramidAccess::propagatePatch(Image::pointer patch, int level, int x, int y) { auto previousData = std::make_unique(patch->getNrOfVoxels()*patch->getNrOfChannels()); auto patchAccess = patch->getImageAccess(ACCESS_READ); auto data = (uchar*)patchAccess->get(); @@ -452,12 +455,12 @@ void ImagePyramidAccess::setPatch(int level, int x, int y, Image::pointer patch, for(int dx = 0; dx < tileWidth/2; ++dx) { for(int c = 0; c < channels; ++c) { newData[c + channels*(dx + offsetX * tileWidth / 2 + (dy + offsetY * tileHeight / 2) * tileWidth)] = - (uchar)round((float)( - previousData[c + channels*(dx * 2 + dy * 2 * previousTileWidth)] + - previousData[c + channels*(dx * 2 + 1 + dy * 2 * previousTileWidth)] + - previousData[c + channels*(dx * 2 + 1 + (dy * 2 + 1) * previousTileWidth)] + - previousData[c + channels*(dx * 2 + (dy * 2 + 1) * previousTileWidth)] - ) / 4); + (uchar)round((float)( + previousData[c + channels*(dx * 2 + dy * 2 * previousTileWidth)] + + previousData[c + channels*(dx * 2 + 1 + dy * 2 * previousTileWidth)] + + previousData[c + channels*(dx * 2 + 1 + (dy * 2 + 1) * previousTileWidth)] + + previousData[c + channels*(dx * 2 + (dy * 2 + 1) * previousTileWidth)] + ) / 4); } } } @@ -491,7 +494,7 @@ void ImagePyramidAccess::setPatch(int level, int x, int y, Image::pointer patch, } } } - tile_id = writeTileToTIFF(level, x, y, newData.get(), tileWidth, tileHeight, channels); + auto tile_id = writeTileToTIFF(level, x, y, newData.get(), tileWidth, tileHeight, channels); previousData = std::move(newData); int levelWidth = m_image->getLevelWidth(level); @@ -505,7 +508,7 @@ void ImagePyramidAccess::setPatch(int level, int x, int y, Image::pointer patch, } } -bool ImagePyramidAccess::isPatchInitialized(uint level, uint x, uint y) { +bool ImagePyramidAccess::isPatchInitialized(int level, int x, int y) { if(m_image->isPyramidFullyInitialized()) return true; std::lock_guard lock(m_readMutex); @@ -614,6 +617,8 @@ void ImagePyramidAccess::setBlankPatch(int level, int x, int y) { TIFFWriteRawTile(m_tiffHandle, tile_id, &data, 1); TIFFCheckpointDirectory(m_tiffHandle); m_initializedPatchList.insert(std::to_string(level) + "-" + std::to_string(tile_id)); + + // TODO Propagate or not? } diff --git a/source/FAST/Data/Access/ImagePyramidAccess.hpp b/source/FAST/Data/Access/ImagePyramidAccess.hpp index 71b38e964..c001f5fe2 100644 --- a/source/FAST/Data/Access/ImagePyramidAccess.hpp +++ b/source/FAST/Data/Access/ImagePyramidAccess.hpp @@ -78,7 +78,7 @@ class FAST_EXPORT ImagePyramidAccess : Object { * @param y */ void setBlankPatch(int level, int x, int y); - bool isPatchInitialized(uint level, uint x, uint y); + bool isPatchInitialized(int level, int x, int y); template std::unique_ptr getPatchData(int level, int x, int y, int width, int height); std::shared_ptr getLevelAsImage(int level); @@ -113,6 +113,7 @@ class FAST_EXPORT ImagePyramidAccess : Object { uint32_t writeTileToTIFFJPEGXL(int level, int x, int y, uchar *data); uint32_t writeTileToTIFFNeuralNetwork(int level, int x, int y, std::shared_ptr image); int readTileFromTIFF(void* data, int x, int y, int level); + void propagatePatch(std::shared_ptr patch, int level, int x, int y); }; template