diff --git a/src/matutils.cpp b/src/matutils.cpp index 87fd937..0a8df9b 100644 --- a/src/matutils.cpp +++ b/src/matutils.cpp @@ -351,3 +351,62 @@ void removeEmptyFrontBackCols(cv::Mat& mat) if(frontRej || backRej) removeEmptyFrontBackCols(mat); } + +static float linInterpolate(float A, float B, float x) +{ + return A * (1.0f - x) + B * x; +} + +template static Type resizePointBilinear(const cv::Mat& inImage, float scaledX, float scaledY, + float xFrac, float yFrac) +{ + int u0 = static_cast(scaledX); + int v0 = static_cast(scaledY); + int u1 = std::min(inImage.cols-1, static_cast(scaledX+1)); + int v1 = v0; + int u2 = u0; + int v2 = std::min(inImage.rows-1, static_cast(scaledY+1)); + int u3 = std::min(inImage.cols-1, static_cast(scaledX+1)); + int v3 = std::min(inImage.rows-1, static_cast(scaledY+1)); + + float col0 = linInterpolate(inImage.at(v0, u0), inImage.at(v1, u1), xFrac); + float col1 = linInterpolate(inImage.at(v2, u2), inImage.at(v3, u3), xFrac); + float value = linInterpolate(col0, col1, yFrac); + + return cv::saturate_cast(value); +} + +template static void resize(const cv::Mat& inImage, cv::Mat& outImage) +{ + float scaleY = (inImage.rows - 1) / static_cast(outImage.rows - 1); + float scaleX = (inImage.cols - 1) / static_cast(outImage.cols - 1); + + for (int y = 0; y < outImage.rows; ++y) + { + float scaledY = y * scaleY; + float yFrac = scaledY - static_cast(scaledY); + + for (int x = 0; x < outImage.cols; x++) + { + float scaledX = x * scaleX; + float xFrac = scaledX - static_cast(scaledX); + + outImage.at(y, x) = resizePointBilinear(inImage, scaledX, scaledY, xFrac, yFrac); + } + } +} + +bool bilinearResize(const cv::Mat& inImage, cv::Mat& outImage, const cv::Size size) +{ + if (!(inImage.type() == CV_8U || inImage.type() == CV_32F) || + size.width < 2 || size.height < 2 || inImage.cols < 2 || inImage.rows < 2) + return false; + + outImage = cv::Mat::zeros(size.height, size.width, inImage.type()); + + if(inImage.type() == CV_8U) + resize(inImage, outImage); + else if(inImage.type() == CV_32F) + resize(inImage, outImage); + return true; +} diff --git a/src/matutils.h b/src/matutils.h index bb195e1..618ca9e 100644 --- a/src/matutils.h +++ b/src/matutils.h @@ -30,8 +30,8 @@ std::vector::iterator getBottomRight(std::vector& poin double distance(const cv::Point2f& a, const cv::Point2f& b); bool findClosest(size_t& xIndex, size_t& yIndex, - const cv::Point2f point, const std::vector< std::vector >& array, - float xTolerance, float yTolerance); + const cv::Point2f point, const std::vector< std::vector >& array, + float xTolerance, float yTolerance); bool findClosest(size_t& index, const cv::Point2f point, const std::vector& array, float xTolerance, float yTolerance); @@ -47,4 +47,7 @@ bool deleteEmptyCols(cv::Mat& mat); void removeEmptyFrontBackCols(cv::Mat& mat); +bool bilinearResize(const cv::Mat& inImage, cv::Mat& outImage, cv::Size size); + +