mirror of
https://github.com/opencv/opencv.git
synced 2026-09-13 05:42:51 -05:00
Merge pull request #29512 from Akansha-977:rectsubpix_IPP_4.x
Extracted IPP to HAL for getRectSubPix function in 4.x - #29512 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -27,6 +27,7 @@ add_library(ipphal STATIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/threshold_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/distancetransform_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/histogram_ipp.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/samplers_ipp.cpp"
|
||||
)
|
||||
|
||||
#TODO: HAVE_IPP_ICV and HAVE_IPP_IW added as private macro till OpenCV itself is
|
||||
|
||||
@@ -159,6 +159,12 @@ int ipp_hal_calcHist(const uchar* src_data, size_t src_step, int src_type, int s
|
||||
#undef cv_hal_calcHist
|
||||
#define cv_hal_calcHist ipp_hal_calcHist
|
||||
|
||||
int ipp_hal_getRectSubPix(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
|
||||
int patch_type, uchar* patch_data, size_t patch_step, int patch_width, int patch_height,
|
||||
double center_x, double center_y);
|
||||
#undef cv_hal_getRectSubPix
|
||||
#define cv_hal_getRectSubPix ipp_hal_getRectSubPix
|
||||
|
||||
#endif // IPP_VERSION_X100 >= 700
|
||||
|
||||
#define IPP_DISABLE_PERF_CANNY_MT 1 // cv::Canny OpenCV MT performance is better
|
||||
|
||||
49
hal/ipp/src/samplers_ipp.cpp
Normal file
49
hal/ipp/src/samplers_ipp.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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) 2026, BigVision LLC, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "ipp_hal_imgproc.hpp"
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int ipp_hal_getRectSubPix(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
|
||||
int patch_type, uchar* patch_data, size_t patch_step, int patch_width, int patch_height,
|
||||
double center_x, double center_y)
|
||||
{
|
||||
CV_HAL_CHECK_USE_IPP();
|
||||
|
||||
int ddepth = CV_MAT_DEPTH(patch_type);
|
||||
|
||||
typedef IppStatus (CV_STDCALL *ippiGetRectSubPixFunc)( const void* src, int src_step,
|
||||
IppiSize src_size, void* dst,
|
||||
int dst_step, IppiSize win_size,
|
||||
IppiPoint_32f center,
|
||||
IppiPoint* minpt, IppiPoint* maxpt );
|
||||
|
||||
ippiGetRectSubPixFunc ippiCopySubpixIntersect =
|
||||
src_type == CV_8UC1 && ddepth == CV_8U ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u_C1R :
|
||||
src_type == CV_8UC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u32f_C1R :
|
||||
src_type == CV_32FC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_32f_C1R : 0;
|
||||
|
||||
if( ippiCopySubpixIntersect )
|
||||
{
|
||||
IppiPoint minpt = {0, 0}, maxpt = {0, 0};
|
||||
IppiPoint_32f icenter = {(float)center_x, (float)center_y};
|
||||
IppiSize src_size = {src_width, src_height}, win_size = {patch_width, patch_height};
|
||||
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiCopySubpixIntersect, src_data, (int)src_step, src_size, patch_data,
|
||||
(int)patch_step, win_size, icenter, &minpt, &maxpt) >= 0 )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
134
modules/imgproc/perf/perf_getrectsubpix.cpp
Normal file
134
modules/imgproc/perf/perf_getrectsubpix.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
// 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) 2026, BigVision LLC, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
#include "perf_precomp.hpp"
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
CV_ENUM(PatchDepth, CV_8U, CV_32F)
|
||||
|
||||
typedef tuple<Size, MatType, PatchDepth> GetRectSubPixParams;
|
||||
typedef perf::TestBaseWithParam<GetRectSubPixParams> GetRectSubPix_Test;
|
||||
|
||||
// Chessboard inner corners (9x6) of the cv/stereo/case1 boards, detected once with
|
||||
// findChessboardCorners and hard-coded so this perf test needs no calib dependency.
|
||||
static const Point2f corners_left01[] = {
|
||||
Point2f(244.4541f, 94.3314f), Point2f(274.6218f, 92.2413f), Point2f(305.4939f, 90.4029f),
|
||||
Point2f(338.3641f, 88.8363f), Point2f(371.5922f, 87.9836f), Point2f(406.8435f, 86.9164f),
|
||||
Point2f(441.6335f, 86.3721f), Point2f(477.6230f, 86.3797f), Point2f(513.9866f, 86.7991f),
|
||||
Point2f(244.9995f, 126.5384f), Point2f(274.9684f, 124.7523f), Point2f(306.0444f, 124.0323f),
|
||||
Point2f(338.7149f, 123.2651f), Point2f(372.0939f, 122.1290f), Point2f(406.6485f, 122.1684f),
|
||||
Point2f(442.1944f, 122.2465f), Point2f(477.8674f, 122.1053f), Point2f(514.0326f, 122.9214f),
|
||||
Point2f(245.4698f, 158.3554f), Point2f(275.3708f, 158.3770f), Point2f(306.4206f, 157.6200f),
|
||||
Point2f(338.7076f, 157.4221f), Point2f(372.3548f, 157.3757f), Point2f(406.5436f, 157.4915f),
|
||||
Point2f(442.1193f, 157.6772f), Point2f(477.6427f, 158.4171f), Point2f(513.5308f, 159.2809f),
|
||||
Point2f(246.3835f, 190.2633f), Point2f(275.7964f, 190.6393f), Point2f(307.2744f, 191.0970f),
|
||||
Point2f(339.1837f, 191.5760f), Point2f(372.3740f, 191.8712f), Point2f(406.9517f, 192.4470f),
|
||||
Point2f(441.5515f, 193.6797f), Point2f(477.3305f, 194.3325f), Point2f(513.2557f, 195.5269f),
|
||||
Point2f(247.4330f, 222.4675f), Point2f(276.8233f, 223.4360f), Point2f(307.4332f, 224.2435f),
|
||||
Point2f(339.5576f, 225.2065f), Point2f(372.9427f, 226.4245f), Point2f(406.4261f, 227.5323f),
|
||||
Point2f(441.4084f, 228.5345f), Point2f(476.7176f, 230.1001f), Point2f(511.5294f, 231.5994f),
|
||||
Point2f(248.7999f, 253.5990f), Point2f(277.5086f, 255.1773f), Point2f(308.5765f, 256.4403f),
|
||||
Point2f(340.3875f, 258.2953f), Point2f(372.7524f, 259.7994f), Point2f(406.1046f, 261.6587f),
|
||||
Point2f(440.4359f, 263.3060f), Point2f(475.4150f, 264.7134f), Point2f(510.1775f, 266.1992f),
|
||||
};
|
||||
|
||||
static const Point2f corners_left02[] = {
|
||||
Point2f(256.5867f, 357.3861f), Point2f(255.3215f, 334.4808f), Point2f(254.7554f, 309.0343f),
|
||||
Point2f(253.2735f, 280.1345f), Point2f(252.5384f, 248.0337f), Point2f(251.7535f, 212.7699f),
|
||||
Point2f(251.2085f, 172.4518f), Point2f(251.3873f, 128.3270f), Point2f(251.4556f, 78.3560f),
|
||||
Point2f(291.6361f, 365.9622f), Point2f(292.5572f, 343.3497f), Point2f(293.5726f, 318.2415f),
|
||||
Point2f(295.2780f, 289.9100f), Point2f(296.7264f, 257.9767f), Point2f(298.7410f, 222.1348f),
|
||||
Point2f(301.2631f, 182.4788f), Point2f(303.7642f, 136.7058f), Point2f(307.1471f, 86.7391f),
|
||||
Point2f(327.6240f, 374.3524f), Point2f(330.8632f, 352.3100f), Point2f(334.4490f, 327.3103f),
|
||||
Point2f(337.8723f, 299.4167f), Point2f(342.3027f, 267.7063f), Point2f(347.3625f, 232.3861f),
|
||||
Point2f(352.3509f, 192.1027f), Point2f(358.5134f, 147.0249f), Point2f(365.3164f, 97.3291f),
|
||||
Point2f(364.5553f, 381.6275f), Point2f(369.4413f, 360.3667f), Point2f(375.1765f, 335.9256f),
|
||||
Point2f(381.4051f, 308.1661f), Point2f(388.5566f, 277.6599f), Point2f(396.0829f, 242.0081f),
|
||||
Point2f(404.5149f, 202.7227f), Point2f(413.7823f, 158.0101f), Point2f(424.3409f, 107.9548f),
|
||||
Point2f(401.3313f, 389.5627f), Point2f(408.5090f, 368.3929f), Point2f(416.5022f, 344.4312f),
|
||||
Point2f(425.1089f, 317.5573f), Point2f(434.4975f, 286.7095f), Point2f(445.0846f, 252.4719f),
|
||||
Point2f(456.7321f, 213.5597f), Point2f(469.1978f, 169.3279f), Point2f(483.2666f, 120.4614f),
|
||||
Point2f(437.8366f, 396.5025f), Point2f(446.5643f, 375.8865f), Point2f(456.9603f, 352.2726f),
|
||||
Point2f(467.8020f, 326.0813f), Point2f(480.4469f, 295.9886f), Point2f(493.1928f, 262.2359f),
|
||||
Point2f(508.0341f, 223.9814f), Point2f(523.4081f, 181.1591f), Point2f(540.2076f, 133.2355f),
|
||||
};
|
||||
|
||||
static const Point2f corners_left03[] = {
|
||||
Point2f(277.4323f, 72.5290f), Point2f(313.4367f, 81.5630f), Point2f(352.9303f, 91.0506f),
|
||||
Point2f(393.5079f, 101.8541f), Point2f(434.6314f, 113.5358f), Point2f(476.8674f, 126.6859f),
|
||||
Point2f(519.5198f, 139.4719f), Point2f(562.0754f, 154.0302f), Point2f(603.5757f, 168.5026f),
|
||||
Point2f(259.6532f, 105.6526f), Point2f(297.3900f, 115.0693f), Point2f(337.2212f, 126.4162f),
|
||||
Point2f(378.3126f, 137.9841f), Point2f(421.3062f, 150.6102f), Point2f(464.5258f, 164.5774f),
|
||||
Point2f(508.5670f, 178.7557f), Point2f(552.4766f, 193.4379f), Point2f(595.2234f, 208.4552f),
|
||||
Point2f(242.7253f, 141.3230f), Point2f(279.8400f, 152.2348f), Point2f(320.5120f, 163.9313f),
|
||||
Point2f(362.5777f, 177.0284f), Point2f(406.0779f, 190.5102f), Point2f(450.5823f, 205.4244f),
|
||||
Point2f(495.9811f, 220.1399f), Point2f(541.2142f, 235.4248f), Point2f(585.0867f, 250.9424f),
|
||||
Point2f(223.8041f, 178.0292f), Point2f(262.7206f, 190.8443f), Point2f(303.1327f, 204.2207f),
|
||||
Point2f(345.8119f, 218.4479f), Point2f(389.5984f, 233.0941f), Point2f(435.4800f, 248.5219f),
|
||||
Point2f(481.7506f, 264.2025f), Point2f(528.0433f, 280.0055f), Point2f(573.3781f, 295.7106f),
|
||||
Point2f(205.9287f, 217.1566f), Point2f(244.4685f, 230.9739f), Point2f(285.0102f, 245.5548f),
|
||||
Point2f(328.2179f, 261.5405f), Point2f(373.1269f, 277.2205f), Point2f(419.5606f, 293.7301f),
|
||||
Point2f(466.3259f, 310.0434f), Point2f(513.5237f, 326.6496f), Point2f(559.9616f, 342.5871f),
|
||||
Point2f(187.4462f, 257.4862f), Point2f(225.3331f, 272.8211f), Point2f(266.7754f, 289.3292f),
|
||||
Point2f(309.9885f, 305.9286f), Point2f(354.7533f, 323.2353f), Point2f(402.4073f, 340.2387f),
|
||||
Point2f(449.5339f, 357.9061f), Point2f(497.6018f, 374.2831f), Point2f(544.2325f, 390.1797f),
|
||||
};
|
||||
|
||||
struct Board { const char* path; const Point2f* corners; int ncorners; };
|
||||
static const Board g_boards[] = {
|
||||
{ "cv/stereo/case1/left01.png", corners_left01, (int)(sizeof(corners_left01) / sizeof(Point2f)) },
|
||||
{ "cv/stereo/case1/left02.png", corners_left02, (int)(sizeof(corners_left02) / sizeof(Point2f)) },
|
||||
{ "cv/stereo/case1/left03.png", corners_left03, (int)(sizeof(corners_left03) / sizeof(Point2f)) },
|
||||
};
|
||||
|
||||
PERF_TEST_P(GetRectSubPix_Test, getRectSubPix,
|
||||
testing::Combine(
|
||||
testing::Values(Size(16, 16), Size(32, 32), Size(64, 64), Size(128, 128)),
|
||||
testing::Values(CV_8UC1, CV_32FC1),
|
||||
PatchDepth::all()
|
||||
)
|
||||
)
|
||||
{
|
||||
Size patchSize = get<0>(GetParam());
|
||||
int srcType = get<1>(GetParam());
|
||||
int patchDepth = get<2>(GetParam());
|
||||
|
||||
// getRectSubPix supports only 8U->8U, 8U->32F and 32F->32F
|
||||
if (CV_MAT_DEPTH(srcType) == CV_32F && patchDepth == CV_8U)
|
||||
throw SkipTestException("getRectSubPix does not support 32F source with 8U patch");
|
||||
|
||||
const size_t nboards = sizeof(g_boards) / sizeof(g_boards[0]);
|
||||
std::vector<Mat> srcs;
|
||||
for (size_t b = 0; b < nboards; b++)
|
||||
{
|
||||
Mat image = imread(getDataPath(g_boards[b].path), IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(image.empty());
|
||||
if (CV_MAT_DEPTH(srcType) == CV_32F)
|
||||
{
|
||||
Mat f;
|
||||
image.convertTo(f, CV_32F);
|
||||
srcs.push_back(f);
|
||||
}
|
||||
else
|
||||
srcs.push_back(image);
|
||||
}
|
||||
|
||||
int patchType = CV_MAKETYPE(patchDepth, 1);
|
||||
Mat patch(patchSize, patchType);
|
||||
|
||||
declare.in(srcs[0]);
|
||||
|
||||
TEST_CYCLE()
|
||||
{
|
||||
for (size_t b = 0; b < nboards; b++)
|
||||
for (int i = 0; i < g_boards[b].ncorners; i++)
|
||||
getRectSubPix(srcs[b], patchSize, g_boards[b].corners[i], patch, patchType);
|
||||
}
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -460,6 +460,28 @@ inline int hal_ni_warpPerspectiveBlockline(const double *M, short* xy, short* al
|
||||
#define cv_hal_warpPerspectiveBlockline hal_ni_warpPerspectiveBlockline
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
@brief hal_getRectSubPix extract a rectangle from an image with sub-pixel accuracy
|
||||
@param src_type source image type
|
||||
@param src_data source image data
|
||||
@param src_step source image step
|
||||
@param src_width source image width
|
||||
@param src_height source image height
|
||||
@param patch_type extracted patch type
|
||||
@param patch_data extracted patch data
|
||||
@param patch_step extracted patch step
|
||||
@param patch_width extracted patch width
|
||||
@param patch_height extracted patch height
|
||||
@param center_x x-coordinate of the rectangle center (sub-pixel)
|
||||
@param center_y y-coordinate of the rectangle center (sub-pixel)
|
||||
@sa cv::getRectSubPix
|
||||
*/
|
||||
inline int hal_ni_getRectSubPix(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, int patch_type, uchar* patch_data, size_t patch_step, int patch_width, int patch_height, double center_x, double center_y) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
//! @cond IGNORED
|
||||
#define cv_hal_getRectSubPix hal_ni_getRectSubPix
|
||||
//! @endcond
|
||||
|
||||
/**
|
||||
@brief hal_remap with floating point maps
|
||||
@param src_type source and destination image type
|
||||
|
||||
@@ -376,36 +376,10 @@ void cv::getRectSubPix( InputArray _image, Size patchSize, Point2f center,
|
||||
_patch.create(patchSize, CV_MAKETYPE(ddepth, cn));
|
||||
Mat patch = _patch.getMat();
|
||||
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700)
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL *ippiGetRectSubPixFunc)( const void* src, int src_step,
|
||||
IppiSize src_size, void* dst,
|
||||
int dst_step, IppiSize win_size,
|
||||
IppiPoint_32f center,
|
||||
IppiPoint* minpt, IppiPoint* maxpt );
|
||||
|
||||
IppiPoint minpt={0,0}, maxpt={0,0};
|
||||
IppiPoint_32f icenter = {center.x, center.y};
|
||||
IppiSize src_size={image.cols, image.rows}, win_size={patch.cols, patch.rows};
|
||||
int srctype = image.type();
|
||||
ippiGetRectSubPixFunc ippiCopySubpixIntersect =
|
||||
srctype == CV_8UC1 && ddepth == CV_8U ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u_C1R :
|
||||
srctype == CV_8UC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u32f_C1R :
|
||||
srctype == CV_32FC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_32f_C1R : 0;
|
||||
|
||||
if( ippiCopySubpixIntersect)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiCopySubpixIntersect, image.ptr(), (int)image.step, src_size, patch.ptr(),
|
||||
(int)patch.step, win_size, icenter, &minpt, &maxpt) >= 0)
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP);
|
||||
return;
|
||||
}
|
||||
setIppErrorStatus();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CALL_HAL(getRectSubPix, cv_hal_getRectSubPix,
|
||||
image.type(), image.data, image.step, image.cols, image.rows,
|
||||
patch.type(), patch.data, patch.step, patch.cols, patch.rows,
|
||||
center.x, center.y);
|
||||
|
||||
if( depth == CV_8U && ddepth == CV_8U )
|
||||
getRectSubPix_Cn_<uchar, uchar, int, scale_fixpt, cast_8u>
|
||||
|
||||
Reference in New Issue
Block a user