Implementation of bit-exact resize. Internal calls to linear resize updated to use bit-exact version. (#9468)

pull/10302/head
Vitaly Tuzov 7 years ago committed by Vadim Pisarevsky
parent 84ee4d701a
commit 51cb56ef2c
  1. 3
      3rdparty/carotene/src/resize.cpp
  2. 2
      apps/annotation/opencv_annotation.cpp
  3. 12
      apps/createsamples/utility.cpp
  4. 4
      apps/traincascade/imagestorage.cpp
  5. 6
      apps/visualisation/opencv_visualisation.cpp
  6. 4
      modules/calib3d/test/test_cameracalibration.cpp
  7. 2
      modules/calib3d/test/test_chessboardgenerator.cpp
  8. 4
      modules/dnn/src/dnn.cpp
  9. 4
      modules/features2d/src/orb.cpp
  10. 2
      modules/features2d/test/test_descriptors_invariance.cpp
  11. 2
      modules/features2d/test/test_detectors_invariance.cpp
  12. 2
      modules/highgui/misc/java/src/java/highgui+ImageWindow.java
  13. 2
      modules/imgcodecs/src/loadsave.cpp
  14. 2
      modules/imgproc/include/opencv2/imgproc.hpp
  15. 2
      modules/imgproc/misc/java/test/ImgprocTest.java
  16. 6
      modules/imgproc/perf/opencl/perf_3vs4.cpp
  17. 2
      modules/imgproc/perf/opencl/perf_imgproc.cpp
  18. 24
      modules/imgproc/perf/opencl/perf_imgwarp.cpp
  19. 4
      modules/imgproc/perf/perf_resize.cpp
  20. 291
      modules/imgproc/src/fixedpoint.inl.hpp
  21. 2
      modules/imgproc/src/lsd.cpp
  22. 652
      modules/imgproc/src/resize.cpp
  23. 8
      modules/imgproc/test/ocl/test_warp.cpp
  24. 2
      modules/imgproc/test/test_canny.cpp
  25. 4
      modules/imgproc/test/test_imgproc_umat.cpp
  26. 25
      modules/imgproc/test/test_imgwarp.cpp
  27. 79
      modules/imgproc/test/test_imgwarp_strict.cpp
  28. 118
      modules/imgproc/test/test_resize_bitexact.cpp
  29. 4
      modules/objdetect/src/cascadedetect.cpp
  30. 2
      modules/objdetect/src/haar.cpp
  31. 6
      modules/objdetect/src/hog.cpp
  32. 4
      modules/photo/src/contrast_preserve.hpp
  33. 4
      modules/photo/src/tonemap.cpp
  34. 2
      modules/python/test/test_facedetect.py
  35. 4
      modules/shape/src/sc_dis.cpp
  36. 4
      modules/stitching/perf/perf_estimators.cpp
  37. 16
      modules/stitching/perf/perf_matchers.cpp
  38. 10
      modules/stitching/src/stitcher.cpp
  39. 2
      modules/ts/include/opencv2/ts/ocl_test.hpp
  40. 6
      modules/video/src/optflowgf.cpp
  41. 26
      modules/video/src/tvl1flow.cpp
  42. 10
      modules/video/test/test_ecc.cpp
  43. 2
      modules/video/test/test_optflowpyrlk.cpp
  44. 2
      samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java
  45. 2
      samples/android/image-manipulations/src/org/opencv/samples/imagemanipulations/ImageManipulationsActivity.java
  46. 2
      samples/cpp/3calibration.cpp
  47. 2
      samples/cpp/bgfg_segm.cpp
  48. 2
      samples/cpp/facedetect.cpp
  49. 2
      samples/cpp/image_alignment.cpp
  50. 6
      samples/cpp/shape_example.cpp
  51. 2
      samples/cpp/smiledetect.cpp
  52. 4
      samples/cpp/stereo_calib.cpp
  53. 8
      samples/cpp/stitching_detailed.cpp
  54. 2
      samples/cpp/train_HOG.cpp
  55. 2
      samples/dnn/fcn_semsegm.cpp
  56. 2
      samples/tapi/hog.cpp
  57. 2
      samples/tapi/ufacedetect.cpp

@ -106,7 +106,8 @@ bool isResizeLinearOpenCVSupported(const Size2D &ssize, const Size2D &dsize, u32
&& !(ssize.width > 0xffffFFFF || ssize.height > 0xffffFFFF)// Restrict image size since internal index evaluation
// is performed with u32
#endif
&& dsize.width >= 2 && dsize.height >= 8)
&& dsize.width >= 2 && dsize.height >= 8
&& (2*dsize.width != ssize.width || 2*dsize.height != ssize.height)) // 2x downscaling is performed as area in OpenCV which differs from this implementation
return isSupportedConfiguration();
default:
return false;

@ -273,7 +273,7 @@ int main( int argc, const char** argv )
}
if(resize_bool){
resize(current_image, current_image, Size(current_image.cols/resizeFactor, current_image.rows/resizeFactor));
resize(current_image, current_image, Size(current_image.cols/resizeFactor, current_image.rows/resizeFactor), 0, 0, INTER_LINEAR_EXACT);
}
// Perform annotations & store the result inside the vectorized structure

