test_hough.cpp 8.45 KB
Newer Older
wester committed
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
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "test_precomp.hpp"

#ifdef HAVE_CUDA

using namespace cvtest;

///////////////////////////////////////////////////////////////////////////////////////////////////////
// HoughLines

wester committed
52
PARAM_TEST_CASE(HoughLines, cv::gpu::DeviceInfo, cv::Size, UseRoi)
wester committed
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
{
    static void generateLines(cv::Mat& img)
    {
        img.setTo(cv::Scalar::all(0));

        cv::line(img, cv::Point(20, 0), cv::Point(20, img.rows), cv::Scalar::all(255));
        cv::line(img, cv::Point(0, 50), cv::Point(img.cols, 50), cv::Scalar::all(255));
        cv::line(img, cv::Point(0, 0), cv::Point(img.cols, img.rows), cv::Scalar::all(255));
        cv::line(img, cv::Point(img.cols, 0), cv::Point(0, img.rows), cv::Scalar::all(255));
    }

    static void drawLines(cv::Mat& dst, const std::vector<cv::Vec2f>& lines)
    {
        dst.setTo(cv::Scalar::all(0));

        for (size_t i = 0; i < lines.size(); ++i)
        {
            float rho = lines[i][0], theta = lines[i][1];
            cv::Point pt1, pt2;
            double a = std::cos(theta), b = std::sin(theta);
            double x0 = a*rho, y0 = b*rho;
            pt1.x = cvRound(x0 + 1000*(-b));
            pt1.y = cvRound(y0 + 1000*(a));
            pt2.x = cvRound(x0 - 1000*(-b));
            pt2.y = cvRound(y0 - 1000*(a));
            cv::line(dst, pt1, pt2, cv::Scalar::all(255));
        }
    }
};

wester committed
83
GPU_TEST_P(HoughLines, Accuracy)
wester committed
84
{
wester committed
85 86
    const cv::gpu::DeviceInfo devInfo = GET_PARAM(0);
    cv::gpu::setDevice(devInfo.deviceID());
wester committed
87 88 89 90 91 92 93 94 95 96
    const cv::Size size = GET_PARAM(1);
    const bool useRoi = GET_PARAM(2);

    const float rho = 1.0f;
    const float theta = (float) (1.5 * CV_PI / 180.0);
    const int threshold = 100;

    cv::Mat src(size, CV_8UC1);
    generateLines(src);

wester committed
97 98
    cv::gpu::GpuMat d_lines;
    cv::gpu::HoughLines(loadMat(src, useRoi), d_lines, rho, theta, threshold);
wester committed
99 100

    std::vector<cv::Vec2f> lines;
wester committed
101
    cv::gpu::HoughLinesDownload(d_lines, lines);
wester committed
102 103 104 105 106 107 108

    cv::Mat dst(size, CV_8UC1);
    drawLines(dst, lines);

    ASSERT_MAT_NEAR(src, dst, 0.0);
}

wester committed
109
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HoughLines, testing::Combine(
wester committed
110 111 112 113 114 115 116
    ALL_DEVICES,
    DIFFERENT_SIZES,
    WHOLE_SUBMAT));

///////////////////////////////////////////////////////////////////////////////////////////////////////
// HoughCircles

wester committed
117
PARAM_TEST_CASE(HoughCircles, cv::gpu::DeviceInfo, cv::Size, UseRoi)
wester committed
118 119 120 121 122 123 124 125 126 127
{
    static void drawCircles(cv::Mat& dst, const std::vector<cv::Vec3f>& circles, bool fill)
    {
        dst.setTo(cv::Scalar::all(0));

        for (size_t i = 0; i < circles.size(); ++i)
            cv::circle(dst, cv::Point2f(circles[i][0], circles[i][1]), (int)circles[i][2], cv::Scalar::all(255), fill ? -1 : 1);
    }
};

