Merge pull request #23807 from mshabunin:barcode-test

objdetect: updated barcode test
pull/23540/head
Alexander Smorkalov 2 years ago committed by GitHub
commit a9d547dfee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 169
      modules/objdetect/test/test_barcode.cpp

@ -4,116 +4,129 @@
#include "test_precomp.hpp" #include "test_precomp.hpp"
#include "opencv2/objdetect/barcode.hpp" #include "opencv2/objdetect/barcode.hpp"
#include <set>
using namespace std;
namespace opencv_test{namespace{ namespace opencv_test{namespace{
typedef std::vector<std::string> stringvec; typedef std::set<string> StringSet;
typedef std::map<std::string, std::string> datasetType;
inline stringvec explode(const std::string &s, const char &c) // Convert ';'-separated strings to a set
inline static StringSet toSet(const string &line)
{ {
std::string buff; StringSet res;
stringvec v; string::size_type it = 0, ti;
while (true)
for (auto n:s)
{ {
if (n != c) { buff += n; } ti = line.find(';', it);
else if (n == c && !buff.empty()) if (ti == string::npos)
{ {
v.push_back(buff); res.insert(string(line, it, line.size() - it));
buff = ""; break;
} }
res.insert(string(line, it, ti - it));
it = ti + 1;
} }
if (!buff.empty()) { v.push_back(buff); } return res;
return v;
} }
inline datasetType buildDataSet(std::string result_file_path) // Convert vector of strings to a set
inline static StringSet toSet(const vector<string> &lines)
{ {
std::ifstream result_file; StringSet res;
datasetType dataset; for (const string & line : lines)
result_file.open(result_file_path); res.insert(line);
std::string line; return res;
if (result_file.is_open())
{
while (std::getline(result_file, line))
{
stringvec result = explode(line, ',');
std::string filename = result[0];
if (dataset.find(filename) == dataset.end())
{
dataset[filename] = result[1];
}
}
} }
result_file.close(); // Get all keys of a map in a vector
return dataset; template<typename T, typename V>
inline static vector<T> getKeys(const map<T, V> &m)
{
vector<T> res;
for (const auto & it : m)
res.push_back(it.first);
return res;
} }
inline datasetType initValidation(std::string path) struct BarcodeResult
{ {
const std::string valid_path = findDataFile(path); string type;
return buildDataSet(valid_path); string data;
} };
//============================================================================== map<string, BarcodeResult> testResults {
{ "single/book.jpg", {"EAN_13", "9787115279460"} },
{ "single/bottle_1.jpg", {"EAN_13", "6922255451427"} },
{ "single/bottle_2.jpg", {"EAN_13", "6921168509256"} },
{ "multiple/4_barcodes.jpg", {"EAN_13;EAN_13;EAN_13;EAN_13", "9787564350840;9783319200064;9787118081473;9787122276124"} }
};
TEST(BARCODE_BarcodeDetector_single, regression) typedef testing::TestWithParam< string > BarcodeDetector_main;
{
const std::string root = "barcode/single/"; TEST_P(BarcodeDetector_main, interface)
datasetType validation = initValidation(root + "result.csv");
auto bardet = barcode::BarcodeDetector();
datasetType::iterator iterator = validation.begin();
while (iterator != validation.end())
{ {
std::string img_name = iterator->first; const string fname = GetParam();
std::string result = iterator->second; const string image_path = findDataFile(string("barcode/") + fname);
std::string image_path = findDataFile(root + img_name); const StringSet expected_lines = toSet(testResults[fname].data);
const StringSet expected_types = toSet(testResults[fname].type);
const size_t expected_count = expected_lines.size(); // assume codes are unique
// TODO: verify points location
Mat img = imread(image_path); Mat img = imread(image_path);
EXPECT_FALSE(img.empty()) << "Can't read image: " << image_path; ASSERT_FALSE(img.empty()) << "Can't read image: " << image_path;
std::vector<cv::Point2f> points;
std::vector<std::string> infos; barcode::BarcodeDetector det;
std::vector<std::string> formats; vector<Point2f> points;
bardet.detectAndDecodeWithType(img, infos, formats, points); vector<string> types;
EXPECT_FALSE(points.empty()) << "Nothing detected: " << image_path; vector<string> lines;
bool is_correct = false;
for (const auto &ans : infos) // common interface (single)
{
if (ans == result)
{ {
is_correct = true; bool res = det.detect(img, points);
break; ASSERT_TRUE(res);
} EXPECT_EQ(expected_count * 4, points.size());
} }
EXPECT_TRUE(is_correct) << "No results for " << img_name;
iterator++; {
string res = det.decode(img, points);
ASSERT_FALSE(res.empty());
EXPECT_EQ(1u, expected_lines.count(res));
} }
// common interface (multi)
{
bool res = det.detectMulti(img, points);
ASSERT_TRUE(res);
EXPECT_EQ(expected_count * 4, points.size());
} }
TEST(BARCODE_BarcodeDetector_detect_multi, detect_regression)
{ {
const std::string root = "barcode/multiple/"; bool res = det.decodeMulti(img, points, lines);
datasetType validation = initValidation(root + "result.csv"); ASSERT_TRUE(res);
auto bardet = barcode::BarcodeDetector(); EXPECT_EQ(expected_lines, toSet(lines));
datasetType::iterator iterator = validation.begin(); }
while (iterator != validation.end())
// specific interface
{ {
std::string img = iterator->first; bool res = det.decodeWithType(img, points, lines, types);
size_t expect_corners_size = std::stoi(iterator->second); ASSERT_TRUE(res);
std::string image_path = findDataFile(root + img); EXPECT_EQ(expected_types, toSet(types));
Mat src = imread(image_path); EXPECT_EQ(expected_lines, toSet(lines));
EXPECT_FALSE(src.empty()) << "Can't read image: " << image_path; }
std::vector<Point> corners; {
bardet.detectMulti(src, corners); bool res = det.detectAndDecodeWithType(img, lines, types, points);
EXPECT_EQ(corners.size(), expect_corners_size) << "Can't detect all barcodes: " << img; ASSERT_TRUE(res);
iterator++; EXPECT_EQ(expected_types, toSet(types));
EXPECT_EQ(expected_lines, toSet(lines));
} }
} }
TEST(BARCODE_BarcodeDetector_basic, not_found_barcode) INSTANTIATE_TEST_CASE_P(/**/, BarcodeDetector_main, testing::ValuesIn(getKeys(testResults)));
TEST(BarcodeDetector_base, invalid)
{ {
auto bardet = barcode::BarcodeDetector(); auto bardet = barcode::BarcodeDetector();
std::vector<Point> corners; std::vector<Point> corners;

Loading…
Cancel
Save