@ -686,8 +686,8 @@ void icvPlaceDistortedSample( Mat background,
Mat img( background.size(), CV_8UC1 );
Mat maskimg( background.size(), CV_8UC1 );
resize( data->img(roi), img, img.size(), 0, 0, INTER_LINEAR);
resize( data->maskimg(roi), maskimg, maskimg.size(), 0, 0, INTER_LINEAR);
resize( data->img(roi), img, img.size(), 0, 0, INTER_LINEAR_EXACT);
resize( data->maskimg(roi), maskimg, maskimg.size(), 0, 0, INTER_LINEAR_EXACT);
forecolordev = (int) (maxintensitydev * (2.0 * rand() / RAND_MAX - 1.0));
@ -877,7 +877,7 @@ void icvGetNextFromBackgroundData( CvBackgroundData* data,
((float) data->winsize.height + reader->point.y) / ((float) reader->src.rows) );
resize( reader->src, reader->img,
Size((int)(reader->scale * reader->src.rows + 0.5F), (int)(reader->scale * reader->src.cols + 0.5F)), 0, 0, INTER_LINEAR );
Size((int)(reader->scale * reader->src.rows + 0.5F), (int)(reader->scale * reader->src.cols + 0.5F)), 0, 0, INTER_LINEAR_EXACT );
}
/*
@ -932,7 +932,7 @@ void icvGetBackgroundImage( CvBackgroundData* data,
if( reader->scale <= 1.0F )
{
resize(reader->src, reader->img,
Size((int)(reader->scale * reader->src.rows), (int)(reader->scale * reader->src.cols)), 0, 0, INTER_LINEAR);
Size((int)(reader->scale * reader->src.rows), (int)(reader->scale * reader->src.cols)), 0, 0, INTER_LINEAR_EXACT);
}
else
{
@ -1323,7 +1323,7 @@ int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilena
if( error ) break;
Mat sample;
resize( src(Rect(x, y, width, height)), sample, Size(winwidth, winheight), 0, 0,
width >= winwidth && height >= winheight ? INTER_AREA : INTER_LINEAR );
width >= winwidth && height >= winheight ? INTER_AREA : INTER_LINEAR_EXACT );
if( showsamples )
{
@ -1452,7 +1452,7 @@ void cvShowVecSamples( const char* filename, int winwidth, int winheight,
icvGetTraininDataFromVec( sample, file );
if( scale != 1.0 )
resize( sample, sample,
Size(MAX(1, cvCeil(scale * winheight)), MAX(1, cvCeil(scale * winwidth))), 0, 0, INTER_LINEAR);
Size(MAX(1, cvCeil(scale * winheight)), MAX(1, cvCeil(scale * winwidth))), 0, 0, INTER_LINEAR_EXACT);
imshow( "Sample", sample );
if( (waitKey( 0 ) & 0xFF) == 27 ) break;
}

@ -77,7 +77,7 @@ bool CvCascadeImageReader::NegReader::nextImg()
((float)winSize.height + point.y) / ((float)src.rows) );
Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
resize( src, img, sz );
resize( src, img, sz, 0, 0, INTER_LINEAR_EXACT );
return true;
}
@ -108,7 +108,7 @@ bool CvCascadeImageReader::NegReader::get( Mat& _img )
point.y = offset.y;
scale *= scaleFactor;
if( scale <= 1.0F )
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ), 0, 0, INTER_LINEAR_EXACT );
else
{
if ( !nextImg() )

@ -142,7 +142,7 @@ int main( int argc, const char** argv )
return -1;
}
Mat visualization;
resize(reference_image, visualization, Size(reference_image.cols * resize_factor, reference_image.rows * resize_factor));
resize(reference_image, visualization, Size(reference_image.cols * resize_factor, reference_image.rows * resize_factor), 0, 0, INTER_LINEAR_EXACT);
// First recover for each stage the number of weak features and their index
// Important since it is NOT sequential when using LBP features
@ -220,7 +220,7 @@ int main( int argc, const char** argv )
int current_feature_index = stage_features[sid][fid];
current_rects = feature_data[current_feature_index];
Mat single_feature = reference_image.clone();
resize(single_feature, single_feature, Size(), resize_storage_factor, resize_storage_factor);
resize(single_feature, single_feature, Size(), resize_storage_factor, resize_storage_factor, INTER_LINEAR_EXACT);
for(int i = 0; i < (int)current_rects.size(); i++){
rect_data local = current_rects[i];
if(draw_planes){
@ -293,7 +293,7 @@ int main( int argc, const char** argv )
int current_feature_index = stage_features[sid][fid];
Rect current_rect = feature_data[current_feature_index];
Mat single_feature = reference_image.clone();
resize(single_feature, single_feature, Size(), resize_storage_factor, resize_storage_factor);
resize(single_feature, single_feature, Size(), resize_storage_factor, resize_storage_factor, INTER_LINEAR_EXACT);
// VISUALISATION
// The rectangle is the top left one of a 3x3 block LBP constructor

@ -1431,10 +1431,10 @@ void CV_StereoCalibrationCornerTest::run(int)
// perform remap-resize
Mat src_result;
remap(image, src_result, srcRmap[0], srcRmap[1], INTER_LINEAR);
resize(src_result, src_result, Size(), scale, scale, INTER_LINEAR);
resize(src_result, src_result, Size(), scale, scale, INTER_LINEAR_EXACT);
// perform resize-remap
Mat rsz_result;
resize(image, rsz_result, Size(), scale, scale, INTER_LINEAR);
resize(image, rsz_result, Size(), scale, scale, INTER_LINEAR_EXACT);
remap(rsz_result, rsz_result, rszRmap[0], rszRmap[1], INTER_LINEAR);
// modifying the camera matrix with resizeCameraMatrix must yield the same

@ -169,7 +169,7 @@ Mat cv::ChessBoardGenerator::generateChessBoard(const Mat& bg, const Mat& camMat
else
{
Mat tmp;
resize(bg, tmp, bg.size() * rendererResolutionMultiplier);
resize(bg, tmp, bg.size() * rendererResolutionMultiplier, 0, 0, INTER_LINEAR_EXACT);
drawContours(tmp, whole_contour, -1, Scalar::all(255), FILLED, LINE_AA);
drawContours(tmp, squares_black, -1, Scalar::all(0), FILLED, LINE_AA);
resize(tmp, result, bg.size(), 0, 0, INTER_AREA);

@ -108,14 +108,14 @@ Mat blobFromImages(const std::vector<Mat>& images_, double scalefactor, Size siz
{
float resizeFactor = std::max(size.width / (float)imgSize.width,
size.height / (float)imgSize.height);
resize(images[i], images[i], Size(), resizeFactor, resizeFactor);
resize(images[i], images[i], Size(), resizeFactor, resizeFactor, INTER_LINEAR);
Rect crop(Point(0.5 * (images[i].cols - size.width),
0.5 * (images[i].rows - size.height)),
size);
images[i] = images[i](crop);
}
else
resize(images[i], images[i], size);
resize(images[i], images[i], size, 0, 0, INTER_LINEAR);
}
if(images[i].depth() == CV_8U)
images[i].convertTo(images[i], CV_32F);

@ -1060,10 +1060,10 @@ void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask,
// Compute the resized image
if( level != firstLevel )
{
resize(prevImg, currImg, sz, 0, 0, INTER_LINEAR);
resize(prevImg, currImg, sz, 0, 0, INTER_LINEAR_EXACT);
if( !mask.empty() )
{
resize(prevMask, currMask, sz, 0, 0, INTER_LINEAR);
resize(prevMask, currMask, sz, 0, 0, INTER_LINEAR_EXACT);
if( level > firstLevel )
threshold(currMask, currMask, 254, 0, THRESH_TOZERO);
}

@ -132,7 +132,7 @@ TEST_P(DescriptorScaleInvariance, scale)
float scale = 1.f + scaleIdx * 0.5f;
Mat image1;
resize(image0, image1, Size(), 1./scale, 1./scale);
resize(image0, image1, Size(), 1./scale, 1./scale, INTER_LINEAR_EXACT);
vector<KeyPoint> keypoints1;
scaleKeyPoints(keypoints0, keypoints1, 1.0f/scale);

@ -166,7 +166,7 @@ TEST_P(DetectorScaleInvariance, scale)
{
float scale = 1.f + scaleIdx * 0.5f;
Mat image1;
resize(image0, image1, Size(), 1./scale, 1./scale);
resize(image0, image1, Size(), 1./scale, 1./scale, INTER_LINEAR_EXACT);
vector<KeyPoint> keypoints1, osiKeypoints1; // osi - original size image
featureDetector->detect(image1, keypoints1);

@ -126,7 +126,7 @@ public final class ImageWindow {
private void resizeImage() {
if (flag == WINDOW_NORMAL) {
Size tmpSize = keepAspectRatioSize(img.width(), img.height(), width, height);
Imgproc.resize(img, img, tmpSize);
Imgproc.resize(img, img, tmpSize, 0, 0, Imgproc.INTER_LINEAR_EXACT);
}
}
}

@ -506,7 +506,7 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
if( decoder->setScale( scale_denom ) > 1 ) // if decoder is JpegDecoder then decoder->setScale always returns 1
{
resize( *mat, *mat, Size( size.width / scale_denom, size.height / scale_denom ) );
resize( *mat, *mat, Size( size.width / scale_denom, size.height / scale_denom ), 0, 0, INTER_LINEAR_EXACT);
}
return hdrtype == LOAD_CVMAT ? (void*)matrix :

@ -279,6 +279,8 @@ enum InterpolationFlags{
INTER_AREA = 3,
/** Lanczos interpolation over 8x8 neighborhood */
INTER_LANCZOS4 = 4,
/** Bit exact bilinear interpolation */
INTER_LINEAR_EXACT = 5,
/** mask for interpolation codes */
INTER_MAX = 7,
/** flag, fills all of the destination image pixels. If some of them correspond to outliers in the

@ -1617,7 +1617,7 @@ public class ImgprocTest extends OpenCVTestCase {
Mat src = new Mat(imgprocSz, imgprocSz, CvType.CV_8UC1, new Scalar(1));
Size dsize = new Size(1, 1);
Imgproc.resize(src, dst, dsize);
Imgproc.resize(src, dst, dsize, 0, 0, Imgproc.INTER_LINEAR_EXACT);
truth = new Mat(1, 1, CvType.CV_8UC1, new Scalar(1));
assertMatEqual(truth, dst);

@ -40,7 +40,7 @@ OCL_PERF_TEST_P(_3vs4_Fixture, Resize,
if (mode == Pure)
{
OCL_TEST_CYCLE() resize(src, dst, Size(), 0.5, 0.5, INTER_LINEAR);
OCL_TEST_CYCLE() resize(src, dst, Size(), 0.5, 0.5, INTER_LINEAR_EXACT);
}
else if (mode == Split)
{
@ -57,7 +57,7 @@ OCL_PERF_TEST_P(_3vs4_Fixture, Resize,
split(src, srcs);
for (size_t i = 0; i < srcs.size(); ++i)
resize(srcs[i], dsts[i], Size(), 0.5, 0.5, INTER_LINEAR);
resize(srcs[i], dsts[i], Size(), 0.5, 0.5, INTER_LINEAR_EXACT);
merge(dsts, dst);
}
@ -70,7 +70,7 @@ OCL_PERF_TEST_P(_3vs4_Fixture, Resize,
OCL_TEST_CYCLE()
{
cvtColor(src, src4, COLOR_RGB2RGBA);
resize(src4, dst4, Size(), 0.5, 0.5, INTER_LINEAR);
resize(src4, dst4, Size(), 0.5, 0.5, INTER_LINEAR_EXACT);
cvtColor(dst4, dst, COLOR_RGBA2RGB);
}
}

@ -311,7 +311,7 @@ OCL_PERF_TEST_P(CannyFixture, Canny, ::testing::Combine(OCL_TEST_SIZES, OCL_PERF
ASSERT_TRUE(!_img.empty()) << "can't open aloe-L.png";
UMat img;
cv::resize(_img, img, imgSize);
cv::resize(_img, img, imgSize, 0, 0, INTER_LINEAR_EXACT);
UMat edges(img.size(), CV_8UC1);
declare.in(img).out(edges);

@ -168,6 +168,30 @@ OCL_PERF_TEST_P(ResizeAreaFixture, Resize,
SANITY_CHECK(dst, eps);
}
typedef ResizeAreaParams ResizeLinearExactParams;
typedef TestBaseWithParam<ResizeLinearExactParams> ResizeLinearExactFixture;
OCL_PERF_TEST_P(ResizeLinearExactFixture, Resize,
::testing::Combine(OCL_TEST_SIZES, ::testing::Values(CV_8UC1, CV_8UC3, CV_8UC4), ::testing::Values(0.5, 2.0)))
{
const ResizeAreaParams params = GetParam();
const Size srcSize = get<0>(params);
const int type = get<1>(params);
double scale = get<2>(params);
const Size dstSize(cvRound(srcSize.width * scale), cvRound(srcSize.height * scale));
const double eps = 1e-4;
checkDeviceMaxMemoryAllocSize(srcSize, type);
checkDeviceMaxMemoryAllocSize(dstSize, type);
UMat src(srcSize, type), dst(dstSize, type);
declare.in(src, WARMUP_RNG).out(dst);
OCL_TEST_CYCLE() cv::resize(src, dst, Size(), scale, scale, cv::INTER_LINEAR_EXACT);
SANITY_CHECK(dst, eps);
}
///////////// Remap ////////////////////////
typedef tuple<Size, MatType, InterType> RemapParams;

@ -25,7 +25,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeUpLinear,
cvtest::fillGradient(src);
declare.in(src).out(dst);
TEST_CYCLE_MULTIRUN(10) resize(src, dst, to);
TEST_CYCLE_MULTIRUN(10) resize(src, dst, to, 0, 0, INTER_LINEAR_EXACT);
#ifdef __ANDROID__
SANITY_CHECK(dst, 5);
@ -52,7 +52,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear,
cvtest::fillGradient(src);
declare.in(src).out(dst);
TEST_CYCLE_MULTIRUN(10) resize(src, dst, to);
TEST_CYCLE_MULTIRUN(10) resize(src, dst, to, 0, 0, INTER_LINEAR_EXACT);
#ifdef __ANDROID__
SANITY_CHECK(dst, 5);

@ -0,0 +1,291 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#ifndef _CV_FIXEDPOINT_HPP_
#define _CV_FIXEDPOINT_HPP_
#include "opencv2/core/softfloat.hpp"
#ifndef CV_ALWAYS_INLINE
#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define CV_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define CV_ALWAYS_INLINE __forceinline
#else
#define CV_ALWAYS_INLINE inline
#endif
#endif
namespace
{
class fixedpoint64
{
private:
static const int fixedShift = 32;
int64_t val;
fixedpoint64(int64_t _val) : val(_val) {}
static CV_ALWAYS_INLINE uint64_t fixedround(const uint64_t& _val) { return (_val + ((1LL << fixedShift) >> 1)); }
public:
typedef fixedpoint64 WT;
CV_ALWAYS_INLINE fixedpoint64() { val = 0; }
CV_ALWAYS_INLINE fixedpoint64(const int8_t& _val) { val = ((int64_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint64(const int16_t& _val) { val = ((int64_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint64(const int32_t& _val) { val = ((int64_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint64(const cv::softdouble& _val) { val = cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); }
CV_ALWAYS_INLINE fixedpoint64& operator = (const int8_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint64& operator = (const int16_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint64& operator = (const int32_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint64& operator = (const cv::softdouble& _val) { val = cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); return *this; }
CV_ALWAYS_INLINE fixedpoint64& operator = (const fixedpoint64& _val) { val = _val.val; return *this; }
template <typename ET>
CV_ALWAYS_INLINE fixedpoint64 operator * (const ET& val2) const { return val * val2; } // Wrong rounding is possible for floating point types
CV_ALWAYS_INLINE fixedpoint64 operator * (const fixedpoint64& val2) const
{
//Assume -0x00000000C0000000 <= val2 <=0x0000000100000000 INT64_MIN <= val <= INT64_MAX, so shifted multiplication result is inside [INT64_MIN, INT64_MAX] range
uint64_t uval = (uint64_t)((val ^ (val >> 63)) - (val >> 63));
uint64_t umul = (uint64_t)((val2.val ^ (val2.val >> 63)) - (val2.val >> 63));
int64_t ressign = (val >> 63) ^ (val2.val >> 63);
uint64_t sh0 = fixedround((uval & 0xFFFFFFFF) * (umul & 0xFFFFFFFF));
uint64_t sh1_0 = (uval >> 32) * (umul & 0xFFFFFFFF);
uint64_t sh1_1 = (uval & 0xFFFFFFFF) * (umul >> 32);
uint64_t sh2 = (uval >> 32) * (umul >> 32);
uint64_t val0_l = (sh1_0 & 0xFFFFFFFF) + (sh1_1 & 0xFFFFFFFF) + (sh0 >> 32);
uint64_t val0_h = (sh2 & 0xFFFFFFFF) + (sh1_0 >> 32) + (sh1_1 >> 32) + (val0_l >> 32);
val0_l &= 0xFFFFFFFF;
if (ressign)
{
val0_l = (~val0_l + 1) & 0xFFFFFFFF;
val0_h = val0_l ? ~val0_h : (~val0_h + 1);
}
return (int64_t)(val0_h << 32 | val0_l);
}
CV_ALWAYS_INLINE fixedpoint64 operator + (const fixedpoint64& val2) const { return fixedpoint64(val + val2.val); }
CV_ALWAYS_INLINE fixedpoint64 operator - (const fixedpoint64& val2) const { return fixedpoint64(val - val2.val); }
// CV_ALWAYS_INLINE fixedpoint64 operator + (const fixedpoint64& val2) const
// {
// int64_t nfrac = (int64_t)frac + val2.frac;
// int64_t nval = (int64_t)val + val2.val + nfrac >> 32;
// return nval > MAXINT32 ? beConv(MAXINT32, MAXINT32) : beConv((int32_t)(nval), 0);
// }
template <typename ET>
CV_ALWAYS_INLINE operator ET() const { return cv::saturate_cast<ET>((int64_t)fixedround((uint64_t)val) >> fixedShift); }
CV_ALWAYS_INLINE operator double() const { return (double)val / (1LL << fixedShift); }
CV_ALWAYS_INLINE operator float() const { return (float)val / (1LL << fixedShift); }
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
static CV_ALWAYS_INLINE fixedpoint64 zero() { return fixedpoint64(); }
static CV_ALWAYS_INLINE fixedpoint64 one() { return fixedpoint64((int64_t)(1LL << fixedShift)); }
friend class fixedpoint32;
};
class ufixedpoint64
{
private:
static const int fixedShift = 32;
uint64_t val;
ufixedpoint64(uint64_t _val) : val(_val) {}
static CV_ALWAYS_INLINE uint64_t fixedround(const uint64_t& _val) { return (_val + ((1LL << fixedShift) >> 1)); }
public:
typedef ufixedpoint64 WT;
CV_ALWAYS_INLINE ufixedpoint64() { val = 0; }
CV_ALWAYS_INLINE ufixedpoint64(const uint8_t& _val) { val = ((uint64_t)_val) << fixedShift; }
CV_ALWAYS_INLINE ufixedpoint64(const uint16_t& _val) { val = ((uint64_t)_val) << fixedShift; }
CV_ALWAYS_INLINE ufixedpoint64(const uint32_t& _val) { val = ((uint64_t)_val) << fixedShift; }
CV_ALWAYS_INLINE ufixedpoint64(const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint64_t)cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); }
CV_ALWAYS_INLINE ufixedpoint64& operator = (const uint8_t& _val) { val = ((uint64_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE ufixedpoint64& operator = (const uint16_t& _val) { val = ((uint64_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE ufixedpoint64& operator = (const uint32_t& _val) { val = ((uint64_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE ufixedpoint64& operator = (const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint64_t)cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); return *this; }
CV_ALWAYS_INLINE ufixedpoint64& operator = (const ufixedpoint64& _val) { val = _val.val; return *this; }
template <typename ET>
CV_ALWAYS_INLINE ufixedpoint64 operator * (const ET& val2) const { return val * val2; } // Wrong rounding is possible for floating point types
CV_ALWAYS_INLINE ufixedpoint64 operator * (const ufixedpoint64& val2) const
{
//Assume val2 <=0x0000000100000000, so shifted multiplication result is less than val and therefore than UINT64_MAX
uint64_t sh0 = fixedround((val & 0xFFFFFFFF) * (val2.val & 0xFFFFFFFF));
uint64_t sh1_0 = (val >> 32) * (val2.val & 0xFFFFFFFF);
uint64_t sh1_1 = (val & 0xFFFFFFFF) * (val2.val >> 32);
uint64_t sh2 = (val >> 32) * (val2.val >> 32);
uint64_t val0_l = (sh1_0 & 0xFFFFFFFF) + (sh1_1 & 0xFFFFFFFF) + (sh0 >> 32);
uint64_t val0_h = (sh2 & 0xFFFFFFFF) + (sh1_0 >> 32) + (sh1_1 >> 32) + (val0_l >> 32);
val0_l &= 0xFFFFFFFF;
return val0_h << 32 | val0_l;
}
CV_ALWAYS_INLINE ufixedpoint64 operator + (const ufixedpoint64& val2) const { return ufixedpoint64(val + val2.val); }
CV_ALWAYS_INLINE ufixedpoint64 operator - (const ufixedpoint64& val2) const { return ufixedpoint64(val - val2.val); }
// CV_ALWAYS_INLINE fixedpoint64 operator + (const fixedpoint64& val2) const
// {
// int64_t nfrac = (int64_t)frac + val2.frac;
// int64_t nval = (int64_t)val + val2.val + nfrac >> 32;
// return nval > MAXINT32 ? beConv(MAXINT32, MAXINT32) : beConv((int32_t)(nval), 0);
// }
template <typename ET>
CV_ALWAYS_INLINE operator ET() const { return cv::saturate_cast<ET>(fixedround(val) >> fixedShift); }
CV_ALWAYS_INLINE operator double() const { return (double)val / (1LL << fixedShift); }
CV_ALWAYS_INLINE operator float() const { return (float)val / (1LL << fixedShift); }
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
static CV_ALWAYS_INLINE ufixedpoint64 zero() { return ufixedpoint64(); }
static CV_ALWAYS_INLINE ufixedpoint64 one() { return ufixedpoint64((uint64_t)(1ULL << fixedShift)); }
friend class ufixedpoint32;
};
class fixedpoint32
{
private:
static const int fixedShift = 16;
int32_t val;
fixedpoint32(int32_t _val) : val(_val) {}
static CV_ALWAYS_INLINE uint32_t fixedround(const uint32_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
public:
typedef fixedpoint64 WT;
CV_ALWAYS_INLINE fixedpoint32() { val = 0; }
CV_ALWAYS_INLINE fixedpoint32(const int8_t& _val) { val = ((int32_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint32(const uint8_t& _val) { val = ((int32_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint32(const int16_t& _val) { val = ((int32_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint32(const cv::softdouble& _val) { val = (int32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); }
CV_ALWAYS_INLINE fixedpoint32& operator = (const int8_t& _val) { val = ((int32_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint32& operator = (const uint8_t& _val) { val = ((int32_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint32& operator = (const int16_t& _val) { val = ((int32_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint32& operator = (const cv::softdouble& _val) { val = (int32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); return *this; }
CV_ALWAYS_INLINE fixedpoint32& operator = (const fixedpoint32& _val) { val = _val.val; return *this; }
template <typename ET>
CV_ALWAYS_INLINE fixedpoint32 operator * (const ET& val2) const { return val * val2; } // Wrong rounding is possible for floating point types
CV_ALWAYS_INLINE fixedpoint64 operator * (const fixedpoint32& val2) const { return (int64_t)val * (int64_t)(val2.val); }
CV_ALWAYS_INLINE fixedpoint32 operator + (const fixedpoint32& val2) const { return fixedpoint32(val + val2.val); }
CV_ALWAYS_INLINE fixedpoint32 operator - (const fixedpoint32& val2) const { return fixedpoint32(val - val2.val); }
// CV_ALWAYS_INLINE fixedpoint32 operator + (const fixedpoint32& val2) const
// {
// int32_t nfrac = (int32_t)frac + val2.frac;
// int32_t nval = (int32_t)val + val2.val + nfrac >> 32;
// return nval > MAXINT32 ? beConv(MAXINT32, MAXINT32) : beConv((int32_t)(nval), 0);
// }
template <typename ET>
CV_ALWAYS_INLINE operator ET() const { return cv::saturate_cast<ET>((int32_t)fixedround((uint32_t)val) >> fixedShift); }
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
static CV_ALWAYS_INLINE fixedpoint32 zero() { return fixedpoint32(); }
static CV_ALWAYS_INLINE fixedpoint32 one() { return fixedpoint32((1 << fixedShift)); }
friend class fixedpoint16;
};
class ufixedpoint32
{
private:
static const int fixedShift = 16;
uint32_t val;
ufixedpoint32(uint32_t _val) : val(_val) {}
static CV_ALWAYS_INLINE uint32_t fixedround(const uint32_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
public:
typedef ufixedpoint64 WT;
CV_ALWAYS_INLINE ufixedpoint32() { val = 0; }
CV_ALWAYS_INLINE ufixedpoint32(const uint8_t& _val) { val = ((uint32_t)_val) << fixedShift; }
CV_ALWAYS_INLINE ufixedpoint32(const uint16_t& _val) { val = ((uint32_t)_val) << fixedShift; }
CV_ALWAYS_INLINE ufixedpoint32(const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); }
CV_ALWAYS_INLINE ufixedpoint32& operator = (const uint8_t& _val) { val = ((uint32_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE ufixedpoint32& operator = (const uint16_t& _val) { val = ((uint32_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE ufixedpoint32& operator = (const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); return *this; }
CV_ALWAYS_INLINE ufixedpoint32& operator = (const ufixedpoint32& _val) { val = _val.val; return *this; }
template <typename ET>
CV_ALWAYS_INLINE ufixedpoint32 operator * (const ET& val2) const { return val * val2; } // Wrong rounding is possible for floating point types
CV_ALWAYS_INLINE ufixedpoint64 operator * (const ufixedpoint32& val2) const { return (uint64_t)val * (uint64_t)(val2.val); }
CV_ALWAYS_INLINE ufixedpoint32 operator + (const ufixedpoint32& val2) const { return ufixedpoint32(val + val2.val); }
CV_ALWAYS_INLINE ufixedpoint32 operator - (const ufixedpoint32& val2) const { return ufixedpoint32(val - val2.val); }
// CV_ALWAYS_INLINE fixedpoint32 operator + (const fixedpoint32& val2) const
// {
// int32_t nfrac = (int32_t)frac + val2.frac;
// int32_t nval = (int32_t)val + val2.val + nfrac >> 32;
// return nval > MAXINT32 ? beConv(MAXINT32, MAXINT32) : beConv((int32_t)(nval), 0);
// }
template <typename ET>
CV_ALWAYS_INLINE operator ET() const { return cv::saturate_cast<ET>(fixedround(val) >> fixedShift); }
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
static CV_ALWAYS_INLINE ufixedpoint32 zero() { return ufixedpoint32(); }
static CV_ALWAYS_INLINE ufixedpoint32 one() { return ufixedpoint32((1U << fixedShift)); }
friend class ufixedpoint16;
};
class fixedpoint16
{
private:
static const int fixedShift = 8;
int16_t val;
fixedpoint16(int16_t _val) : val(_val) {}
static CV_ALWAYS_INLINE uint16_t fixedround(const uint16_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
public:
typedef fixedpoint32 WT;
CV_ALWAYS_INLINE fixedpoint16() { val = 0; }
CV_ALWAYS_INLINE fixedpoint16(const int8_t& _val) { val = ((int16_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint16(const uint8_t& _val) { val = ((int16_t)_val) << fixedShift; }
CV_ALWAYS_INLINE fixedpoint16(const cv::softdouble& _val) { val = (int16_t)cvRound(_val * cv::softdouble((1 << fixedShift))); }
CV_ALWAYS_INLINE fixedpoint16& operator = (const int8_t& _val) { val = ((int16_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE fixedpoint16& operator = (const cv::softdouble& _val) { val = (int16_t)cvRound(_val * cv::softdouble((1 << fixedShift))); return *this; }
CV_ALWAYS_INLINE fixedpoint16& operator = (const fixedpoint16& _val) { val = _val.val; return *this; }
template <typename ET>
CV_ALWAYS_INLINE fixedpoint16 operator * (const ET& val2) const { return (int16_t)(val * val2); } // Wrong rounding is possible for floating point types
CV_ALWAYS_INLINE fixedpoint32 operator * (const fixedpoint16& val2) const { return (int32_t)val * (int32_t)(val2.val); }
CV_ALWAYS_INLINE fixedpoint16 operator + (const fixedpoint16& val2) const { return fixedpoint16((int16_t)(val + val2.val)); }
CV_ALWAYS_INLINE fixedpoint16 operator - (const fixedpoint16& val2) const { return fixedpoint16((int16_t)(val - val2.val)); }
template <typename ET>
CV_ALWAYS_INLINE operator ET() const { return cv::saturate_cast<ET>((int16_t)fixedround((uint16_t)val) >> fixedShift); }
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
static CV_ALWAYS_INLINE fixedpoint16 zero() { return fixedpoint16(); }
static CV_ALWAYS_INLINE fixedpoint16 one() { return fixedpoint16((int16_t)(1 << fixedShift)); }
};
class ufixedpoint16
{
private:
static const int fixedShift = 8;
uint16_t val;
ufixedpoint16(uint16_t _val) : val(_val) {}
static CV_ALWAYS_INLINE uint16_t fixedround(const uint16_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
public:
typedef ufixedpoint32 WT;
CV_ALWAYS_INLINE ufixedpoint16() { val = 0; }
CV_ALWAYS_INLINE ufixedpoint16(const uint8_t& _val) { val = ((uint16_t)_val) << fixedShift; }
CV_ALWAYS_INLINE ufixedpoint16(const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint16_t)cvRound(_val * cv::softdouble((int32_t)(1 << fixedShift))); }
CV_ALWAYS_INLINE ufixedpoint16& operator = (const uint8_t& _val) { val = ((uint16_t)_val) << fixedShift; return *this; }
CV_ALWAYS_INLINE ufixedpoint16& operator = (const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint16_t)cvRound(_val * cv::softdouble((int32_t)(1 << fixedShift))); return *this; }
CV_ALWAYS_INLINE ufixedpoint16& operator = (const ufixedpoint16& _val) { val = _val.val; return *this; }
template <typename ET>
CV_ALWAYS_INLINE ufixedpoint16 operator * (const ET& val2) const { return (uint16_t)(val * val2); } // Wrong rounding is possible for floating point types
CV_ALWAYS_INLINE ufixedpoint32 operator * (const ufixedpoint16& val2) const { return ((uint32_t)val * (uint32_t)(val2.val)); }
CV_ALWAYS_INLINE ufixedpoint16 operator + (const ufixedpoint16& val2) const { return ufixedpoint16((uint16_t)(val + val2.val)); }
CV_ALWAYS_INLINE ufixedpoint16 operator - (const ufixedpoint16& val2) const { return ufixedpoint16((uint16_t)(val - val2.val)); }
// CV_ALWAYS_INLINE fixedpoint16 operator + (const fixedpoint16& val2) const
// {
// int16_t nfrac = (int32_t)frac + val2.frac;
// int16_t nval = (int32_t)val + val2.val + nfrac >> 16;
// return nval > MAXINT32 ? beConv(MAXINT16, MAXINT16) : beConv((int16_t)(nval), 0);
// }
template <typename ET>
CV_ALWAYS_INLINE operator ET() const { return cv::saturate_cast<ET>(fixedround(val) >> fixedShift); }
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
static CV_ALWAYS_INLINE ufixedpoint16 zero() { return ufixedpoint16(); }
static CV_ALWAYS_INLINE ufixedpoint16 one() { return ufixedpoint16((uint16_t)(1 << fixedShift)); }
};
}
#endif

@ -453,7 +453,7 @@ void LineSegmentDetectorImpl::flsd(std::vector<Vec4f>& lines,
Size ksize(1 + 2 * h, 1 + 2 * h); // kernel size
GaussianBlur(image, gaussian_img, ksize, sigma);
// Scale image to needed size
resize(gaussian_img, scaled_image, Size(), SCALE, SCALE);
resize(gaussian_img, scaled_image, Size(), SCALE, SCALE, INTER_LINEAR_EXACT);
ll_angle(rho, N_BINS);
}
else

@ -50,12 +50,633 @@
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
#include "hal_replacement.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/openvx/ovx_defs.hpp"
#include "resize.hpp"
#include "opencv2/core/softfloat.hpp"
#include "fixedpoint.inl.hpp"
using namespace cv;
namespace
{
template <typename ET, bool needsign> struct fixedtype { typedef fixedpoint64 type; };
template <> struct fixedtype<uint32_t, false> { typedef ufixedpoint64 type; };
template <bool needsign> struct fixedtype<int16_t, needsign> { typedef fixedpoint32 type; };
template <> struct fixedtype<uint16_t, false> { typedef ufixedpoint32 type; };
template <bool needsign> struct fixedtype<int8_t, needsign> { typedef fixedpoint32 type; };
template <> struct fixedtype<uint8_t, false> { typedef ufixedpoint16 type; };
//FT is fixedtype<ET, needsign>::type
template <typename ET, typename FT, int n, bool mulall>
static void hlineResize(ET* src, int cn, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
for (; i < dst_min; i++, m += n) // Points that fall left from src image so became equal to leftmost src point
{
for (int j = 0; j < cn; j++, dst++)
{
*dst = src[j];
}
}
for (; i < dst_max; i++, m += n)
{
ET* src_ofst = src + cn*ofst[i];
for (int j = 0; j < cn; j++, dst++)
{
*dst = (mulall || !m[0].isZero()) ? m[0] * src_ofst[j] : FT::zero();
for (int k = 1; k < n; k++)
{
*dst = *dst + ((mulall || !m[k].isZero()) ? m[k] * src_ofst[j+k*cn] : FT::zero());
}
}
}
ET* src_last = src + cn*ofst[dst_width - 1];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
for (int j = 0; j < cn; j++, dst++)
{
*dst = src_last[j];
}
}
}
template <typename ET, typename FT, int n, bool mulall, int cncnt> struct hline
{
static void ResizeCn(ET* src, int cn, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
hlineResize<ET, FT, n, mulall>(src, cn, ofst, m, dst, dst_min, dst_max, dst_width);
}
};
template <typename ET, typename FT> struct hline<ET, FT, 2, true, 1>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]);
for (; i < dst_min; i++, m += 2) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
}
for (; i < dst_max; i++, m += 2)
{
ET* px = src + ofst[i];
*(dst++) = m[0] * px[0] + m[1] * px[1];
}
src0 = (src + ofst[dst_width - 1])[0];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 2, true, 2>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]), src1(src[1]);
for (; i < dst_min; i++, m += 2) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
*(dst++) = src1;
}
for (; i < dst_max; i++, m += 2)
{
ET* px = src + 2*ofst[i];
*(dst++) = m[0] * px[0] + m[1] * px[2];
*(dst++) = m[0] * px[1] + m[1] * px[3];
}
src0 = (src + 2*ofst[dst_width - 1])[0];
src1 = (src + 2*ofst[dst_width - 1])[1];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
*(dst++) = src1;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 2, true, 3>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]), src1(src[1]), src2(src[2]);
for (; i < dst_min; i++, m += 2) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
}
for (; i < dst_max; i++, m += 2)
{
ET* px = src + 3*ofst[i];
*(dst++) = m[0] * px[0] + m[1] * px[3];
*(dst++) = m[0] * px[1] + m[1] * px[4];
*(dst++) = m[0] * px[2] + m[1] * px[5];
}
src0 = (src + 3*ofst[dst_width - 1])[0];
src1 = (src + 3*ofst[dst_width - 1])[1];
src2 = (src + 3*ofst[dst_width - 1])[2];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 2, true, 4>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]), src1(src[1]), src2(src[2]), src3(src[3]);
for (; i < dst_min; i++, m += 2) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
*(dst++) = src3;
}
for (; i < dst_max; i++, m += 2)
{
ET* px = src + 4*ofst[i];
*(dst++) = m[0] * px[0] + m[1] * px[4];
*(dst++) = m[0] * px[1] + m[1] * px[5];
*(dst++) = m[0] * px[2] + m[1] * px[6];
*(dst++) = m[0] * px[3] + m[1] * px[7];
}
src0 = (src + 4*ofst[dst_width - 1])[0];
src1 = (src + 4*ofst[dst_width - 1])[1];
src2 = (src + 4*ofst[dst_width - 1])[2];
src3 = (src + 4*ofst[dst_width - 1])[3];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
*(dst++) = src3;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 4, true, 1>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]);
for (; i < dst_min; i++, m += 4) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
}
for (; i < dst_max; i++, m += 4)
{
ET* px = src + ofst[i];
*(dst++) = m[0] * src[0] + m[1] * src[1] + m[2] * src[2] + m[3] * src[3];
}
src0 = (src + ofst[dst_width - 1])[0];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 4, true, 2>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]), src1(src[1]);
for (; i < dst_min; i++, m += 4) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
*(dst++) = src1;
}
for (; i < dst_max; i++, m += 4)
{
ET* px = src + 2*ofst[i];
*(dst++) = m[0] * src[0] + m[1] * src[2] + m[2] * src[4] + m[3] * src[6];
*(dst++) = m[0] * src[1] + m[1] * src[3] + m[2] * src[5] + m[3] * src[7];
}
src0 = (src + 2*ofst[dst_width - 1])[0];
src1 = (src + 2*ofst[dst_width - 1])[1];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
*(dst++) = src1;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 4, true, 3>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]), src1(src[1]), src2(src[2]);
for (; i < dst_min; i++, m += 4) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
}
for (; i < dst_max; i++, m += 4)
{
ET* px = src + 3*ofst[i];
*(dst++) = m[0] * src[0] + m[1] * src[3] + m[2] * src[6] + m[3] * src[ 9];
*(dst++) = m[0] * src[1] + m[1] * src[4] + m[2] * src[7] + m[3] * src[10];
*(dst++) = m[0] * src[2] + m[1] * src[5] + m[2] * src[8] + m[3] * src[11];
}
src0 = (src + 3*ofst[dst_width - 1])[0];
src1 = (src + 3*ofst[dst_width - 1])[1];
src2 = (src + 3*ofst[dst_width - 1])[2];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
}
}
};
template <typename ET, typename FT> struct hline<ET, FT, 4, true, 4>
{
static void ResizeCn(ET* src, int, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
FT src0(src[0]), src1(src[1]), src2(src[2]), src3(src[3]);
for (; i < dst_min; i++, m += 4) // Points that fall left from src image so became equal to leftmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
*(dst++) = src3;
}
for (; i < dst_max; i++, m += 4)
{
ET* px = src + 4*ofst[i];
*(dst++) = m[0] * src[0] + m[1] * src[4] + m[2] * src[ 8] + m[3] * src[12];
*(dst++) = m[0] * src[1] + m[1] * src[5] + m[2] * src[ 9] + m[3] * src[13];
*(dst++) = m[0] * src[2] + m[1] * src[6] + m[2] * src[10] + m[3] * src[14];
*(dst++) = m[0] * src[3] + m[1] * src[7] + m[2] * src[11] + m[3] * src[15];
}
src0 = (src + 4*ofst[dst_width - 1])[0];
src1 = (src + 4*ofst[dst_width - 1])[1];
src2 = (src + 4*ofst[dst_width - 1])[2];
src3 = (src + 4*ofst[dst_width - 1])[3];
for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point
{
*(dst++) = src0;
*(dst++) = src1;
*(dst++) = src2;
*(dst++) = src3;
}
}
};
template <typename ET, typename FT, int n, bool mulall, int cncnt>
static void hlineResizeCn(ET* src, int cn, int *ofst, FT* m, FT* dst, int dst_min, int dst_max, int dst_width)
{
hline<ET, FT, n, mulall, cncnt>::ResizeCn(src, cn, ofst, m, dst, dst_min, dst_max, dst_width);
};
template <>
void hlineResizeCn<uint8_t, ufixedpoint16, 2, true, 1>(uint8_t* src, int, int *ofst, ufixedpoint16* m, ufixedpoint16* dst, int dst_min, int dst_max, int dst_width)
{
int i = 0;
ufixedpoint16 src_0(src[0]);
v_uint16x8 v_src_0 = v_setall_u16(*((uint16_t*)&src_0));
for (; i < dst_min - 7; i += 8, m += 16, dst += 8) // Points that fall left from src image so became equal to leftmost src point
{
v_store((uint16_t*)dst, v_src_0);
}
for (; i < dst_min; i++, m += 2)
{
*(dst++) = src_0;
}
for (; i < dst_max - 7 && ofst[i + 7] + 15 <= ofst[dst_width - 1]; i += 8, m += 16, dst += 8)
{
v_uint32x4 v_src01 = v_combine_low(v_reinterpret_as_u32(v_load_expand(src + ofst[i])), v_reinterpret_as_u32(v_load_expand(src + ofst[i + 1])));
v_uint32x4 v_src23 = v_combine_low(v_reinterpret_as_u32(v_load_expand(src + ofst[i + 2])), v_reinterpret_as_u32(v_load_expand(src + ofst[i + 3])));
v_uint32x4 v_src45 = v_combine_low(v_reinterpret_as_u32(v_load_expand(src + ofst[i + 4])), v_reinterpret_as_u32(v_load_expand(src + ofst[i + 5])));
v_uint32x4 v_src67 = v_combine_low(v_reinterpret_as_u32(v_load_expand(src + ofst[i + 6])), v_reinterpret_as_u32(v_load_expand(src + ofst[i + 7])));
v_uint32x4 v_zip02, v_zip13, v_zip46, v_zip57;
v_zip(v_src01, v_src23, v_zip02, v_zip13);
v_zip(v_src45, v_src67, v_zip46, v_zip57);
v_uint32x4 v_src0, v_src1;
v_zip(v_combine_low(v_zip02, v_zip46), v_combine_low(v_zip13, v_zip57), v_src0, v_src1);
v_int16x8 v_mul0 = v_load((int16_t*)m);
v_int16x8 v_mul1 = v_load((int16_t*)m + 8);
v_uint32x4 v_res0 = v_reinterpret_as_u32(v_dotprod(v_reinterpret_as_s16(v_src0), v_mul0));
v_uint32x4 v_res1 = v_reinterpret_as_u32(v_dotprod(v_reinterpret_as_s16(v_src1), v_mul1));
v_store((uint16_t*)dst, v_pack(v_res0, v_res1));
}
for (; i < dst_max; i += 1, m += 2)
{
uint8_t* px = src + ofst[i];
*(dst++) = m[0] * px[0] + m[1] * px[1];
}
src_0 = (src + ofst[dst_width - 1])[0];
v_src_0 = v_setall_u16(*((uint16_t*)&src_0));
for (; i < dst_width - 7; i += 8, dst += 8) // Points that fall left from src image so became equal to leftmost src point
{
v_store((uint16_t*)dst, v_src_0);
}
for (; i < dst_width; i++)
{
*(dst++) = src_0;
}
}
template <>
void hlineResizeCn<uint16_t, ufixedpoint32, 2, true, 1>(uint16_t* src, int, int *ofst, ufixedpoint32* m, ufixedpoint32* dst, int dst_min, int dst_max, int dst_width)
{
typedef v_uint32x4 v_fixedtype;
typedef uint32_t lanetype;
int i = 0;
ufixedpoint32 src_0(src[0]);
v_fixedtype v_src_0 = v_setall_u32(*((lanetype*)&src_0));
for (; i < dst_min - 3; i += 4, m += 8, dst += 4) // Points that fall left from src image so became equal to leftmost src point
{
v_store((lanetype*)dst, v_src_0);
}
for (; i < dst_min; i++, m += 2)
{
*(dst++) = src_0;
}
for (; i < dst_max - 3 && ofst[i + 3] + 8 <= ofst[dst_width - 1]; i += 4, m += 8, dst += 4)
{
v_fixedtype v_src0 = v_combine_low(v_load_expand(src + ofst[i]), v_load_expand(src + ofst[i + 1]));
v_fixedtype v_mul0 = v_load((lanetype*)m);
v_fixedtype v_src1 = v_combine_low(v_load_expand(src + ofst[i + 2]), v_load_expand(src + ofst[i + 3]));
v_fixedtype v_mul1 = v_load((lanetype*)m + 4);
v_fixedtype v_res0 = v_src0 * v_mul0;//a1a2b1b2
v_fixedtype v_res1 = v_src1 * v_mul1;//c1c2d1d2
v_fixedtype v_tmp0, v_tmp1;
v_recombine(v_res0, v_res1, v_tmp0, v_tmp1);//a1a2c1c2 b1b2d1d2
v_zip(v_tmp0, v_tmp1, v_res0, v_res1);//a1b1a2b2 c1d1c2d2
v_recombine(v_res0, v_res1, v_tmp0, v_tmp1);//a1b1c1d1 a2b2c2d2
v_store((lanetype*)dst, v_tmp0 + v_tmp1);//abcd
}
for (; i < dst_max; i += 1, m += 2)
{
uint16_t* px = src + ofst[i];
*(dst++) = m[0] * px[0] + m[1] * px[1];
}
src_0 = (src + ofst[dst_width - 1])[0];
v_src_0 = v_setall_u32(*((lanetype*)&src_0));
for (; i < dst_width - 3; i += 4, dst += 4)
{
v_store((lanetype*)dst, v_src_0);
}
for (; i < dst_width; i++)
{
*(dst++) = src_0;
}
}
template <typename ET, typename FT>
void vlineSet(FT* src, ET* dst, int dst_width)
{
for (int i = 0; i < dst_width; i++)
dst[i] = src[i];
}
template <>
void vlineSet<uint8_t, ufixedpoint16>(ufixedpoint16* src, uint8_t* dst, int dst_width)
{
static const v_uint16x8 v_fixedRound = v_setall_u16((uint16_t)((1U << 8) >> 1));
int i = 0;
for (; i < dst_width - 15; i += 16, src += 16, dst += 16)
{
v_uint16x8 v_src0 = v_load((uint16_t*)src);
v_uint16x8 v_src1 = v_load((uint16_t*)src + 8);
v_uint16x8 v_res0 = (v_src0 + v_fixedRound) >> 8;
v_uint16x8 v_res1 = (v_src1 + v_fixedRound) >> 8;
v_store(dst, v_pack(v_res0, v_res1));
}
for (; i < dst_width; i++)
*(dst++) = *(src++);
}
template <typename ET, typename FT, int n>
void vlineResize(FT* src, size_t src_step, FT* m, ET* dst, int dst_width)
{
for (int i = 0; i < dst_width; i++)
{
typename FT::WT res = src[i] * m[0];
for (int k = 1; k < n; k++)
res = res + src[i + k*src_step] * m[k];
dst[i] = res;
}
}
template <>
void vlineResize<uint8_t, ufixedpoint16, 2>(ufixedpoint16* src, size_t src_step, ufixedpoint16* m, uint8_t* dst, int dst_width)
{
static const v_int32x4 v_fixedRound = v_setall_s32((int32_t)((1 << 16) >> 1));
static const v_int16x8 v_128 = v_reinterpret_as_s16(v_setall_u16((uint16_t)1<<15));
static const v_int8x16 v_128_16 = v_reinterpret_as_s8 (v_setall_u8 ((uint8_t) 1<<7));
int i = 0;
ufixedpoint16* src1 = src + src_step;
v_int16x8 v_mul = v_reinterpret_as_s16(v_setall_u32(((uint32_t*)m)[0]));
for (; i < dst_width - 15; i += 16, src += 16, src1 += 16, dst += 16)
{
v_int16x8 v_src00 = v_load((int16_t*)src);
v_int16x8 v_src10 = v_load((int16_t*)src1);
v_int16x8 v_tmp0, v_tmp1;
v_zip(v_add_wrap(v_src00,v_128), v_add_wrap(v_src10,v_128), v_tmp0, v_tmp1);
v_int32x4 v_res0 = v_dotprod(v_tmp0, v_mul);
v_int32x4 v_res1 = v_dotprod(v_tmp1, v_mul);
v_int16x8 v_src01 = v_load((int16_t*)src + 8);
v_int16x8 v_src11 = v_load((int16_t*)src1 + 8);
v_zip(v_add_wrap(v_src01,v_128), v_add_wrap(v_src11,v_128), v_tmp0, v_tmp1);
v_int32x4 v_res2 = v_dotprod(v_tmp0, v_mul);
v_int32x4 v_res3 = v_dotprod(v_tmp1, v_mul);
v_int8x16 v_res = v_pack(v_pack((v_res0 + v_fixedRound) >> 16,
(v_res1 + v_fixedRound) >> 16),
v_pack((v_res2 + v_fixedRound) >> 16,
(v_res3 + v_fixedRound) >> 16));
v_store(dst, v_reinterpret_as_u8(v_sub_wrap(v_res, v_128_16)));
}
for (; i < dst_width; i++)
{
*(dst++) = (uint8_t)(*(src++) * m[0] + *(src1++) * m[1]);
}
}
template <typename ET> class interpolationLinear
{
public:
static const int len = 2;
static const bool needsign = false;
interpolationLinear(double inv_scale, int srcsize, int dstsize) : scale(softdouble::one() / softdouble(inv_scale)), maxsize(srcsize), minofst(0), maxofst(dstsize) {}
void getCoeffs(int val, int* offset, typename fixedtype<ET, needsign>::type* coeffs)
{
typedef typename fixedtype<ET, needsign>::type fixedpoint;
softdouble fval = scale*(softdouble(val)+softdouble(0.5))-softdouble(0.5);
int ival = cvFloor(fval);
if (ival >= 0 && maxsize > 1)
{
if (ival < maxsize - 1)
{
*offset = ival;
coeffs[1] = fval - softdouble(ival);
coeffs[0] = fixedpoint::one() - coeffs[1];
}
else
{
*offset = maxsize - 1;
maxofst = min(maxofst, val);
}
}
else
{
minofst = max(minofst, val + 1);
}
}
void getMinMax(int &min, int &max)
{
min = minofst;
max = maxofst;
}
protected:
softdouble scale;
int maxsize;
int minofst, maxofst;
};
template <typename ET, typename FT, int interp_y_len>
class resize_bitExactInvoker :
public ParallelLoopBody
{
public:
typedef FT fixedpoint;
typedef void(*hResizeFunc)(ET* src, int cn, int *ofst, fixedpoint* m, fixedpoint* dst, int dst_min, int dst_max, int dst_width);
resize_bitExactInvoker(const uchar* _src, size_t _src_step, int _src_width, int _src_height,
uchar* _dst, size_t _dst_step, int _dst_width, int _dst_height,
int _cn, int *_xoffsets, int *_yoffsets, fixedpoint *_xcoeffs, fixedpoint *_ycoeffs,
int _min_x, int _max_x, int _min_y, int _max_y, hResizeFunc _hResize) : ParallelLoopBody(),
src(_src), src_step(_src_step), src_width(_src_width), src_height(_src_height),
dst(_dst), dst_step(_dst_step), dst_width(_dst_width), dst_height(_dst_height),
cn(_cn), xoffsets(_xoffsets), yoffsets(_yoffsets), xcoeffs(_xcoeffs), ycoeffs(_ycoeffs),
min_x(_min_x), max_x(_max_x), min_y(_min_y), max_y(_max_y), hResize(_hResize) {}
virtual void operator() (const Range& range) const
{
AutoBuffer<fixedpoint> linebuf(interp_y_len * dst_width * cn);
int last_eval = - interp_y_len;
int evalbuf_start = 0;
int rmin_y = max(min_y, range.start);
int rmax_y = min(max_y, range.end);
if (range.start < min_y)
{
last_eval = 1 - interp_y_len;
evalbuf_start = 1;
hResize((ET*)src, cn, xoffsets, xcoeffs, (fixedpoint*)linebuf, min_x, max_x, dst_width);
}
int dy = range.start;
for (; dy < rmin_y; dy++)
vlineSet<ET, FT>((fixedpoint*)linebuf, (ET*)(dst + dst_step * dy), dst_width*cn);
for (; dy < rmax_y; dy++)
{
int &iy = yoffsets[dy];
int i;
for (i = max(iy, last_eval + interp_y_len); i < min(iy + interp_y_len, src_height); i++, evalbuf_start = (evalbuf_start + 1) % interp_y_len)
hResize((ET*)(src + i * src_step), cn, xoffsets, xcoeffs, (fixedpoint*)linebuf + evalbuf_start*(dst_width * cn), min_x, max_x, dst_width);
evalbuf_start = (evalbuf_start + max(iy, src_height - interp_y_len) - max(last_eval, src_height - interp_y_len)) % interp_y_len;
last_eval = iy;
fixedpoint curcoeffs[interp_y_len];
for (i = 0; i < evalbuf_start; i++)
curcoeffs[i] = ycoeffs[ dy*interp_y_len - evalbuf_start + interp_y_len + i];
for (; i < interp_y_len; i++)
curcoeffs[i] = ycoeffs[ dy*interp_y_len - evalbuf_start + i];
vlineResize<ET, FT, interp_y_len>((fixedpoint*)linebuf, dst_width*cn, curcoeffs, (ET*)(dst + dst_step * dy), dst_width*cn);
}
fixedpoint *endline = (fixedpoint*)linebuf;
if (last_eval + interp_y_len > src_height)
endline += dst_width*cn*((evalbuf_start + src_height - 1 - last_eval) % interp_y_len);
else
hResize((ET*)(src + (src_height - 1) * src_step), cn, xoffsets, xcoeffs, endline, min_x, max_x, dst_width);
for (; dy < range.end; dy++)
vlineSet<ET, FT>(endline, (ET*)(dst + dst_step * dy), dst_width*cn);
}
private:
const uchar* src;
size_t src_step;
int src_width, src_height;
uchar* dst;
size_t dst_step;
int dst_width, dst_height, cn;
int *xoffsets, *yoffsets;
fixedpoint *xcoeffs, *ycoeffs;
int min_x, max_x, min_y, max_y;
hResizeFunc hResize;
resize_bitExactInvoker(const resize_bitExactInvoker&);
resize_bitExactInvoker& operator=(const resize_bitExactInvoker&);
};
template <typename ET, typename interpolation>
void resize_bitExact(const uchar* src, size_t src_step, int src_width, int src_height,
uchar* dst, size_t dst_step, int dst_width, int dst_height,
int cn, double inv_scale_x, double inv_scale_y)
{
typedef typename fixedtype<ET, interpolation::needsign>::type fixedpoint;
void(*hResize)(ET* src, int cn, int *ofst, fixedpoint* m, fixedpoint* dst, int dst_min, int dst_max, int dst_width);
switch (cn)
{
case 1: hResize = src_width > interpolation::len ? hlineResizeCn<ET, fixedpoint, interpolation::len, true, 1> : hlineResizeCn<ET, fixedpoint, interpolation::len, false, 1>; break;
case 2: hResize = src_width > interpolation::len ? hlineResizeCn<ET, fixedpoint, interpolation::len, true, 2> : hlineResizeCn<ET, fixedpoint, interpolation::len, false, 2>; break;
case 3: hResize = src_width > interpolation::len ? hlineResizeCn<ET, fixedpoint, interpolation::len, true, 3> : hlineResizeCn<ET, fixedpoint, interpolation::len, false, 3>; break;
case 4: hResize = src_width > interpolation::len ? hlineResizeCn<ET, fixedpoint, interpolation::len, true, 4> : hlineResizeCn<ET, fixedpoint, interpolation::len, false, 4>; break;
default: hResize = src_width > interpolation::len ? hlineResize<ET, fixedpoint, interpolation::len, true> : hlineResize<ET, fixedpoint, interpolation::len, false> ; break;
}
interpolation interp_x(inv_scale_x, src_width, dst_width);
interpolation interp_y(inv_scale_y, src_height, dst_height);
AutoBuffer<uchar> buf( dst_width * sizeof(int) +
dst_height * sizeof(int) +
dst_width * interp_x.len*sizeof(fixedpoint) +
dst_height * interp_y.len * sizeof(fixedpoint) );
int* xoffsets = (int*)((uchar*)buf);
int* yoffsets = xoffsets + dst_width;
fixedpoint* xcoeffs = (fixedpoint*)(yoffsets + dst_height);
fixedpoint* ycoeffs = xcoeffs + dst_width * interp_x.len;
int min_x, max_x, min_y, max_y;
for (int dx = 0; dx < dst_width; dx++)
interp_x.getCoeffs(dx, xoffsets+dx, xcoeffs+dx*interp_x.len);
interp_x.getMinMax(min_x, max_x);
for (int dy = 0; dy < dst_height; dy++)
interp_y.getCoeffs(dy, yoffsets+dy, ycoeffs+dy*interp_y.len);
interp_y.getMinMax(min_y, max_y);
resize_bitExactInvoker<ET, fixedpoint, interpolation::len> invoker(src, src_step, src_width, src_height, dst, dst_step, dst_width, dst_height, cn,
xoffsets, yoffsets, xcoeffs, ycoeffs, min_x, max_x, min_y, max_y, hResize);
Range range(0, dst_height);
parallel_for_(range, invoker, dst_width * dst_height / (double)(1 << 16));
}
typedef void(*be_resize_func)(const uchar* src, size_t src_step, int src_width, int src_height,
uchar* dst, size_t dst_step, int dst_width, int dst_height,
int cn, double inv_scale_x, double inv_scale_y);
}
namespace cv
{
@ -89,7 +710,7 @@ static inline void interpolateLanczos4( float x, float* coeffs )
}
float sum = 0;
double y0=-(x+3)*CV_PI*0.25, s0 = sin(y0), c0=cos(y0);
double y0=-(x+3)*CV_PI*0.25, s0 = std::sin(y0), c0= std::cos(y0);
for(int i = 0; i < 8; i++ )
{
double y = -(x+3-i)*CV_PI*0.25;
@ -3066,6 +3687,18 @@ void resize(int src_type,
resizeArea_<double, double>, 0
};
static be_resize_func linear_exact_tab[] =
{
resize_bitExact<uchar, interpolationLinear<uchar> >,
resize_bitExact<schar, interpolationLinear<schar> >,
resize_bitExact<ushort, interpolationLinear<ushort> >,
resize_bitExact<short, interpolationLinear<short> >,
resize_bitExact<int, interpolationLinear<int> >,
0,
0,
0
};
double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y;
int iscale_x = saturate_cast<int>(scale_x);
@ -3077,6 +3710,23 @@ void resize(int src_type,
Mat src(Size(src_width, src_height), src_type, const_cast<uchar*>(src_data), src_step);
Mat dst(dsize, src_type, dst_data, dst_step);
if (interpolation == INTER_LINEAR_EXACT)
{
// in case of inv_scale_x && inv_scale_y is equal to 0.5
// INTER_AREA (fast) is equal to bit exact INTER_LINEAR
if (is_area_fast && iscale_x == 2 && iscale_y == 2)
interpolation = INTER_AREA;
else
{
be_resize_func func = linear_exact_tab[depth];
CV_Assert(func != 0);
func(src_data, src_step, src_width, src_height,
dst_data, dst_step, dst_width, dst_height,
cn, inv_scale_x, inv_scale_y);
return;
}
}
if( interpolation == INTER_NEAREST )
{
resizeNN( src, dst, inv_scale_x, inv_scale_y );

@ -461,6 +461,14 @@ OCL_INSTANTIATE_TEST_CASE_P(ImgprocWarp, Resize, Combine(
Bool(),
Values(1, 16)));
OCL_INSTANTIATE_TEST_CASE_P(ImgprocWarpLinearExact, Resize, Combine(
Values(CV_8UC1, CV_8UC4, CV_16UC2),
Values(0.5, 1.5, 2.0, 0.2),
Values(0.5, 1.5, 2.0, 0.2),
Values((Interpolation)INTER_LINEAR_EXACT),
Bool(),
Values(1, 16)));
OCL_INSTANTIATE_TEST_CASE_P(ImgprocWarpResizeArea, Resize, Combine(
Values((MatType)CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4),
Values(0.7, 0.4, 0.5),

@ -121,7 +121,7 @@ int CV_CannyTest::prepare_test_case( int test_case_idx )
Mat& src = test_mat[INPUT][0];
//GaussianBlur(src, src, Size(11, 11), 5, 5);
if(src.cols > img.cols || src.rows > img.rows)
resize(img, src, src.size());
resize(img, src, src.size(), 0, 0, INTER_LINEAR_EXACT);
else
img(
Rect(

@ -59,11 +59,11 @@ protected:
UMat uimg = img.getUMat(ACCESS_READ), ugray, usmallimg, uresult;
cvtColor(img, gray, COLOR_BGR2GRAY);
resize(gray, smallimg, Size(), 0.75, 0.75, INTER_LINEAR);
resize(gray, smallimg, Size(), 0.75, 0.75, INTER_LINEAR_EXACT);
equalizeHist(smallimg, result);
cvtColor(uimg, ugray, COLOR_BGR2GRAY);
resize(ugray, usmallimg, Size(), 0.75, 0.75, INTER_LINEAR);
resize(ugray, usmallimg, Size(), 0.75, 0.75, INTER_LINEAR_EXACT);
equalizeHist(usmallimg, uresult);
#if 0

@ -335,6 +335,30 @@ void CV_ResizeTest::prepare_to_validation( int /*test_case_idx*/ )
cvReleaseMat( &y_idx );
}
class CV_ResizeExactTest : public CV_ResizeTest
{
public:
CV_ResizeExactTest();
protected:
void get_test_array_types_and_sizes(int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types);
};
CV_ResizeExactTest::CV_ResizeExactTest() : CV_ResizeTest()
{
max_interpolation = 1;
}
void CV_ResizeExactTest::get_test_array_types_and_sizes(int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types)
{
CV_ResizeTest::get_test_array_types_and_sizes(test_case_idx, sizes, types);
interpolation = INTER_LINEAR_EXACT;
if (CV_MAT_DEPTH(types[INPUT][0]) == CV_32F ||
CV_MAT_DEPTH(types[INPUT][0]) == CV_64F)
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(CV_8U, CV_MAT_CN(types[INPUT][0]));
}
/////////////////////////
@ -1589,6 +1613,7 @@ TEST(Imgproc_resize_area, regression_quarter_round)
//////////////////////////////////////////////////////////////////////////
TEST(Imgproc_Resize, accuracy) { CV_ResizeTest test; test.safe_run(); }
TEST(Imgproc_ResizeExact, accuracy) { CV_ResizeExactTest test; test.safe_run(); }
TEST(Imgproc_WarpAffine, accuracy) { CV_WarpAffineTest test; test.safe_run(); }
TEST(Imgproc_WarpPerspective, accuracy) { CV_WarpPerspectiveTest test; test.safe_run(); }
TEST(Imgproc_Remap, accuracy) { CV_RemapTest test; test.safe_run(); }

