updated normalization routine in the matchTemplate to avoid division by zero on black...
authorAlexey Spizhevoy <no@email>
Tue, 11 Jan 2011 09:36:21 +0000 (09:36 +0000)
committerAlexey Spizhevoy <no@email>
Tue, 11 Jan 2011 09:36:21 +0000 (09:36 +0000)
modules/gpu/include/opencv2/gpu/gpu.hpp
modules/gpu/src/cuda/match_template.cu
tests/gpu/src/match_template.cpp

index b7e85a3..957299b 100644 (file)
@@ -1180,7 +1180,6 @@ namespace cv
             size_t getBlockHistogramSize() const;\r
 \r
             void setSVMDetector(const vector<float>& detector);\r
-            bool checkDetectorSize() const;\r
 \r
             static vector<float> getDefaultPeopleDetector();\r
             static vector<float> getPeopleDetector_48x96();\r
@@ -1212,7 +1211,9 @@ namespace cv
         protected:\r
             void computeBlockHistograms(const GpuMat& img);\r
             void computeGradient(const GpuMat& img, GpuMat& grad, GpuMat& qangle);\r
+\r
             double getWinSigma() const;\r
+            bool checkDetectorSize() const;\r
 \r
             static int numPartsWithin(int size, int part_size, int stride);\r
             static Size numPartsWithin(Size size, Size part_size, Size stride);\r
index 3ac98c8..1765724 100644 (file)
@@ -560,7 +560,7 @@ __global__ void matchTemplatePreparedKernel_CCOFF_NORMED_8U(
                 (image_sqsum.ptr(y + h)[x + w] - image_sqsum.ptr(y)[x + w]) -\r
                 (image_sqsum.ptr(y + h)[x] - image_sqsum.ptr(y)[x]));\r
         result.ptr(y)[x] = min(1.f, (ccorr - image_sum_ * templ_sum_scale) * \r
-                           rsqrtf(templ_sqsum_scale * (image_sqsum_ - weight * image_sum_ * image_sum_)));\r
+                           rsqrtf(templ_sqsum_scale * (image_sqsum_ - weight * image_sum_ * image_sum_ + 1.f)));\r
     }\r
 }\r
 \r
@@ -611,7 +611,7 @@ __global__ void matchTemplatePreparedKernel_CCOFF_NORMED_8UC2(
                 (image_sqsum_g.ptr(y + h)[x] - image_sqsum_g.ptr(y)[x]));\r
         float ccorr = result.ptr(y)[x];\r
         float rdenom = rsqrtf(templ_sqsum_scale * (image_sqsum_r_ - weight * image_sum_r_ * image_sum_r_ \r
-                                                   + image_sqsum_g_ - weight * image_sum_g_ * image_sum_g_));\r
+                                                   + image_sqsum_g_ - weight * image_sum_g_ * image_sum_g_ + 1.f));\r
         result.ptr(y)[x] = min(1.f, (ccorr - image_sum_r_ * templ_sum_scale_r\r
                                      - image_sum_g_ * templ_sum_scale_g) * rdenom);\r
     }\r
@@ -680,7 +680,7 @@ __global__ void matchTemplatePreparedKernel_CCOFF_NORMED_8UC3(
         float ccorr = result.ptr(y)[x];\r
         float rdenom = rsqrtf(templ_sqsum_scale * (image_sqsum_r_ - weight * image_sum_r_ * image_sum_r_ \r
                                                    + image_sqsum_g_ - weight * image_sum_g_ * image_sum_g_\r
-                                                   + image_sqsum_b_ - weight * image_sum_b_ * image_sum_b_));\r
+                                                   + image_sqsum_b_ - weight * image_sum_b_ * image_sum_b_ + 1.f));\r
         result.ptr(y)[x] = min(1.f, (ccorr - image_sum_r_ * templ_sum_scale_r\r
                                      - image_sum_g_ * templ_sum_scale_g\r
                                      - image_sum_b_ * templ_sum_scale_b) * rdenom);\r