wester committed
128
GPU_TEST_P(HoughCircles, Accuracy)
wester committed
129
{
wester committed
130 131
    const cv::gpu::DeviceInfo devInfo = GET_PARAM(0);
    cv::gpu::setDevice(devInfo.deviceID());
wester committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
    const cv::Size size = GET_PARAM(1);
    const bool useRoi = GET_PARAM(2);

    const float dp = 2.0f;
    const float minDist = 0.0f;
    const int minRadius = 10;
    const int maxRadius = 20;
    const int cannyThreshold = 100;
    const int votesThreshold = 20;

    std::vector<cv::Vec3f> circles_gold(4);
    circles_gold[0] = cv::Vec3i(20, 20, minRadius);
    circles_gold[1] = cv::Vec3i(90, 87, minRadius + 3);
    circles_gold[2] = cv::Vec3i(30, 70, minRadius + 8);
    circles_gold[3] = cv::Vec3i(80, 10, maxRadius);

    cv::Mat src(size, CV_8UC1);
    drawCircles(src, circles_gold, true);

wester committed
151 152
    cv::gpu::GpuMat d_circles;
    cv::gpu::HoughCircles(loadMat(src, useRoi), d_circles, CV_HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius);
wester committed
153 154

    std::vector<cv::Vec3f> circles;
wester committed
155
    cv::gpu::HoughCirclesDownload(d_circles, circles);
wester committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

    ASSERT_FALSE(circles.empty());

    for (size_t i = 0; i < circles.size(); ++i)
    {
        cv::Vec3f cur = circles[i];

        bool found = false;

        for (size_t j = 0; j < circles_gold.size(); ++j)
        {
            cv::Vec3f gold = circles_gold[j];

            if (std::fabs(cur[0] - gold[0]) < 5 && std::fabs(cur[1] - gold[1]) < 5 && std::fabs(cur[2] - gold[2]) < 5)
            {
                found = true;
                break;
            }
        }

        ASSERT_TRUE(found);
    }
}

wester committed
180
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HoughCircles, testing::Combine(
wester committed
181 182 183 184 185 186 187
    ALL_DEVICES,
    DIFFERENT_SIZES,
    WHOLE_SUBMAT));

///////////////////////////////////////////////////////////////////////////////////////////////////////
// GeneralizedHough

wester committed
188 189 190
#if !defined(__GNUC__) || (__GNUC__ * 10 + __GNUC_MINOR__ != 47)

PARAM_TEST_CASE(GeneralizedHough, cv::gpu::DeviceInfo, UseRoi)
wester committed
191 192 193
{
};

wester committed
194
GPU_TEST_P(GeneralizedHough, POSITION)
wester committed
195
{
wester committed
196 197
    const cv::gpu::DeviceInfo devInfo = GET_PARAM(0);
    cv::gpu::setDevice(devInfo.deviceID());
wester committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
    const bool useRoi = GET_PARAM(1);

    cv::Mat templ = readImage("../cv/shared/templ.png", cv::IMREAD_GRAYSCALE);
    ASSERT_FALSE(templ.empty());

    cv::Point templCenter(templ.cols / 2, templ.rows / 2);

    const size_t gold_count = 3;
    cv::Point pos_gold[gold_count];
    pos_gold[0] = cv::Point(templCenter.x + 10, templCenter.y + 10);
    pos_gold[1] = cv::Point(2 * templCenter.x + 40, templCenter.y + 10);
    pos_gold[2] = cv::Point(2 * templCenter.x + 40, 2 * templCenter.y + 40);

    cv::Mat image(templ.rows * 3, templ.cols * 3, CV_8UC1, cv::Scalar::all(0));
    for (size_t i = 0; i < gold_count; ++i)
    {
        cv::Rect rec(pos_gold[i].x - templCenter.x, pos_gold[i].y - templCenter.y, templ.cols, templ.rows);
        cv::Mat imageROI = image(rec);
        templ.copyTo(imageROI);
    }

wester committed
219 220
    cv::Ptr<cv::gpu::GeneralizedHough_GPU> hough = cv::gpu::GeneralizedHough_GPU::create(cv::GHT_POSITION);
    hough->set("votesThreshold", 200);
wester committed
221

wester committed
222
    hough->setTemplate(loadMat(templ, useRoi));
wester committed
223

wester committed
224 225
    cv::gpu::GpuMat d_pos;
    hough->detect(loadMat(image, useRoi), d_pos);
wester committed
226 227

    std::vector<cv::Vec4f> pos;
wester committed
228
    hough->download(d_pos, pos);
wester committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252

    ASSERT_EQ(gold_count, pos.size());

    for (size_t i = 0; i < gold_count; ++i)
    {
        cv::Point gold = pos_gold[i];

        bool found = false;

        for (size_t j = 0; j < pos.size(); ++j)
        {
            cv::Point2f p(pos[j][0], pos[j][1]);

            if (::fabs(p.x - gold.x) < 2 && ::fabs(p.y - gold.y) < 2)
            {
                found = true;
                break;
            }
        }

        ASSERT_TRUE(found);
    }
}

wester committed
253
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, GeneralizedHough, testing::Combine(
wester committed
254 255 256
    ALL_DEVICES,
    WHOLE_SUBMAT));

wester committed
257 258
#endif

wester committed
259
#endif // HAVE_CUDA