@ -119,6 +119,8 @@ String CV_ImageWarpBaseTest::interpolation_to_string(int inter) const
str = "INTER_NEAREST";
else if (inter == INTER_LINEAR)
str = "INTER_LINEAR";
else if (inter == INTER_LINEAR_EXACT)
str = "INTER_LINEAR_EXACT";
else if (inter == INTER_AREA)
str = "INTER_AREA";
else if (inter == INTER_CUBIC)
@ -418,11 +420,78 @@ namespace
void CV_Resize_Test::generate_test_data()
{
CV_ImageWarpBaseTest::generate_test_data();
RNG& rng = ts->get_rng();
// generating the src matrix structure
Size ssize = randSize(rng), dsize;
int depth = rng.uniform(0, CV_64F);
while (depth == CV_8S || depth == CV_32S)
depth = rng.uniform(0, CV_64F);
int cn = rng.uniform(1, 4);
while (cn == 2)
cn = rng.uniform(1, 4);
src.create(ssize, CV_MAKE_TYPE(depth, cn));
// generating the src matrix
int x, y;
if (cvtest::randInt(rng) % 2)
{
for (y = 0; y < ssize.height; y += cell_size)
for (x = 0; x < ssize.width; x += cell_size)
rectangle(src, Point(x, y), Point(x + std::min<int>(cell_size, ssize.width - x), y +
std::min<int>(cell_size, ssize.height - y)), Scalar::all((x + y) % 2 ? 255: 0), CV_FILLED);
}
else
{
src = Scalar::all(255);
for (y = cell_size; y < src.rows; y += cell_size)
line(src, Point2i(0, y), Point2i(src.cols, y), Scalar::all(0), 1);
for (x = cell_size; x < src.cols; x += cell_size)
line(src, Point2i(x, 0), Point2i(x, src.rows), Scalar::all(0), 1);
}
// generating an interpolation type
interpolation = rng.uniform(0, cv::INTER_MAX - 1);
// generating the dst matrix structure
if (interpolation == INTER_AREA)
{
area_fast = rng.uniform(0., 1.) > 0.5;
if (area_fast)
{
scale_x = rng.uniform(2, 5);
scale_y = rng.uniform(2, 5);
}
else
{
scale_x = rng.uniform(1.0, 3.0);
scale_y = rng.uniform(1.0, 3.0);
}
}
else
{
scale_x = rng.uniform(0.4, 4.0);
scale_y = rng.uniform(0.4, 4.0);
}
CV_Assert(scale_x > 0.0f && scale_y > 0.0f);
dsize.width = saturate_cast<int>((ssize.width + scale_x - 1) / scale_x);
dsize.height = saturate_cast<int>((ssize.height + scale_y - 1) / scale_y);
dst = Mat::zeros(dsize, src.type());
reference_dst = Mat::zeros(dst.size(), CV_MAKE_TYPE(CV_32F, dst.channels()));
scale_x = src.cols / static_cast<double>(dst.cols);
scale_y = src.rows / static_cast<double>(dst.rows);
if (interpolation == INTER_AREA && (scale_x < 1.0 || scale_y < 1.0))
interpolation = INTER_LINEAR_EXACT;
if (interpolation == INTER_LINEAR_EXACT && (depth == CV_32F || depth == CV_64F))
interpolation = INTER_LINEAR;
area_fast = interpolation == INTER_AREA &&
fabs(scale_x - cvRound(scale_x)) < FLT_EPSILON &&
fabs(scale_y - cvRound(scale_y)) < FLT_EPSILON;
@ -508,7 +577,7 @@ void CV_Resize_Test::resize_area()
}
}
// for interpolation type : INTER_LINEAR, INTER_LINEAR, INTER_CUBIC, INTER_LANCZOS4
// for interpolation type : INTER_LINEAR, INTER_LINEAR_EXACT, INTER_CUBIC, INTER_LANCZOS4
void CV_Resize_Test::resize_1d(const Mat& _src, Mat& _dst, int dy, const dim& _dim)
{
Size dsize = _dst.size();
@ -528,9 +597,9 @@ void CV_Resize_Test::resize_1d(const Mat& _src, Mat& _dst, int dy, const dim& _d
xyD[r] = xyS[r];
}
}
else if (interpolation == INTER_LINEAR || interpolation == INTER_CUBIC || interpolation == INTER_LANCZOS4)
else if (interpolation == INTER_LINEAR || interpolation == INTER_LINEAR_EXACT || interpolation == INTER_CUBIC || interpolation == INTER_LANCZOS4)
{
interpolate_method inter_func = inter_array[interpolation - (interpolation == INTER_LANCZOS4 ? 2 : 1)];
interpolate_method inter_func = inter_array[interpolation - (interpolation == INTER_LANCZOS4 ? 2 : interpolation == INTER_LINEAR_EXACT ? 5 : 1)];
size_t elemsize = _src.elemSize();
int ofs = 0, ksize = 2;
@ -1223,7 +1292,7 @@ TEST(Imgproc_WarpPerspective_Test, accuracy) { CV_WarpPerspective_Test test; tes
#ifdef OPENCV_TEST_BIGDATA
CV_ENUM(Interpolation, INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_AREA)
CV_ENUM(Interpolation, INTER_NEAREST, INTER_LINEAR, INTER_LINEAR_EXACT, INTER_CUBIC, INTER_AREA)
class Imgproc_Resize :
public ::testing::TestWithParam<Interpolation>

@ -0,0 +1,118 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
using namespace cv;
using namespace std;
namespace
{
static const int fixedShiftU8 = 8;
template <typename T, int fixedShift>
void eval4(int64_t xcoeff0, int64_t xcoeff1, int64_t ycoeff0, int64_t ycoeff1, int cn,
uint8_t* src_pt00, uint8_t* src_pt01, uint8_t* src_pt10, uint8_t* src_pt11, uint8_t* dst_pt)
{
static const int64_t fixedRound = ((1LL << (fixedShift * 2)) >> 1);
int64_t val = (((T*)src_pt00)[cn] * xcoeff0 + ((T*)src_pt01)[cn] * xcoeff1) * ycoeff0 +
(((T*)src_pt10)[cn] * xcoeff0 + ((T*)src_pt11)[cn] * xcoeff1) * ycoeff1 ;
((T*)dst_pt)[cn] = saturate_cast<T>((val + fixedRound) >> (fixedShift * 2));
}
}
TEST(Resize_Bitexact, Linear8U)
{
static const int64_t fixedOne = (1L << fixedShiftU8);
int types[] = { CV_8UC1, CV_8UC4 };
// NOTICE: 2x downscaling ommitted since it use different rounding
// 1/2 1 1 1/2 1/2 1/2 1/4 1/4 1/256 1/256 1/3 1/2 1/3 1/3 1/2 1/3 1/7 1/7
Size dstsizes[] = {Size(512, 768), Size(1024, 384), Size(512, 384), Size(256, 192), Size(4, 3), Size(342, 384), Size(342, 256), Size(512, 256), Size(146, 110),
// 10/11 10/11 10/12 10/12 251/256 2 2 3 3 7 7
Size(931, 698), Size(853, 640), Size(1004, 753), Size(2048,1536), Size(3072,2304), Size(7168,5376) };
for (int dsizeind = 0, _dsizecnt = sizeof(dstsizes) / sizeof(dstsizes[0]); dsizeind < _dsizecnt; ++dsizeind)
for (int typeind = 0, _typecnt = sizeof(types) / sizeof(types[0]); typeind < _typecnt; ++typeind)
{
int type = types[typeind], depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
int dcols = dstsizes[dsizeind].width, drows = dstsizes[dsizeind].height;
int cols = 1024, rows = 768;
double inv_scale_x = (double)dcols / cols;
double inv_scale_y = (double)drows / rows;
softdouble scale_x = softdouble::one() / softdouble(inv_scale_x);
softdouble scale_y = softdouble::one() / softdouble(inv_scale_y);
Mat src(rows, cols, type), refdst(drows, dcols, type), dst;
for (int j = 0; j < rows; j++)
{
uint8_t* line = src.ptr(j);
for (int i = 0; i < cols; i++)
for (int c = 0; c < cn; c++)
{
RNG rnd(0x123456789abcdefULL);
double val = j < rows / 2 ? ( i < cols / 2 ? ((sin((i + 1)*CV_PI / 256.)*sin((j + 1)*CV_PI / 256.)*sin((cn + 4)*CV_PI / 8.) + 1.)*128.) :
(((i / 128 + j / 128) % 2) * 250 + (j / 128) % 2) ) :
( i < cols / 2 ? ((i / 128) * (85 - j / 256 * 40) * ((j / 128) % 2) + (7 - i / 128) * (85 - j / 256 * 40) * ((j / 128 + 1) % 2)) :
((uchar)rnd) ) ;
if (depth == CV_8U)
line[i*cn + c] = (uint8_t)val;
else if (depth == CV_16U)
((uint16_t*)line)[i*cn + c] = (uint16_t)val;
else if (depth == CV_16S)
((int16_t*)line)[i*cn + c] = (int16_t)val;
else if (depth == CV_32S)
((int32_t*)line)[i*cn + c] = (int32_t)val;
else
CV_Assert(0);
}
}
for (int j = 0; j < drows; j++)
{
softdouble src_row_flt = scale_y*(softdouble(j) + softdouble(0.5)) - softdouble(0.5);
int src_row = cvFloor(src_row_flt);
int64_t ycoeff1 = cvRound64((src_row_flt - softdouble(src_row))*softdouble(fixedOne));
int64_t ycoeff0 = fixedOne - ycoeff1;
for (int i = 0; i < dcols; i++)
{
softdouble src_col_flt = scale_x*(softdouble(i) + softdouble(0.5)) - softdouble(0.5);
int src_col = cvFloor(src_col_flt);
int64_t xcoeff1 = cvRound64((src_col_flt - softdouble(src_col))*softdouble(fixedOne));
int64_t xcoeff0 = fixedOne - xcoeff1;
uint8_t* dst_pt = refdst.ptr(j, i);
uint8_t* src_pt00 = src.ptr( src_row < 0 ? 0 : src_row >= rows ? rows - 1 : src_row ,
src_col < 0 ? 0 : src_col >= cols ? cols - 1 : src_col );
uint8_t* src_pt01 = src.ptr( src_row < 0 ? 0 : src_row >= rows ? rows - 1 : src_row ,
(src_col + 1) < 0 ? 0 : (src_col + 1) >= cols ? cols - 1 : (src_col + 1));
uint8_t* src_pt10 = src.ptr((src_row + 1) < 0 ? 0 : (src_row + 1) >= rows ? rows - 1 : (src_row + 1),
src_col < 0 ? 0 : src_col >= cols ? cols - 1 : src_col );
uint8_t* src_pt11 = src.ptr((src_row + 1) < 0 ? 0 : (src_row + 1) >= rows ? rows - 1 : (src_row + 1),
(src_col + 1) < 0 ? 0 : (src_col + 1) >= cols ? cols - 1 : (src_col + 1));
for (int c = 0; c < cn; c++)
{
if (depth == CV_8U)
eval4< uint8_t, fixedShiftU8>(xcoeff0, xcoeff1, ycoeff0, ycoeff1, c, src_pt00, src_pt01, src_pt10, src_pt11, dst_pt);
else if (depth == CV_16U)
eval4<uint16_t, fixedShiftU8>(xcoeff0, xcoeff1, ycoeff0, ycoeff1, c, src_pt00, src_pt01, src_pt10, src_pt11, dst_pt);
else if (depth == CV_16S)
eval4< int16_t, fixedShiftU8>(xcoeff0, xcoeff1, ycoeff0, ycoeff1, c, src_pt00, src_pt01, src_pt10, src_pt11, dst_pt);
else if (depth == CV_32S)
eval4< int32_t, fixedShiftU8>(xcoeff0, xcoeff1, ycoeff0, ycoeff1, c, src_pt00, src_pt01, src_pt10, src_pt11, dst_pt);
else
CV_Assert(0);
}
}
}
cv::resize(src, dst, Size(dcols, drows), 0, 0, cv::INTER_LINEAR_EXACT);
EXPECT_GE(0, cvtest::norm(refdst, dst, cv::NORM_L1))
<< "Resize from " << cols << "x" << rows << " to " << dcols << "x" << drows << " failed with max diff " << cvtest::norm(refdst, dst, cv::NORM_INF);
}
}
///* End of file. */

@ -511,7 +511,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s
{
const ScaleData& s = scaleData->at(i);
UMat dst(urbuf, Rect(0, 0, s.szi.width - 1, s.szi.height - 1));
resize(_image, dst, dst.size(), 1. / s.scale, 1. / s.scale, INTER_LINEAR);
resize(_image, dst, dst.size(), 1. / s.scale, 1. / s.scale, INTER_LINEAR_EXACT);
computeChannels((int)i, dst);
}
sbufFlag = USBUF_VALID;
@ -526,7 +526,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s
{
const ScaleData& s = scaleData->at(i);
Mat dst(s.szi.height - 1, s.szi.width - 1, CV_8U, rbuf.ptr());
resize(image, dst, dst.size(), 1. / s.scale, 1. / s.scale, INTER_LINEAR);
resize(image, dst, dst.size(), 1. / s.scale, 1. / s.scale, INTER_LINEAR_EXACT);
computeChannels((int)i, dst);
}
sbufFlag = SBUF_VALID;

@ -1323,7 +1323,7 @@ cvHaarDetectObjectsForROC( const CvArr* _img,
norm1 = cvMat( sz1.height, sz1.width, CV_32FC1, normImg ? normImg->data.ptr : 0 );
mask1 = cvMat( sz1.height, sz1.width, CV_8UC1, temp->data.ptr );
cvResize( img, &img1, CV_INTER_LINEAR );
cvResize( img, &img1, cv::INTER_LINEAR_EXACT );
cvIntegral( &img1, &sum1, &sqsum1, _tilted );
int ystep = factor > 2 ? 1 : 2;

@ -1814,7 +1814,7 @@ public:
if( sz == img.size() )
smallerImg = Mat(sz, img.type(), img.data, img.step);
else
resize(img, smallerImg, sz);
resize(img, smallerImg, sz, 0, 0, INTER_LINEAR_EXACT);
hog->detect(smallerImg, locations, hitsWeights, hitThreshold, winStride, padding);
Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale));
@ -2031,7 +2031,7 @@ static bool ocl_detectMultiScale(InputArray _img, std::vector<Rect> &found_locat
}
else
{
resize(_img, image_scale, effect_size);
resize(_img, image_scale, effect_size, 0, 0, INTER_LINEAR_EXACT);
if(!ocl_detect(image_scale, locations, hit_threshold, win_stride, oclSvmDetector, blockSize, cellSize, nbins,
blockStride, winSize, gammaCorrection, L2HysThreshold, sigma, free_coef, signedGradient))
return false;
@ -3525,7 +3525,7 @@ public:
if( sz == img.size() )
smallerImg = Mat(sz, img.type(), img.data, img.step);
else
resize(img, smallerImg, sz);
resize(img, smallerImg, sz, 0, 0, INTER_LINEAR_EXACT);
hog->detectROI(smallerImg, (*locations)[i].locations, dets, (*locations)[i].confidences, hitThreshold, Size(), padding);
Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale));