@@ -763,7 +763,7 @@ __global__ void matchTemplatePreparedKernel_CCOFF_NORMED_8UC4(
         float rdenom = rsqrtf(templ_sqsum_scale * (image_sqsum_r_ - weight * image_sum_r_ * image_sum_r_\r
                                                    + image_sqsum_g_ - weight * image_sum_g_ * image_sum_g_\r
                                                    + image_sqsum_b_ - weight * image_sum_b_ * image_sum_b_\r
-                                                   + image_sqsum_a_ - weight * image_sum_a_ * image_sum_a_));\r
+                                                   + image_sqsum_a_ - weight * image_sum_a_ * image_sum_a_ + 1.f));\r
         result.ptr(y)[x] = min(1.f, (ccorr - image_sum_r_ * templ_sum_scale_r\r
                                      - image_sum_g_ * templ_sum_scale_g\r
                                      - image_sum_b_ * templ_sum_scale_b\r
@@ -822,7 +822,7 @@ __global__ void normalizeKernel_8U(
         float image_sqsum_ = (float)(\r
                 (image_sqsum.ptr(y + h)[(x + w) * cn] - image_sqsum.ptr(y)[(x + w) * cn]) -\r
                 (image_sqsum.ptr(y + h)[x * cn] - image_sqsum.ptr(y)[x * cn]));\r
-        result.ptr(y)[x] = min(1.f, result.ptr(y)[x] * rsqrtf(image_sqsum_ * templ_sqsum));\r
+        result.ptr(y)[x] = min(1.f, result.ptr(y)[x] * rsqrtf((image_sqsum_ + 1.f) * templ_sqsum));\r
     }\r
 }\r
 \r
index e4ccd37..f29d5d7 100644 (file)
@@ -124,7 +124,7 @@ struct CV_GpuMatchTemplateTest: CvTest
                     F(t = clock();)\r
                     gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCORR_NORMED);\r
                     F(cout << "gpu_block: " << clock() - t << endl;)\r
-                    if (!check(dst_gold, Mat(dst), h * w * 1e-5f)) return;\r
+                    if (!check(dst_gold, Mat(dst), h * w * 1e-4f)) return;\r
 \r
                     gen(image, n, m, CV_8U, cn);\r
                     gen(templ, h, w, CV_8U, cn);\r
@@ -146,7 +146,7 @@ struct CV_GpuMatchTemplateTest: CvTest
                     F(t = clock();)\r
                     gpu::matchTemplate(gpu::GpuMat(image), gpu::GpuMat(templ), dst, CV_TM_CCOEFF_NORMED);\r
                     F(cout << "gpu_block: " << clock() - t << endl;)\r
-                    if (!check(dst_gold, Mat(dst), h * w * 1e-6f)) return;\r
+                    if (!check(dst_gold, Mat(dst), h * w * 1e-4f)) return;\r
 \r
                     gen(image, n, m, CV_32F, cn);\r
                     gen(templ, h, w, CV_32F, cn);\r
@@ -207,66 +207,70 @@ struct CV_GpuMatchTemplateTest: CvTest
             return false;\r
         }\r
 \r
-        //// Debug check\r
-        //for (int i = 0; i < a.rows; ++i)\r
-        //{\r
-        //    for (int j = 0; j < a.cols; ++j)\r
-        //    {\r
-        //        float v1 = a.at<float>(i, j);\r
-        //        float v2 = b.at<float>(i, j);\r
-        //        if (fabs(v1 - v2) > max_err)\r
-        //        {\r
-        //            ts->printf(CvTS::CONSOLE, "%d %d %f %f\n", i, j, v1, v2);\r
-        //            cin.get();\r
-        //        }\r
-        //    }\r
-        //}\r
-\r
         return true;\r
     }\r
+} match_template_test;\r
 \r
