File: test_moments.cpp

package info (click to toggle)
opencv 4.10.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 282,092 kB
  • sloc: cpp: 1,178,079; xml: 682,621; python: 49,092; lisp: 31,150; java: 25,469; ansic: 11,039; javascript: 6,085; sh: 1,214; cs: 601; perl: 494; objc: 210; makefile: 173
file content (121 lines) | stat: -rw-r--r-- 5,920 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// 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"

#ifdef HAVE_CUDA

namespace opencv_test { namespace {

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Moments

CV_ENUM(MaxMomentsOrder, MomentsOrder::FIRST_ORDER_MOMENTS, MomentsOrder::SECOND_ORDER_MOMENTS, MomentsOrder::THIRD_ORDER_MOMENTS)

PARAM_TEST_CASE(Moments, cv::cuda::DeviceInfo, cv::Size, bool, MatDepth, MatDepth, UseRoi, MaxMomentsOrder)
{
    DeviceInfo devInfo;
    Size size;
    bool isBinary;
    float pcWidth = 0.6f;
    int momentsType;
    int imgType;
    bool useRoi;
    MomentsOrder order;

    virtual void SetUp()
    {
        devInfo = GET_PARAM(0);
        size = GET_PARAM(1);
        isBinary = GET_PARAM(2);
        momentsType = GET_PARAM(3);
        imgType = GET_PARAM(4);
        useRoi = GET_PARAM(5);
        order = static_cast<MomentsOrder>(static_cast<int>(GET_PARAM(6)));
        cv::cuda::setDevice(devInfo.deviceID());
    }

    static void drawCircle(cv::Mat& dst, const cv::Vec3i& circle, bool fill)
    {
        dst.setTo(Scalar::all(0));
        cv::circle(dst, Point2i(circle[0], circle[1]), circle[2], Scalar::all(255), fill ? -1 : 1, cv::LINE_AA);
    }
};

bool Equal(const double m0, const double m1, const double absPcErr) {
    if (absPcErr == 0) return m0 == m1;
    if (m0 == 0) {
        if (m1 < absPcErr) return true;
        else return false;
    }
    const double pcDiff = abs(m0 - m1) / m1;
    return pcDiff < absPcErr;
}

void CheckMoments(const cv::Moments m0, const cv::Moments m1, const MomentsOrder order, const int momentsType) {
    double absPcErr = momentsType == CV_64F ? 0 : 5e-7;
    ASSERT_TRUE(Equal(m0.m00, m1.m00, absPcErr)) << "m0.m00: " << m0.m00 << ", m1.m00: " << m1.m00 << ", absPcErr: " << absPcErr;
    ASSERT_TRUE(Equal(m0.m10, m1.m10, absPcErr)) << "m0.m10: " << m0.m10 << ", m1.m10: " << m1.m10 << ", absPcErr: " << absPcErr;
    ASSERT_TRUE(Equal(m0.m01, m1.m01, absPcErr)) << "m0.m01: " << m0.m01 << ", m1.m01: " << m1.m01 << ", absPcErr: " << absPcErr;
    if (static_cast<int>(order) >= static_cast<int>(MomentsOrder::SECOND_ORDER_MOMENTS)) {
        ASSERT_TRUE(Equal(m0.m20, m1.m20, absPcErr)) << "m0.m20: " << m0.m20 << ", m1.m20: " << m1.m20 << ", absPcErr: " << absPcErr;
        ASSERT_TRUE(Equal(m0.m11, m1.m11, absPcErr)) << "m0.m11: " << m0.m11 << ", m1.m11: " << m1.m11 << ", absPcErr: " << absPcErr;
        ASSERT_TRUE(Equal(m0.m02, m1.m02, absPcErr)) << "m0.m02: " << m0.m02 << ", m1.m02: " << m1.m02 << ", absPcErr: " << absPcErr;
    }
    if (static_cast<int>(order) >= static_cast<int>(MomentsOrder::THIRD_ORDER_MOMENTS)) {
        ASSERT_TRUE(Equal(m0.m30, m1.m30, absPcErr)) << "m0.m30: " << m0.m30 << ", m1.m30: " << m1.m30 << ", absPcErr: " << absPcErr;
        ASSERT_TRUE(Equal(m0.m21, m1.m21, absPcErr)) << "m0.m21: " << m0.m21 << ", m1.m21: " << m1.m21 << ", absPcErr: " << absPcErr;
        ASSERT_TRUE(Equal(m0.m12, m1.m12, absPcErr)) << "m0.m12: " << m0.m12 << ", m1.m12: " << m1.m12 << ", absPcErr: " << absPcErr;
        ASSERT_TRUE(Equal(m0.m03, m1.m03, absPcErr)) << "m0.m03: " << m0.m03 << ", m1.m03: " << m1.m03 << ", absPcErr: " << absPcErr;
    }
}

CUDA_TEST_P(Moments, Accuracy)
{
    Mat imgHost(size, imgType);
    const Rect roi = useRoi ? Rect(1, 0, imgHost.cols - 2, imgHost.rows) : Rect(0, 0, imgHost.cols, imgHost.rows);
    const Vec3i circle(size.width / 2, size.height / 2, static_cast<int>(static_cast<float>(size.width/2) * pcWidth));
    drawCircle(imgHost, circle, true);
    const GpuMat imgDevice(imgHost);
    const int nMoments = numMoments(order);
    setBufferPoolUsage(true);
    setBufferPoolConfig(getDevice(), nMoments * ((momentsType == CV_64F) ? sizeof(double) : sizeof(float)), 1);
    const cv::Moments moments = cuda::moments(imgDevice(roi), isBinary, order, momentsType);
    Mat imgHostFloat; imgHost(roi).convertTo(imgHostFloat, CV_32F);
    const cv::Moments momentsGs = cv::moments(imgHostFloat, isBinary);
    CheckMoments(momentsGs, moments, order, momentsType);
}

CUDA_TEST_P(Moments, Async)
{
    Stream stream;
    const int nMoments = numMoments(order);
    GpuMat momentsDevice(1, nMoments, momentsType);
    Mat imgHost(size, imgType);
    const Rect roi = useRoi ? Rect(1, 0, imgHost.cols - 2, imgHost.rows) : Rect(0, 0, imgHost.cols, imgHost.rows);
    const Vec3i circle(size.width / 2, size.height / 2, static_cast<int>(static_cast<float>(size.width/2) * pcWidth));
    drawCircle(imgHost, circle, true);
    const GpuMat imgDevice(imgHost);
    cuda::spatialMoments(imgDevice(roi), momentsDevice, isBinary, order, momentsType, stream);
    HostMem momentsHost(1, nMoments, momentsType);
    momentsDevice.download(momentsHost, stream);
    stream.waitForCompletion();
    const cv::Moments moments  = convertSpatialMoments(momentsHost.createMatHeader(), order, momentsType);
    Mat imgHostAdjustedType = imgHost(roi);
    if (imgType != CV_8U && imgType != CV_32F)
        imgHost(roi).convertTo(imgHostAdjustedType, CV_32F);
    const cv::Moments momentsGs = cv::moments(imgHostAdjustedType, isBinary);
    CheckMoments(momentsGs, moments, order, momentsType);
}

#define SIZES DIFFERENT_SIZES
#define GRAYSCALE_BINARY testing::Bool()
#define MOMENTS_TYPE testing::Values(MatDepth(CV_32F), MatDepth(CV_64F))
#define IMG_TYPE ALL_DEPTH
#define USE_ROI WHOLE_SUBMAT
#define MOMENTS_ORDER testing::Values(MaxMomentsOrder(MomentsOrder::FIRST_ORDER_MOMENTS), MaxMomentsOrder(MomentsOrder::SECOND_ORDER_MOMENTS), MaxMomentsOrder(MomentsOrder::THIRD_ORDER_MOMENTS))
INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, Moments, testing::Combine(ALL_DEVICES, SIZES, GRAYSCALE_BINARY, MOMENTS_TYPE, IMG_TYPE, USE_ROI, MOMENTS_ORDER));
}} // namespace

#endif // HAVE_CUDA