@ -233,7 +233,7 @@ void Decolor::weak_order(Mat img, vector <double> &alf)
if((h + w) > 800)
{
sizefactor = (double)800/(h+w);
resize(img,img,Size(round_num(h*sizefactor),round_num(w*sizefactor)));
resize(img,img,Size(round_num(h*sizefactor),round_num(w*sizefactor)), 0, 0, INTER_LINEAR_EXACT);
}
Mat curIm = Mat(img.size(),CV_32FC1);
@ -309,7 +309,7 @@ void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad,
if((h + w) > 800)
{
sizefactor = (double)800/(h+w);
resize(img,img,Size(round_num(h*sizefactor),round_num(w*sizefactor)));
resize(img,img,Size(round_num(h*sizefactor),round_num(w*sizefactor)), 0, 0, INTER_LINEAR_EXACT);
}
h = img.size().height;

@ -519,7 +519,7 @@ protected:
for(int i = 0; i < levels; i++) {
getGradient(layer, x_contrast[i], 0);
getGradient(layer.t(), y_contrast[i], 0);
resize(layer, layer, Size(layer.cols / 2, layer.rows / 2));
resize(layer, layer, Size(layer.cols / 2, layer.rows / 2), 0, 0, INTER_LINEAR);
}
}
@ -534,7 +534,7 @@ protected:
Mat grad_x, grad_y;
getGradient(x_contrast[i], grad_x, 1);
getGradient(y_contrast[i], grad_y, 1);
resize(sum, sum, x_contrast[i].size());
resize(sum, sum, x_contrast[i].size(), 0, 0, INTER_LINEAR);
sum += grad_x + grad_y.t();
}
}