-    //void match_template_naive_SQDIFF(const Mat& a, const Mat& b, Mat& c)\r
-    //{\r
-    //    c.create(a.rows - b.rows + 1, a.cols - b.cols + 1, CV_32F);         \r
-    //    for (int i = 0; i < c.rows; ++i)\r
-    //    {\r
-    //        for (int j = 0; j < c.cols; ++j)\r
-    //        {\r
-    //            float delta;\r
-    //            float sum = 0.f;\r
-    //            for (int y = 0; y < b.rows; ++y)\r
-    //            {\r
-    //                const unsigned char* arow = a.ptr(i + y);\r
-    //                const unsigned char* brow = b.ptr(y);\r
-    //                for (int x = 0; x < b.cols; ++x)\r
-    //                {\r
-    //                    delta = (float)(arow[j + x] - brow[x]);\r
-    //                    sum += delta * delta;\r
-    //                }\r
-    //            }\r
-    //            c.at<float>(i, j) = sum;\r
-    //        }\r
-    //    }\r
-    //}\r
+struct CV_GpuMatchTemplateFindPatternInBlackTest: CvTest \r
+{\r
+    CV_GpuMatchTemplateFindPatternInBlackTest()\r
+            : CvTest("GPU-MatchTemplateFindPatternInBlackTest", "matchTemplate") {}\r
 \r
-    //void match_template_naive_CCORR(const Mat& a, const Mat& b, Mat& c)\r
-    //{\r
-    //    c.create(a.rows - b.rows + 1, a.cols - b.cols + 1, CV_32F);         \r
-    //    for (int i = 0; i < c.rows; ++i)\r
-    //    {\r
-    //        for (int j = 0; j < c.cols; ++j)\r
-    //        {\r
-    //            float sum = 0.f;\r
-    //            for (int y = 0; y < b.rows; ++y)\r
-    //            {\r
-    //                const float* arow = a.ptr<float>(i + y);\r
-    //                const float* brow = b.ptr<float>(y);\r
-    //                for (int x = 0; x < b.cols; ++x)\r
-    //                    sum += arow[j + x] * brow[x];\r
-    //            }\r
-    //            c.at<float>(i, j) = sum;\r
-    //        }\r
-    //    }\r
-    //}\r
-} match_template_test;\r
+    void run(int)\r
+    {\r
+        try\r
+        {\r
+            Mat image = imread(std::string(ts->get_data_path()) + "matchtemplate/black.jpg");\r
+            if (image.empty())\r
+            {\r
+                ts->printf(CvTS::CONSOLE, "can't open file '%s'", (std::string(ts->get_data_path()) \r
+                                                                   + "matchtemplate/black.jpg").c_str());\r
+                ts->set_failed_test_info(CvTS::FAIL_INVALID_TEST_DATA);\r
+                return;\r
+            }\r
+\r
+            Mat pattern = imread(std::string(ts->get_data_path()) + "matchtemplate/cat.jpg");\r
+            if (pattern.empty())\r
+            {\r
+                ts->printf(CvTS::CONSOLE, "can't open file '%s'", (std::string(ts->get_data_path()) \r
+                                                                   + "matchtemplate/cat.jpg").c_str());\r
+                ts->set_failed_test_info(CvTS::FAIL_INVALID_TEST_DATA);\r
+                return;\r
+            }\r
+\r
+            gpu::GpuMat d_image(image);\r
+            gpu::GpuMat d_pattern(pattern);\r
+            gpu::GpuMat d_result;\r
 \r
+            double maxValue;\r
+            Point maxLoc;\r
+            Point maxLocGold(284, 12);\r
+\r
+            gpu::matchTemplate(d_image, d_pattern, d_result, CV_TM_CCOEFF_NORMED);\r
+            gpu::minMaxLoc(d_result, NULL, &maxValue, NULL, &maxLoc );\r
+            if (maxLoc != maxLocGold)\r
+            {\r
+                ts->printf(CvTS::CONSOLE, "bad match (CV_TM_CCOEFF_NORMED): %d %d, must be at: %d %d", \r
+                           maxLoc.x, maxLoc.y, maxLocGold.x, maxLocGold.y);\r
+                ts->set_failed_test_info(CvTS::FAIL_INVALID_OUTPUT);\r
+                return;\r
+            }\r
+\r
+            gpu::matchTemplate(d_image, d_pattern, d_result, CV_TM_CCORR_NORMED);\r
+            gpu::minMaxLoc(d_result, NULL, &maxValue, NULL, &maxLoc );\r
+            if (maxLoc != maxLocGold)\r
+            {\r
+                ts->printf(CvTS::CONSOLE, "bad match (CV_TM_CCORR_NORMED): %d %d, must be at: %d %d", \r
+                           maxLoc.x, maxLoc.y, maxLocGold.x, maxLocGold.y);\r
+                ts->set_failed_test_info(CvTS::FAIL_INVALID_OUTPUT);\r
+                return;\r
+            }\r
+        }\r
+        catch (const 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
+} match_templet_find_bordered_pattern_test;
\ No newline at end of file