implemented gpu::norm via absSum, sqrSum, and minMax (removed norm_diff call), added...
authorAlexey Spizhevoy <no@email>
Tue, 1 Feb 2011 10:23:10 +0000 (10:23 +0000)
committerAlexey Spizhevoy <no@email>
Tue, 1 Feb 2011 10:23:10 +0000 (10:23 +0000)
doc/gpu_matrix_reductions.tex
modules/gpu/src/matrix_reductions.cpp
tests/gpu/src/imgproc_gpu.cpp

index fd78673..70b5c5f 100644 (file)
@@ -19,7 +19,7 @@ Returns norm of matrix (or of two matrices difference).
 \r
 \cvdefCpp{double norm(const GpuMat\& src1, int normType=NORM\_L2);}\r
 \begin{description}\r
-\cvarg{src1}{Source matrix. \texttt{CV\_8UC1} matrices are supported for now.}\r
+\cvarg{src1}{Source matrix. Any matrices except 64F are supported.}\r
 \cvarg{normType}{Norm type. \texttt{NORM\_L1}, \texttt{NORM\_L2} and \texttt{NORM\_INF} are supported for now.}\r
 \end{description}\r
 \r
index 0c83271..3ef13f6 100644 (file)
@@ -86,9 +86,25 @@ void cv::gpu::meanStdDev(const GpuMat& src, Scalar& mean, Scalar& stddev)
 ////////////////////////////////////////////////////////////////////////\r
 // norm\r
 \r
-double cv::gpu::norm(const GpuMat& src1, int normType)\r
+double cv::gpu::norm(const GpuMat& src, int normType)\r
 {\r
-    return norm(src1, GpuMat(src1.size(), src1.type(), Scalar::all(0.0)), normType);\r
+    GpuMat src_single_channel = src.reshape(1);\r
+\r
+    if (normType == NORM_L1)\r
+        return absSum(src_single_channel)[0];\r
+\r
+    if (normType == NORM_L2)\r
+        return sqrt(sqrSum(src_single_channel)[0]);\r
+\r
+    if (normType == NORM_INF)\r
+    {\r
+        double min_val, max_val;\r
+        minMax(src_single_channel, &min_val, &max_val);\r
+        return std::max(std::abs(min_val), std::abs(max_val));\r
+    }\r
+\r
+    CV_Error(CV_StsBadArg, "norm: unsupported norm type");\r
+    return 0;\r
 }\r
 \r
 double cv::gpu::norm(const GpuMat& src1, const GpuMat& src2, int normType)\r
index d941a00..1de3bd6 100644 (file)
@@ -825,6 +825,77 @@ struct CV_GpuColumnSumTest: CvTest
     }\r
 };\r
 \r
+struct CV_GpuNormTest : CvTest \r
+{\r
+    CV_GpuNormTest() : CvTest("GPU-Norm", "norm") {}\r
+\r
+    void run(int)\r
+    {\r
+        try\r
+        {\r
+            RNG rng(0);\r
+\r
+            int rows = rng.uniform(1, 500);\r
+            int cols = rng.uniform(1, 500);\r
+\r
+            for (int cn = 1; cn <= 4; ++cn)\r
+            {\r
+                test(NORM_L1, rows, cols, CV_8U, cn, Scalar::all(0), Scalar::all(10));\r
+                test(NORM_L1, rows, cols, CV_8S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_L1, rows, cols, CV_16U, cn, Scalar::all(0), Scalar::all(10));\r
+                test(NORM_L1, rows, cols, CV_16S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_L1, rows, cols, CV_32S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_L1, rows, cols, CV_32F, cn, Scalar::all(0), Scalar::all(1));\r
+\r
+                test(NORM_L2, rows, cols, CV_8U, cn, Scalar::all(0), Scalar::all(10));\r
+                test(NORM_L2, rows, cols, CV_8S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_L2, rows, cols, CV_16U, cn, Scalar::all(0), Scalar::all(10));\r
+                test(NORM_L2, rows, cols, CV_16S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_L2, rows, cols, CV_32S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_L2, rows, cols, CV_32F, cn, Scalar::all(0), Scalar::all(1));\r
+\r
+                test(NORM_INF, rows, cols, CV_8U, cn, Scalar::all(0), Scalar::all(10));\r
+                test(NORM_INF, rows, cols, CV_8S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_INF, rows, cols, CV_16U, cn, Scalar::all(0), Scalar::all(10));\r
+                test(NORM_INF, rows, cols, CV_16S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_INF, rows, cols, CV_32S, cn, Scalar::all(-10), Scalar::all(10));\r
+                test(NORM_INF, rows, cols, CV_32F, cn, Scalar::all(0), Scalar::all(1));\r
+            }\r
+        }\r
+        catch (const cv::Exception& e)\r
+        {\r
+            ts->printf(CvTS::CONSOLE, e.what());\r
+            if (!check_and_treat_gpu_exception(e, ts)) throw;\r
+            return;\r
+        }\r
+    }\r
+\r
+    void gen(Mat& mat, int rows, int cols, int type, Scalar low, Scalar high)\r
+    {\r
+        mat.create(rows, cols, type);\r
+        RNG rng(0);\r
+        rng.fill(mat, RNG::UNIFORM, low, high);\r
+    }\r
+\r
+    void test(int norm_type, int rows, int cols, int depth, int cn, Scalar low, Scalar high)\r
+    {\r
+        int type = CV_MAKE_TYPE(depth, cn);\r
+\r
+        Mat src;\r
+        gen(src, rows, cols, type, low, high);\r
+\r
+        double gold = norm(src, norm_type);\r
+        double mine = norm(GpuMat(src), norm_type);\r
+\r
+        if (abs(gold - mine) > 1e-3)\r
+        {\r
+            ts->printf(CvTS::CONSOLE, "failed test: gold=%f, mine=%f, norm_type=%d, rows=%d, "\r
+                       "cols=%d, depth=%d, cn=%d\n", gold, mine, norm_type, rows, cols, depth, cn);\r
+            ts->set_failed_test_info(CvTS::FAIL_INVALID_OUTPUT);\r
+        }\r
+    }\r
+};\r
+\r
 /////////////////////////////////////////////////////////////////////////////\r
 /////////////////// tests registration  /////////////////////////////////////\r
 /////////////////////////////////////////////////////////////////////////////\r
@@ -845,4 +916,4 @@ CV_GpuHistogramsTest CV_GpuHistograms_test;
 CV_GpuCornerHarrisTest CV_GpuCornerHarris_test;\r
 CV_GpuCornerMinEigenValTest CV_GpuCornerMinEigenVal_test;\r
 CV_GpuColumnSumTest CV_GpuColumnSum_test;\r
-\r
+CV_GpuNormTest CV_GpuNormTest_test;\r