@ -11,7 +11,7 @@ import numpy as np
import cv2 as cv
def detect(img, cascade):
rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30),
rects = cascade.detectMultiScale(img, scaleFactor=1.275, minNeighbors=4, minSize=(30, 30),
flags=cv.CASCADE_SCALE_IMAGE)
if len(rects) == 0:
return []

@ -281,13 +281,13 @@ float ShapeContextDistanceExtractorImpl::computeDistance(InputArray contour1, In
// compute appearance cost
if ( !transDown.empty() )
{
resize(warpedImage, warpedImage, image1.size());
resize(warpedImage, warpedImage, image1.size(), 0, 0, INTER_LINEAR_EXACT);
Mat temp=(warpedImage-image1);
multiply(temp, temp, diffIm);
}
else
{
resize(warpedImage, warpedImage, image2.size());
resize(warpedImage, warpedImage, image2.size(), 0, 0, INTER_LINEAR_EXACT);
Mat temp=(warpedImage-image2);
multiply(temp, temp, diffIm);
}

@ -24,8 +24,8 @@ PERF_TEST_P(bundleAdjuster, affine, testing::Combine(TEST_DETECTORS, AFFINE_FUNC
Mat img2, img2_full = imread(getDataPath("stitching/s2.jpg"));
float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
resize(img1_full, img1, Size(), scale1, scale1);
resize(img2_full, img2, Size(), scale2, scale2);
resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);
resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);
string detector = get<0>(GetParam());
string affine_fun = get<1>(GetParam());

@ -64,8 +64,8 @@ PERF_TEST_P( match, bestOf2Nearest, TEST_DETECTORS)
Mat img2, img2_full = imread( getDataPath("stitching/boat2.jpg") );
float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
resize(img1_full, img1, Size(), scale1, scale1);
resize(img2_full, img2, Size(), scale2, scale2);
resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);
resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);
Ptr<detail::FeaturesFinder> finder;
Ptr<detail::FeaturesMatcher> matcher;
@ -117,8 +117,8 @@ PERF_TEST_P( matchVector, bestOf2NearestVectorFeatures, testing::Combine(
Mat img2, img2_full = imread( getDataPath("stitching/boat2.jpg") );
float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
resize(img1_full, img1, Size(), scale1, scale1);
resize(img2_full, img2, Size(), scale2, scale2);
resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);
resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);
Ptr<detail::FeaturesFinder> finder;
Ptr<detail::FeaturesMatcher> matcher;
@ -182,8 +182,8 @@ PERF_TEST_P( match, affineBestOf2Nearest, TEST_DETECTORS)
Mat img2, img2_full = imread( getDataPath("stitching/s2.jpg") );
float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
resize(img1_full, img1, Size(), scale1, scale1);
resize(img2_full, img2, Size(), scale2, scale2);
resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);
resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);
Ptr<detail::FeaturesFinder> finder;
Ptr<detail::FeaturesMatcher> matcher;
@ -241,8 +241,8 @@ PERF_TEST_P( matchVector, affineBestOf2NearestVectorFeatures, testing::Combine(
Mat img2, img2_full = imread( getDataPath("stitching/s2.jpg") );
float scale1 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img1_full.total()));
float scale2 = (float)std::min(1.0, sqrt(WORK_MEGAPIX * 1e6 / img2_full.total()));
resize(img1_full, img1, Size(), scale1, scale1);
resize(img2_full, img2, Size(), scale2, scale2);
resize(img1_full, img1, Size(), scale1, scale1, INTER_LINEAR_EXACT);
resize(img2_full, img2, Size(), scale2, scale2, INTER_LINEAR_EXACT);
Ptr<detail::FeaturesFinder> finder;
Ptr<detail::FeaturesMatcher> matcher;

