diff --git a/modules/objdetect/include/opencv2/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect.hpp index ed0d6f76ac..4652b0da6f 100644 --- a/modules/objdetect/include/opencv2/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect.hpp @@ -702,6 +702,19 @@ public: }; //! @} +//! @addtogroup objdetect_colornames +//! @{ +class CV_EXPORTS_W ColorNamesFeatures +{ +public: + typedef Vec PixType; + typedef Vec FeatureType; + virtual ~ColorNamesFeatures() {} + CV_WRAP virtual void compute(InputArray image_patch, OutputArray feature_vector) = 0; + static Ptr create(const std::string & table_file); +}; +//! @} + //! @addtogroup objdetect_qrcode //! @{ diff --git a/modules/objdetect/src/color_names.cpp b/modules/objdetect/src/color_names.cpp new file mode 100644 index 0000000000..0e0d19982a --- /dev/null +++ b/modules/objdetect/src/color_names.cpp @@ -0,0 +1,75 @@ +// 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 "precomp.hpp" + +namespace cv { + +class ColorNamesImpl : public ColorNamesFeatures +{ +public: + ColorNamesImpl(); + bool read(const std::string & table_file); + void compute(InputArray image_patch, OutputArray feature_vector) CV_OVERRIDE; +private: + Mat table; + const int LEN = 32768; +}; + +ColorNamesImpl::ColorNamesImpl() +{ +} + +bool ColorNamesImpl::read(const std::string & table_file) +{ + FileStorage fs(table_file, FileStorage::READ); + if (!fs.isOpened()) + return false; + FileNode node = fs["ColorNames"]; + if (node.empty()) + return false; + table = node.mat(); + if ((table.size() != Size(10, LEN)) || (table.type() != CV_32FC1)) + { + table.release(); + return false; + } + return true; +} + +void ColorNamesImpl::compute(InputArray image_patch, OutputArray feature_vector) +{ + CV_CheckType(image_patch.type(), image_patch.type() == CV_8UC3, "BGR image expected"); + Mat image_patch_rgb555; + cvtColor(image_patch, image_patch_rgb555, COLOR_RGB2BGR555); + // TODO: why RGB555 is 8UC2? + Mat patch(image_patch.size(), CV_16UC1, image_patch_rgb555.data); + CV_CheckType(patch.type(), patch.type() == CV_16UC1, "Internal error"); + + feature_vector.create(image_patch.size(), CV_32FC(10)); + Mat feature_mat = feature_vector.getMat(); + + Mat ftable(Size(1, LEN), CV_32FC(10), table.data); + for (int i = 0; i < patch.rows; i++) + { + for (int j = 0; j < patch.cols; j++) + { + typedef uint16_t Pix; + typedef Vec Feat; + const Pix pix = patch.at(i, j); + const Feat val = ftable.at(pix); + feature_mat.at(i, j) = val; + } + } +} + +Ptr ColorNamesFeatures::create(const std::string & table_file) +{ + cv::Ptr res = std::make_shared(); + if (!res->read(table_file)) + return NULL; + return res; +} + +} // cv:: diff --git a/modules/objdetect/test/test_color_names.cpp b/modules/objdetect/test/test_color_names.cpp new file mode 100644 index 0000000000..ff4e6e7363 --- /dev/null +++ b/modules/objdetect/test/test_color_names.cpp @@ -0,0 +1,28 @@ +// 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" + +using namespace std; + +namespace opencv_test{namespace{ + +TEST(ColorNames, test) +{ + const std::string fname = findDataFile("objdetect/color_names.yaml.gz"); + ASSERT_FALSE(fname.empty()); + Ptr cnames = ColorNamesFeatures::create(fname); + ASSERT_TRUE(cnames); + const Size SZ(100, 100); + Mat img = cvtest::randomMat(theRNG(), SZ, CV_8UC3, 0, 255, false); + img.at(99, 99) = {255, 255, 255}; + Mat features; + cnames->compute(img, features); + ASSERT_EQ(features.type(), CV_32FC(10)); + ASSERT_EQ(features.size(), SZ); + const float last_item = features.at(99, 99)[0]; + ASSERT_NEAR(last_item, 0.0087778, 0.00001); +} + +}} // opencv_test::::