Skip to content

Commit aede3fb

Browse files
committed
Implemented ImagePyramid::getLevelSizes(), added some more tests, and added additional checks to constructor when levelSizes is provided.
1 parent 1d4c82a commit aede3fb

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

source/FAST/Data/ImagePyramid.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ ImagePyramid::ImagePyramid(int width, int height, int channels, int patchWidth,
101101
break;
102102
if(levelSizes[currentLevel-1].x() <= 2 && levelSizes[currentLevel-1].y() <= 2)
103103
throw Exception("Invalid level size smaller than 2");
104+
if(currentLevel == 1 && levelSizes[0].x() == currentWidth && levelSizes[0].y() == currentHeight) {
105+
// User has specified width and height of level 0 in levelSizes: skip it, as this level is already created
106+
++currentLevel;
107+
continue;
108+
}
109+
if(levelSizes[currentLevel-1].x() >= currentWidth || levelSizes[currentLevel-1].y() >= currentHeight)
110+
throw Exception("Invalid level size, each size must be smaller than previous level."
111+
"Current: " + std::to_string(currentWidth) + " " + std::to_string(currentHeight) + " "
112+
"Next: " + std::to_string(levelSizes[currentLevel-1].x()) + " " + std::to_string(levelSizes[currentLevel-1].y())
113+
);
104114
currentWidth = levelSizes[currentLevel-1].x();
105115
currentHeight = levelSizes[currentLevel-1].y();
106116
} else if(!levelDownsamples.empty()) {
@@ -683,4 +693,12 @@ int ImagePyramid::getWidth() const {
683693
int ImagePyramid::getHeight() const {
684694
return getLevelHeight(0);
685695
}
696+
697+
std::vector<Vector2i> ImagePyramid::getLevelSizes() const {
698+
std::vector<Vector2i> sizes;
699+
for(int i = 0; i < getNrOfLevels(); ++i) {
700+
sizes.emplace_back(getLevelWidth(i), getLevelHeight(i));
701+
}
702+
return sizes;
703+
}
686704
}

source/FAST/Data/ImagePyramid.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,16 @@ class FAST_EXPORT ImagePyramid : public SpatialDataObject {
8282
int getFullHeight();
8383
int getWidth() const;
8484
int getHeight() const;
85+
/**
86+
* @brief Get size (width and height) for each level in the image pyramid
87+
* @return list of image pyramid level sizes
88+
*/
89+
std::vector<Vector2i> getLevelSizes() const;
8590
int getNrOfChannels() const;
8691
bool isBGRA() const;
8792
bool usesTIFF() const;
8893
/**
89-
* Whether all patches in entire pyramid has been initialized.
94+
* @brief Whether all patches in entire pyramid has been initialized.
9095
*/
9196
bool isPyramidFullyInitialized() const;
9297
bool usesOpenSlide() const;

source/FAST/Data/Tests/ImagePyramidTests.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,56 @@ TEST_CASE("Create image pyramid with custom level sizes", "[fast][ImagePyramid]"
180180
CHECK(pyramid->getLevelScale(1) == Approx(1.5f).margin(0.01));
181181
CHECK(pyramid->getLevelScale(2) == Approx(4.5f).margin(0.01));
182182
}
183+
184+
TEST_CASE("Create image pyramid with custom level sizes including level 0", "[fast][ImagePyramid]") {
185+
std::vector<Vector2i> sizes = {
186+
{22000, 13000},
187+
{22000/1.5f, 13000/1.5f},
188+
{22000/4.5f, 13000/4.5f}
189+
};
190+
auto pyramid = ImagePyramid::create(22000, 13000, 1, 512, 512, ImageCompression::JPEG, 90,
191+
fast::TYPE_UINT8, {}, sizes);
192+
193+
CHECK(pyramid->getNrOfLevels() == 3);
194+
CHECK(pyramid->getWidth() == 22000);
195+
CHECK(pyramid->getHeight() == 13000);
196+
CHECK(pyramid->getLevelWidth(1) == sizes[1].x());
197+
CHECK(pyramid->getLevelHeight(1) == sizes[1].y());
198+
CHECK(pyramid->getLevelWidth(2) == sizes[2].x());
199+
CHECK(pyramid->getLevelHeight(2) == sizes[2].y());
200+
CHECK_THROWS(pyramid->getLevelWidth(3));
201+
CHECK(pyramid->getDataType() == TYPE_UINT8);
202+
CHECK(pyramid->getLevelTileWidth(0) == 512);
203+
CHECK(pyramid->getLevelTileHeight(0) == 512);
204+
CHECK(pyramid->getCompression() == ImageCompression::JPEG);
205+
CHECK(pyramid->getNrOfChannels() == 1);
206+
CHECK(pyramid->getLevelScale(0) == Approx(1.0f).margin(0.01));
207+
CHECK(pyramid->getLevelScale(1) == Approx(1.5f).margin(0.01));
208+
CHECK(pyramid->getLevelScale(2) == Approx(4.5f).margin(0.01));
209+
}
210+
211+
TEST_CASE("Invalid level sizes", "[fast][ImagePyramid]") {
212+
std::vector<Vector2i> sizes = {
213+
{24000, 13000},
214+
{128, 128}
215+
};
216+
CHECK_THROWS(
217+
auto pyramid = ImagePyramid::create(22000, 13000, 1, 512, 512, ImageCompression::JPEG, 90,
218+
fast::TYPE_UINT8, {}, sizes);
219+
);
220+
221+
}
222+
223+
TEST_CASE("getLevelSizes", "[fast][ImagePyramid]") {
224+
std::vector<Vector2i> sizes = {
225+
{22000, 13000},
226+
{22000/1.5f, 13000/1.5f},
227+
{22000/4.5f, 13000/4.5f}
228+
};
229+
auto pyramid = ImagePyramid::create(22000, 13000, 1, 512, 512, ImageCompression::JPEG, 90,
230+
fast::TYPE_UINT8, {}, sizes);
231+
auto levelSizes = pyramid->getLevelSizes();
232+
for(int i = 0; i < 3; ++i) {
233+
CHECK(levelSizes[i] == sizes[i]);
234+
}
235+
}

0 commit comments

Comments
 (0)