@ -173,7 +173,7 @@ Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArra
for (size_t i = 0; i < imgs.size(); ++i)
{
imgs_[i] = imgs[i];
resize(imgs[i], img, Size(), seam_scale_, seam_scale_);
resize(imgs[i], img, Size(), seam_scale_, seam_scale_, INTER_LINEAR_EXACT);
seam_est_imgs_[i] = img.clone();
}
@ -315,7 +315,7 @@ Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArra
#if ENABLE_LOG
int64 resize_t = getTickCount();
#endif
resize(full_img, img, Size(), compose_scale, compose_scale);
resize(full_img, img, Size(), compose_scale, compose_scale, INTER_LINEAR_EXACT);
LOGLN(" resize time: " << ((getTickCount() - resize_t) / getTickFrequency()) << " sec");
}
else
@ -361,7 +361,7 @@ Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArra
// Make sure seam mask has proper size
dilate(masks_warped[img_idx], dilated_mask, Mat());
resize(dilated_mask, seam_mask, mask_warped.size());
resize(dilated_mask, seam_mask, mask_warped.size(), 0, 0, INTER_LINEAR_EXACT);
bitwise_and(seam_mask, mask_warped, mask_warped);
@ -471,7 +471,7 @@ Stitcher::Status Stitcher::matchImages()
work_scale_ = std::min(1.0, std::sqrt(registr_resol_ * 1e6 / full_img.size().area()));
is_work_scale_set = true;
}
resize(full_img, img, Size(), work_scale_, work_scale_);
resize(full_img, img, Size(), work_scale_, work_scale_, INTER_LINEAR_EXACT);
}
if (!is_seam_scale_set)
{
@ -496,7 +496,7 @@ Stitcher::Status Stitcher::matchImages()
features_[i].img_idx = (int)i;
LOGLN("Features in image #" << i+1 << ": " << features_[i].keypoints.size());
resize(full_img, img, Size(), seam_scale_, seam_scale_);
resize(full_img, img, Size(), seam_scale_, seam_scale_, INTER_LINEAR_EXACT);
seam_est_imgs_[i] = img.clone();
}

