Skip to content

Commit 1a27a35

Browse files
committed
Fixed issue with PatchGenerator and PatchStitcher when creating patches at the first row and column when overlap > 0
1 parent 8dcc1de commit 1a27a35

File tree

3 files changed

+21
-27
lines changed

3 files changed

+21
-27
lines changed

source/FAST/Algorithms/ImagePatch/PatchGenerator.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void PatchGenerator::generateStream() {
8484
try {
8585
std::tie(level, resampleFactor) = m_inputImagePyramid->getClosestLevelForMagnification(m_magnification, 0.1);
8686
if(resampleFactor != 1.0f)
87-
reportWarning() << "Requested magnification level does not exist in image pyramid. " <<
87+
reportWarning() << "Requested magnification " << m_magnification << " does not exist in a level of the image pyramid. " <<
8888
"Will now try to sample from a lower level and resize. This may increase runtime." << reportEnd();
8989
} catch(Exception &e) {
9090
throw Exception("Unable to generate patches for magnification level " +
@@ -121,13 +121,7 @@ void PatchGenerator::generateStream() {
121121
patchHeight = levelHeight - (patchY * patchHeightWithoutOverlap - overlapInPixelsY)*resampleFactor;
122122
}
123123
int patchOffsetX = (patchX * patchWidthWithoutOverlap - overlapInPixelsX)*resampleFactor;
124-
if(patchX == 0 && overlapInPixelsX > 0) {
125-
patchOffsetX = 0;
126-
}
127124
int patchOffsetY = (patchY * patchHeightWithoutOverlap - overlapInPixelsY)*resampleFactor;
128-
if(patchY == 0 && overlapInPixelsY > 0) {
129-
patchOffsetY = 0;
130-
}
131125

132126
if(m_inputMask) {
133127
// If a mask exist, check if this patch should be included or not
@@ -160,10 +154,10 @@ void PatchGenerator::generateStream() {
160154
if(patchWidth < overlapInPixelsX*2 || patchHeight < overlapInPixelsY*2)
161155
continue;
162156
auto patch = access->getPatchAsImage(level,
163-
patchOffsetX,
164-
patchOffsetY,
165-
patchWidth,
166-
patchHeight);
157+
patchOffsetX < 0 ? 0 : patchOffsetX, // if there is overlap, we will have negative offset at edges
158+
patchOffsetY < 0 ? 0 : patchOffsetY,
159+
patchWidth + (patchOffsetX < 0 ? patchOffsetX : 0), // We have to reduce width and height if negative offset
160+
patchHeight + (patchOffsetY < 0 ? patchOffsetY : 0));
167161

168162
// If patch does not have correct size, pad it
169163
int paddingValue = m_paddingValue;
@@ -174,18 +168,13 @@ void PatchGenerator::generateStream() {
174168
paddingValue = 0;
175169
}
176170
}
177-
if(patch->getWidth() != (int)(m_width*resampleFactor) || patch->getHeight() != (int)(m_height*resampleFactor)) {
171+
if(patchOffsetX < 0 || patchOffsetY < 0 || patch->getWidth() != (int)(m_width*resampleFactor) || patch->getHeight() != (int)(m_height*resampleFactor)) {
178172
// Edge cases, patches may not be the target patch size. Need to pad.
179-
patch = patch->crop(Vector2i(0, 0), Vector2i(m_width*resampleFactor, m_height*resampleFactor), true, paddingValue);
173+
patch = patch->crop(Vector2i(patchOffsetX < 0 ? patchOffsetX : 0, patchOffsetY < 0 ? patchOffsetY : 0), Vector2i(m_width*resampleFactor, m_height*resampleFactor), true, paddingValue);
180174
}
181175
if(resampleFactor > 1.0f) {
182176
patch = ImageResizer::create(m_width, m_height, 1, m_inputImagePyramid->getNrOfChannels() > 1)->connect(patch)->runAndGetOutputData<Image>();
183177
}
184-
if(m_overlapPercent > 0.0f && (patchX == 0 || patchY == 0)) {
185-
int offsetX = patchX == 0 ? -overlapInPixelsX : 0;
186-
int offsetY = patchY == 0 ? -overlapInPixelsY : 0;
187-
patch = patch->crop(Vector2i(offsetX, offsetY), Vector2i(m_width, m_height), true, paddingValue);
188-
}
189178

190179
// Store some frame data useful for patch stitching
191180
patch->setFrameData("original-width", std::to_string(round(levelWidth/resampleFactor)));

source/FAST/Algorithms/ImagePatch/PatchStitcher.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,12 @@ void PatchStitcher::processImage(std::shared_ptr<Image> patch) {
170170
const int patchOverlapY = std::stoi(patch->getFrameData("patch-overlap-y"));
171171
// Calculate offset. If this calculation is incorrect. Update in ImagePyramidPatchExporter as well.
172172
// Position of where to insert the (cropped) patch
173-
const int startX = std::stoi(patch->getFrameData("patchid-x")) * (std::stoi(patch->getFrameData("patch-width")) - patchOverlapX*2); // TODO + overlap to compensate for start offset
174-
const int startY = std::stoi(patch->getFrameData("patchid-y")) * (std::stoi(patch->getFrameData("patch-height")) - patchOverlapY*2);
173+
const int patchWidth = std::stoi(patch->getFrameData("patch-width"));
174+
const int patchHeight = std::stoi(patch->getFrameData("patch-height"));
175+
const int patchWidthWithoutOverlap = patchWidth - patchOverlapX*2;
176+
const int patchHeightWithoutOverlap = patchHeight - patchOverlapY*2;
177+
const int startX = std::stoi(patch->getFrameData("patchid-x")) * patchWidthWithoutOverlap;
178+
const int startY = std::stoi(patch->getFrameData("patchid-y")) * patchHeightWithoutOverlap;
175179
if(m_outputImage) {
176180
// 2D image
177181
cl::Program program = getOpenCLProgram(device, "2D");
@@ -190,8 +194,8 @@ void PatchStitcher::processImage(std::shared_ptr<Image> patch) {
190194
kernel,
191195
cl::NullRange,
192196
cl::NDRange(
193-
std::min(patch->getWidth(), m_outputImage->getWidth()-startX),
194-
std::min(patch->getHeight(), m_outputImage->getHeight()-startY)
197+
std::min(patchWidthWithoutOverlap, m_outputImage->getWidth()-startX),
198+
std::min(patchHeightWithoutOverlap, m_outputImage->getHeight()-startY)
195199
),
196200
cl::NullRange
197201
);

source/FAST/Algorithms/ImagePatch/PatchStitcher2D.cl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ __kernel void applyPatch2D(
88
__private int patchOverlapX,
99
__private int patchOverlapY
1010
) {
11-
const int2 pos = {get_global_id(0) + startX, get_global_id(1) + startY};
11+
const int2 pos = {get_global_id(0), get_global_id(1)}; // Patch pos
12+
const int2 globalPos = {get_global_id(0) + startX, get_global_id(1) + startY};
1213
int dataType = get_image_channel_data_type(image);
13-
int2 offset = {startX - patchOverlapX, startY - patchOverlapY};
14+
int2 offset = {patchOverlapX, patchOverlapY};
1415
if(dataType == CLK_FLOAT) {
15-
write_imagef(image, pos, read_imagef(patch, sampler, pos - offset));
16+
write_imagef(image, globalPos, read_imagef(patch, sampler, pos + offset));
1617
} else if(dataType == CLK_UNSIGNED_INT8 || dataType == CLK_UNSIGNED_INT16 || dataType == CLK_UNSIGNED_INT32) {
17-
write_imageui(image, pos, read_imageui(patch, sampler, pos - offset));
18+
write_imageui(image, globalPos, read_imageui(patch, sampler, pos + offset));
1819
} else {
19-
write_imagei(image, pos, read_imagei(patch, sampler, pos - offset));
20+
write_imagei(image, globalPos, read_imagei(patch, sampler, pos + offset));
2021
}
2122
}

0 commit comments

Comments
 (0)