Skip to content

Commit

Permalink
Custom version of cv::warpAffine for small sizes, fix #6
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Mar 29, 2024
1 parent 15917cd commit 25ceb96
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
32 changes: 31 additions & 1 deletion src/immvision/internal/cv/zoom_pan_transform.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "immvision/internal/cv/zoom_pan_transform.h"
#include "immvision/internal/misc/math_utils.h"

#include <opencv2/imgproc.hpp>

namespace ImmVision
{
namespace ZoomPanTransform
Expand Down Expand Up @@ -162,6 +164,35 @@ namespace ImmVision
return roi;
}

// Custom version of cv::warpAffine for small sizes, since cv::warpAffine happily ignores cv::INTER_AREA
// cf https://github.com/pthom/immvision/issues/6 and
// cf https://github.com/opencv/opencv/blob/4.x/modules/imgproc/src/imgwarp.cpp#L2826-L2827
void _WarpAffineInterAreaForSmallSizes(const cv::Mat& src, cv::Mat& dst, const cv::Matx33d& m)
{
// Since in our case, we are only dealing with transformations that do not modify
// the orientation of the vertical arrow and horizontal axes, we take the easy route:
// first resize the image and then place it at the correct location in the final image.


// first, compute the resized image size by using the transformation matrix.
cv::Point2d tl = ZoomPanTransform::Apply(m, cv::Point2d(0., 0.));
cv::Point2d br = ZoomPanTransform::Apply(m, cv::Point2d((double)src.cols, (double)src.rows));
cv::Size resizedSize(MathUtils::RoundInt(br.x - tl.x), MathUtils::RoundInt(br.y - tl.y));

// then, resize the image
cv::Mat resized;
cv::resize(src, resized, resizedSize, 0, 0, cv::INTER_AREA);

// then, place the resized image at the correct location in the final image.
cv::Matx23d translation = cv::Matx23d::eye();
translation(0, 2) = tl.x;
translation(1, 2) = tl.y;


cv::warpAffine(resized, dst, translation, dst.size(), cv::INTER_AREA);
}


} // namespace ZoomPanTransform

cv::Matx33d MakeZoomPanMatrix(const cv::Point2d & zoomCenter, double zoomRatio, const cv::Size displayedImageSize)
Expand All @@ -182,5 +213,4 @@ namespace ImmVision
{
return ZoomPanTransform::MakeFullView(imageSize, displayedImageSize);
}

}
7 changes: 6 additions & 1 deletion src/immvision/internal/cv/zoom_pan_transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ namespace ImmVision
cv::Size originalImageSize
);

} // namespace ZoomPanTransform
// Custom version of cv::warpAffine for small sizes, since cv::warpAffine happily ignores cv::INTER_AREA
// cf https://github.com/pthom/immvision/issues/6 and
// cf https://github.com/opencv/opencv/blob/4.x/modules/imgproc/src/imgwarp.cpp#L2826-L2827
void _WarpAffineInterAreaForSmallSizes(const cv::Mat& src, cv::Mat& dst, const cv::Matx33d& m);

} // namespace ZoomPanTransform

cv::Matx33d MakeZoomPanMatrix(const cv::Point2d & zoomCenter, double zoomRatio, const cv::Size displayedImageSize);

Expand Down
28 changes: 21 additions & 7 deletions src/immvision/internal/drawing/image_drawing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "immvision/internal/cv/colormap.h"

#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>


namespace ImmVision
Expand Down Expand Up @@ -251,13 +252,26 @@ namespace ImmVision
warpInterpolationFlags = cv::INTER_NEAREST;

cv::Mat backgroundWithImage = fnMakeBackground();
cv::warpAffine(finalImage, backgroundWithImage,
ZoomPanTransform::ZoomMatrixToM23(params.ZoomPanMatrix),
params.ImageDisplaySize,
warpInterpolationFlags,
cv::BorderTypes::BORDER_TRANSPARENT,
cv::Scalar(127, 127, 127, 127)
);

// Use custom version of cv::warpAffine for small sizes,
// since cv::warpAffine happily ignores cv::INTER_AREA
if (zoomFactor < 1.)
{
ZoomPanTransform::_WarpAffineInterAreaForSmallSizes(
finalImage,
backgroundWithImage,
params.ZoomPanMatrix);
}
else
{
cv::warpAffine(finalImage, backgroundWithImage,
ZoomPanTransform::ZoomMatrixToM23(params.ZoomPanMatrix),
params.ImageDisplaySize,
warpInterpolationFlags,
cv::BorderTypes::BORDER_TRANSPARENT,
cv::Scalar(127, 127, 127, 127)
);
}
finalImage = backgroundWithImage;
}

Expand Down

0 comments on commit 25ceb96

Please sign in to comment.