@ -355,7 +355,7 @@ IMPLEMENT_PARAM_CLASS(Channels, int)
#define OCL_ALL_DEPTHS Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F)
#define OCL_ALL_CHANNELS Values(1, 2, 3, 4)
CV_ENUM(Interpolation, INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_AREA)
CV_ENUM(Interpolation, INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_AREA, INTER_LINEAR_EXACT)
CV_ENUM(ThreshOp, THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV)
CV_ENUM(BorderType, BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT, BORDER_WRAP, BORDER_REFLECT_101)

@ -767,7 +767,7 @@ private:
{
if (!gaussianBlurOcl(frames_[i], smoothSize/2, blurredFrame[i]))
return false;
resize(blurredFrame[i], pyrLevel[i], Size(width, height), INTER_LINEAR);
resize(blurredFrame[i], pyrLevel[i], Size(width, height), INTER_LINEAR_EXACT);
if (!polynomialExpansionOcl(pyrLevel[i], R[i]))
return false;
}
@ -1153,7 +1153,7 @@ void FarnebackOpticalFlowImpl::calc(InputArray _prev0, InputArray _next0,
}
else
{
resize( prevFlow, flow, Size(width, height), 0, 0, INTER_LINEAR );
resize( prevFlow, flow, Size(width, height), 0, 0, INTER_LINEAR);
flow *= 1./pyrScale_;
}
@ -1162,7 +1162,7 @@ void FarnebackOpticalFlowImpl::calc(InputArray _prev0, InputArray _next0,
{
img[i]->convertTo(fimg, CV_32F);
GaussianBlur(fimg, fimg, Size(smooth_sz, smooth_sz), sigma, sigma);
resize( fimg, I, Size(width, height), INTER_LINEAR );
resize( fimg, I, Size(width, height), INTER_LINEAR);
FarnebackPolyExp( I, R[i], polyN_, polySigma_ );
}

@ -465,8 +465,8 @@ void OpticalFlowDual_TVL1::calc(InputArray _I0, InputArray _I1, InputOutputArray
// create the scales
for (int s = 1; s < nscales; ++s)
{
resize(dm.I0s[s - 1], dm.I0s[s], Size(), scaleStep, scaleStep);
resize(dm.I1s[s - 1], dm.I1s[s], Size(), scaleStep, scaleStep);
resize(dm.I0s[s - 1], dm.I0s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
resize(dm.I1s[s - 1], dm.I1s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
if (dm.I0s[s].cols < 16 || dm.I0s[s].rows < 16)
{
@ -476,8 +476,8 @@ void OpticalFlowDual_TVL1::calc(InputArray _I0, InputArray _I1, InputOutputArray
if (useInitialFlow)
{
resize(dm.u1s[s - 1], dm.u1s[s], Size(), scaleStep, scaleStep);
resize(dm.u2s[s - 1], dm.u2s[s], Size(), scaleStep, scaleStep);
resize(dm.u1s[s - 1], dm.u1s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
resize(dm.u2s[s - 1], dm.u2s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
multiply(dm.u1s[s], Scalar::all(scaleStep), dm.u1s[s]);
multiply(dm.u2s[s], Scalar::all(scaleStep), dm.u2s[s]);
@ -508,9 +508,9 @@ void OpticalFlowDual_TVL1::calc(InputArray _I0, InputArray _I1, InputOutputArray
// otherwise, upsample the optical flow
// zoom the optical flow for the next finer scale
resize(dm.u1s[s], dm.u1s[s - 1], dm.I0s[s - 1].size());
resize(dm.u2s[s], dm.u2s[s - 1], dm.I0s[s - 1].size());
if (use_gamma) resize(dm.u3s[s], dm.u3s[s - 1], dm.I0s[s - 1].size());
resize(dm.u1s[s], dm.u1s[s - 1], dm.I0s[s - 1].size(), 0, 0, INTER_LINEAR);
resize(dm.u2s[s], dm.u2s[s - 1], dm.I0s[s - 1].size(), 0, 0, INTER_LINEAR);
if (use_gamma) resize(dm.u3s[s], dm.u3s[s - 1], dm.I0s[s - 1].size(), 0, 0, INTER_LINEAR);
// scale the optical flow with the appropriate zoom factor (don't scale u3!)
multiply(dm.u1s[s - 1], Scalar::all(1 / scaleStep), dm.u1s[s - 1]);
@ -575,8 +575,8 @@ bool OpticalFlowDual_TVL1::calc_ocl(InputArray _I0, InputArray _I1, InputOutputA
// create the scales
for (int s = 1; s < nscales; ++s)
{
resize(dum.I0s[s - 1], dum.I0s[s], Size(), scaleStep, scaleStep);
resize(dum.I1s[s - 1], dum.I1s[s], Size(), scaleStep, scaleStep);
resize(dum.I0s[s - 1], dum.I0s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
resize(dum.I1s[s - 1], dum.I1s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
if (dum.I0s[s].cols < 16 || dum.I0s[s].rows < 16)
{
@ -586,8 +586,8 @@ bool OpticalFlowDual_TVL1::calc_ocl(InputArray _I0, InputArray _I1, InputOutputA
if (useInitialFlow)
{
resize(dum.u1s[s - 1], dum.u1s[s], Size(), scaleStep, scaleStep);
resize(dum.u2s[s - 1], dum.u2s[s], Size(), scaleStep, scaleStep);
resize(dum.u1s[s - 1], dum.u1s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
resize(dum.u2s[s - 1], dum.u2s[s], Size(), scaleStep, scaleStep, INTER_LINEAR);
//scale by scale factor
multiply(dum.u1s[s], Scalar::all(scaleStep), dum.u1s[s]);
@ -607,8 +607,8 @@ bool OpticalFlowDual_TVL1::calc_ocl(InputArray _I0, InputArray _I1, InputOutputA
break;
// zoom the optical flow for the next finer scale
resize(dum.u1s[s], dum.u1s[s - 1], dum.I0s[s - 1].size());
resize(dum.u2s[s], dum.u2s[s - 1], dum.I0s[s - 1].size());
resize(dum.u1s[s], dum.u1s[s - 1], dum.I0s[s - 1].size(), 0, 0, INTER_LINEAR);
resize(dum.u2s[s], dum.u2s[s - 1], dum.I0s[s - 1].size(), 0, 0, INTER_LINEAR);
// scale the optical flow with the appropriate zoom factor
multiply(dum.u1s[s - 1], Scalar::all(1 / scaleStep), dum.u1s[s - 1]);

@ -121,7 +121,7 @@ bool CV_ECC_Test_Translation::testTranslation(int from)
return false;
}
Mat testImg;
resize(img, testImg, Size(216, 216));
resize(img, testImg, Size(216, 216), 0, 0, INTER_LINEAR_EXACT);
cv::RNG rng = ts->get_rng();
@ -196,7 +196,7 @@ bool CV_ECC_Test_Euclidean::testEuclidean(int from)
return false;
}
Mat testImg;
resize(img, testImg, Size(216, 216));
resize(img, testImg, Size(216, 216), 0, 0, INTER_LINEAR_EXACT);
cv::RNG rng = ts->get_rng();
@ -270,7 +270,7 @@ bool CV_ECC_Test_Affine::testAffine(int from)
return false;
}
Mat testImg;
resize(img, testImg, Size(216, 216));
resize(img, testImg, Size(216, 216), 0, 0, INTER_LINEAR_EXACT);
cv::RNG rng = ts->get_rng();
@ -346,7 +346,7 @@ bool CV_ECC_Test_Homography::testHomography(int from)
return false;
}
Mat testImg;
resize(img, testImg, Size(216, 216));
resize(img, testImg, Size(216, 216), 0, 0, INTER_LINEAR_EXACT);
cv::RNG rng = ts->get_rng();
@ -418,7 +418,7 @@ bool CV_ECC_Test_Mask::testMask(int from)
return false;
}
Mat scaledImage;
resize(img, scaledImage, Size(216, 216));
resize(img, scaledImage, Size(216, 216), 0, 0, INTER_LINEAR_EXACT );
Mat_<float> testImg;
scaledImage.convertTo(testImg, testImg.type());

@ -234,7 +234,7 @@ TEST(Video_OpticalFlowPyrLK, submat)
ASSERT_FALSE(lenaImg.empty());
cv::Mat wholeImage;
cv::resize(lenaImg, wholeImage, cv::Size(1024, 1024));
cv::resize(lenaImg, wholeImage, cv::Size(1024, 1024), 0, 0, cv::INTER_LINEAR_EXACT);
cv::Mat img1 = wholeImage(cv::Rect(0, 0, 640, 360)).clone();
cv::Mat img2 = wholeImage(cv::Rect(40, 60, 640, 360));

@ -159,7 +159,7 @@ public class ColorBlobDetectionActivity extends Activity implements OnTouchListe
mDetector.setHsvColor(mBlobColorHsv);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE, 0, 0, Imgproc.INTER_LINEAR_EXACT);
mIsColorSelected = true;

@ -286,7 +286,7 @@ public class ImageManipulationsActivity extends Activity implements CvCameraView
case ImageManipulationsActivity.VIEW_MODE_ZOOM:
Mat zoomCorner = rgba.submat(0, rows / 2 - rows / 10, 0, cols / 2 - cols / 10);
Mat mZoomWindow = rgba.submat(rows / 2 - 9 * rows / 100, rows / 2 + 9 * rows / 100, cols / 2 - 9 * cols / 100, cols / 2 + 9 * cols / 100);
Imgproc.resize(mZoomWindow, zoomCorner, zoomCorner.size());
Imgproc.resize(mZoomWindow, zoomCorner, zoomCorner.size(), 0, 0, Imgproc.INTER_LINEAR_EXACT);
Size wsize = mZoomWindow.size();
Imgproc.rectangle(mZoomWindow, new Point(1, 1), new Point(wsize.width - 2, wsize.height - 2), new Scalar(255, 0, 0, 255), 2);
zoomCorner.release();

@ -347,7 +347,7 @@ int main( int argc, char** argv )
remap(view, rview, map1[k1], map2[k1], INTER_LINEAR);
}
printf("%s %s %s\n", imageList[i*3].c_str(), imageList[i*3+1].c_str(), imageList[i*3+2].c_str());
resize( canvas, small_canvas, Size(1500, 1500/3) );
resize( canvas, small_canvas, Size(1500, 1500/3), 0, 0, INTER_LINEAR_EXACT );
for( k = 0; k < small_canvas.rows; k += 16 )
line(small_canvas, Point(0, k), Point(small_canvas.cols, k), Scalar(0,255,0), 1);
imshow("rectified", small_canvas);

@ -70,7 +70,7 @@ int main(int argc, const char** argv)
if( img0.empty() )
break;
resize(img0, img, Size(640, 640*img0.rows/img0.cols), INTER_LINEAR);
resize(img0, img, Size(640, 640*img0.rows/img0.cols), 0, 0, INTER_LINEAR_EXACT);
if( fgimg.empty() )
fgimg.create(img.size(), img.type());

@ -174,7 +174,7 @@ void detectAndDraw( Mat& img, CascadeClassifier& cascade,
cvtColor( img, gray, COLOR_BGR2GRAY );
double fx = 1 / scale;
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR );
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT );
equalizeHist( smallImg, smallImg );
t = (double)getTickCount();

@ -232,7 +232,7 @@ int main (const int argc, const char * argv[])
}
else{ //apply random warp to input image
resize(inputImage, target_image, Size(216, 216));
resize(inputImage, target_image, Size(216, 216), 0, 0, INTER_LINEAR_EXACT);
Mat warpGround;
RNG rng(getTickCount());
double angle;

@ -80,7 +80,7 @@ int main(int argc, char** argv)
queryName<<path<<indexQuery<<".png";
Mat query=imread(queryName.str(), IMREAD_GRAYSCALE);
Mat queryToShow;
resize(query, queryToShow, sz2Sh);
resize(query, queryToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT);
imshow("QUERY", queryToShow);
moveWindow("TEST", 0,0);
vector<Point> contQuery = simpleContour(query);
@ -95,7 +95,7 @@ int main(int argc, char** argv)
cout<<"name: "<<iiname.str()<<endl;
Mat iiIm=imread(iiname.str(), 0);
Mat iiToShow;
resize(iiIm, iiToShow, sz2Sh);
resize(iiIm, iiToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT);
imshow("TEST", iiToShow);
moveWindow("TEST", sz2Sh.width+50,0);
vector<Point> contii = simpleContour(iiIm);
@ -112,7 +112,7 @@ int main(int argc, char** argv)
bestname<<path<<bestMatch<<".png";
Mat iiIm=imread(bestname.str(), 0);
Mat bestToShow;
resize(iiIm, bestToShow, sz2Sh);
resize(iiIm, bestToShow, sz2Sh, 0, 0, INTER_LINEAR_EXACT);
imshow("BEST MATCH", bestToShow);
moveWindow("BEST MATCH", sz2Sh.width+50,0);
waitKey();

@ -135,7 +135,7 @@ void detectAndDraw( Mat& img, CascadeClassifier& cascade,
cvtColor( img, gray, COLOR_BGR2GRAY );
double fx = 1 / scale;
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR );
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT );
equalizeHist( smallImg, smallImg );
cascade.detectMultiScale( smallImg, faces,

@ -100,7 +100,7 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
if( scale == 1 )
timg = img;
else
resize(img, timg, Size(), scale, scale);
resize(img, timg, Size(), scale, scale, INTER_LINEAR_EXACT);
found = findChessboardCorners(timg, boardSize, corners,
CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);
if( found )
@ -120,7 +120,7 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
cvtColor(img, cimg, COLOR_GRAY2BGR);
drawChessboardCorners(cimg, boardSize, corners, found);
double sf = 640./MAX(img.rows, img.cols);
resize(cimg, cimg1, Size(), sf, sf);
resize(cimg, cimg1, Size(), sf, sf, INTER_LINEAR_EXACT);
imshow("corners", cimg1);
char c = (char)waitKey(500);
if( c == 27 || c == 'q' || c == 'Q' ) //Allow ESC to quit

@ -465,7 +465,7 @@ int main(int argc, char* argv[])
work_scale = min(1.0, sqrt(work_megapix * 1e6 / full_img.size().area()));
is_work_scale_set = true;
}
resize(full_img, img, Size(), work_scale, work_scale);
resize(full_img, img, Size(), work_scale, work_scale, INTER_LINEAR_EXACT);
}
if (!is_seam_scale_set)
{
@ -478,7 +478,7 @@ int main(int argc, char* argv[])
features[i].img_idx = i;
LOGLN("Features in image #" << i+1 << ": " << features[i].keypoints.size());
resize(full_img, img, Size(), seam_scale, seam_scale);
resize(full_img, img, Size(), seam_scale, seam_scale, INTER_LINEAR_EXACT);
images[i] = img.clone();
}
@ -805,7 +805,7 @@ int main(int argc, char* argv[])
}
}
if (abs(compose_scale - 1) > 1e-1)
resize(full_img, img, Size(), compose_scale, compose_scale);
resize(full_img, img, Size(), compose_scale, compose_scale, INTER_LINEAR_EXACT);
else
img = full_img;
full_img.release();
@ -831,7 +831,7 @@ int main(int argc, char* argv[])
mask.release();
dilate(masks_warped[img_idx], dilated_mask, Mat());
resize(dilated_mask, seam_mask, mask_warped.size());
resize(dilated_mask, seam_mask, mask_warped.size(), 0, 0, INTER_LINEAR_EXACT);
mask_warped = seam_mask & mask_warped;
if (!blender && !timelapse)

@ -344,7 +344,7 @@ int main( int argc, char** argv )
for ( size_t j = 0; j < detections.size(); j++ )
{
Mat detection = full_neg_lst[i]( detections[j] ).clone();
resize( detection, detection, pos_image_size );
resize( detection, detection, pos_image_size, 0, 0, INTER_LINEAR_EXACT);
neg_lst.push_back( detection );
}

@ -113,7 +113,7 @@ int main(int argc, char **argv)
exit(-1);
}
resize(img, img, Size(500, 500)); //FCN accepts 500x500 BGR-images
resize(img, img, Size(500, 500), 0, 0, INTER_LINEAR_EXACT); //FCN accepts 500x500 BGR-images
Mat inputBlob = blobFromImage(img, 1, Size(), Scalar(), false); //Convert Mat to batch of images
//! [Prepare blob]

@ -191,7 +191,7 @@ void App::run()
if (abs(scale-1.0)>0.001)
{
Size sz((int)((double)img_aux.cols/resize_scale), (int)((double)img_aux.rows/resize_scale));
resize(img_aux, img, sz);
resize(img_aux, img, sz, 0, 0, INTER_LINEAR_EXACT);
}
else img = img_aux;
img.copyTo(img_to_show);

@ -177,7 +177,7 @@ void detectAndDraw( UMat& img, Mat& canvas, CascadeClassifier& cascade,
cvtColor( img, gray, COLOR_BGR2GRAY );
double fx = 1 / scale;
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR );
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT );
equalizeHist( smallImg, smallImg );
cascade.detectMultiScale( smallImg, faces,

Loading…
Cancel
Save