Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated tests to detect BarcodeFormat & Barcode data #219

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions tests/src/QZXingTests/DecodeTestExecutor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include "DecodeTestExecutor.h"
#include <QDebug>
#include <QDir>
#include <QFileInfoList>

int DecodeTestExecutor::fileCount = 0;

DecodeTestExecutor::DecodeTestExecutor(QString dirPath, QObject* parent) : QObject(parent){
m_datasetPath = dirPath;

initializeDecoderCorrelation();
decoder.setTryHarder(true);

connect(&decoder, SIGNAL(tagFoundAdvanced(const QString&, const QString&, const QString&)),
this, SLOT(tagFound(const QString&, const QString&, const QString&)));

connect(&decoder, SIGNAL(decodingFinished(bool)),
this, SLOT(decodingFinished(bool)));
}

void DecodeTestExecutor::executeTest() {
QFileInfo dirInfo(m_datasetPath);
if (!dirInfo.isDir()) {
qDebug() << m_datasetPath << "Doesn't seem to be valid directory";
return;
}

QDir folder(m_datasetPath);

QFileInfoList l = folder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
qDebug() << "Fetching files to decode... ";
for (int i = 0; i < l.count(); i++) {
QFileInfo info = l.at(i);
qDebug() << "Reading folder: " << info.absoluteFilePath();
fetchFilesToDecode(info.absoluteFilePath());
}
qDebug() << "started decoding "<< fileCount<<" files.. ";
startDecoding();
}

void DecodeTestExecutor::fetchFilesToDecode(QString path) {
QDir curPath(path);
curPath.setFilter(QDir::NoDotAndDotDot);
QStringList images =
curPath.entryList(QStringList() << "*.png", QDir::Files);

foreach (QString file, images) {
fileCount++;
QString imgPath = curPath.path() + "/" + file;
allFiles.enqueue(imgPath);
}
}

void DecodeTestExecutor::startDecoding() {
//dequeue a file and start decoding.
if (!allFiles.isEmpty()) {
QString file = allFiles.dequeue();
QString exp = file.left(file.lastIndexOf('.')).append(".txt");
QString expFormat = file.left(file.lastIndexOf('.')).append(".fmt");
QFile expectedDataFile(exp);
QFile expectedFormatFile(expFormat);
m_expectedFormat = QZXing::DecoderFormat::DecoderFormat_None;
if (expectedDataFile.open(QFile::ReadOnly)) {
m_curentExpectedData = expectedDataFile.readAll();
}
if (expectedFormatFile.open(QFile::ReadOnly)) {
m_expectedFormat =
m_decoderCorrelationMap[expectedFormatFile.readAll()];
}
m_currentFile = file;
decoder.decodeImageFromFile(file);
} else {
printResults();
}
}

void DecodeTestExecutor::printResults() {
qDebug() << "Decoded Results";

qDebug() << "Total Files : " << DecodeTestExecutor::fileCount;
qDebug() << "Decode Success count : " << m_successResults.count();
qDebug() << "Decode Failure count : " << m_failedResults.count();
qDebug() << "-----------------------------";
}


void DecodeTestExecutor::initializeDecoderCorrelation()
{
m_decoderCorrelationMap["AZTEC"] = QZXing::DecoderFormat_Aztec;
m_decoderCorrelationMap["CODABAR"] = QZXing::DecoderFormat_CODABAR;
m_decoderCorrelationMap["CODE_39"] = QZXing::DecoderFormat_CODE_39;
m_decoderCorrelationMap["CODE_93"] = QZXing::DecoderFormat_CODE_93;
m_decoderCorrelationMap["CODE_128"] = QZXing::DecoderFormat_CODE_128;
m_decoderCorrelationMap["DATA_MATRIX"] = QZXing::DecoderFormat_DATA_MATRIX;
m_decoderCorrelationMap["EAN_8"] = QZXing::DecoderFormat_EAN_8;
m_decoderCorrelationMap["EAN_13"] = QZXing::DecoderFormat_EAN_13;
m_decoderCorrelationMap["ITF"] = QZXing::DecoderFormat_ITF;
m_decoderCorrelationMap["PDF_417"] = QZXing::DecoderFormat_PDF_417;
m_decoderCorrelationMap["QR_CODE"] = QZXing::DecoderFormat_QR_CODE;
m_decoderCorrelationMap["RSS_14"] = QZXing::DecoderFormat_RSS_14;
m_decoderCorrelationMap["RSS_EXPANDED"] = QZXing::DecoderFormat_RSS_EXPANDED;
m_decoderCorrelationMap["UPC_A"] = QZXing::DecoderFormat_UPC_A;
m_decoderCorrelationMap["UPC_E"] = QZXing::DecoderFormat_UPC_E;
m_decoderCorrelationMap["UPC_EAN_EXTENSION"] = QZXing::DecoderFormat_UPC_EAN_EXTENSION;
m_decoderCorrelationMap["CODE_128_GS1"] = QZXing::DecoderFormat_CODE_128_GS1;
}

void DecodeTestExecutor::tagFound(const QString& tag, const QString& format,
const QString& charSet) {
Q_UNUSED(charSet);

if (m_curentExpectedData == tag || m_expectedFormat == m_decoderCorrelationMap[format]) {
qDebug() << m_currentFile << " Format : "<< format << "Decode Success";
m_successResults.append(TestResult(m_currentFile, format, true));
}
else{
m_failedResults.append(TestResult(m_currentFile,QString(""),false));
}
}

void DecodeTestExecutor::decodingFinished(bool result) {
if (!result) {
qDebug() << m_currentFile << " Format : UNKNOWN" << "Decode Failure";
m_failedResults.append(TestResult(m_currentFile,QString(""),false));
}

//After decoding a file has finished, fetch the next available file in the queue to decode.
startDecoding();
}
51 changes: 51 additions & 0 deletions tests/src/QZXingTests/DecodeTestExecutor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef DECODETESTEXECUTOR_H
#define DECODETESTEXECUTOR_H

#include <QDebug>
#include <QList>
#include <QObject>
#include <QQueue>
#include "QZXing.h"

struct TestResult {
TestResult(QString file, QString fmt, bool res) {
fileName = file;
format = fmt;
result = res;
}
QString fileName;
QString format;
bool result;
};

class DecodeTestExecutor : public QObject {
Q_OBJECT

public:
explicit DecodeTestExecutor(QString dirPath, QObject* parent = nullptr);
void executeTest();

public slots:
void tagFound(const QString& tag, const QString& format, const QString& charSet);
void decodingFinished(bool);

private:
void fetchFilesToDecode(QString path);
void startDecoding();
void printResults();
void initializeDecoderCorrelation();

QString m_datasetPath = "";
QZXing decoder;
QString m_curentExpectedData, m_currentFile;
QZXing::DecoderFormat m_expectedFormat{
QZXing::DecoderFormat::DecoderFormat_None};
QMap<QString, QZXing::DecoderFormat> m_decoderCorrelationMap;
QQueue<QString> allFiles;
QList<TestResult> m_successResults;
QList<TestResult> m_failedResults;
static int fileCount;
};
Q_DECLARE_METATYPE(QZXing::DecoderFormat)

#endif // DECODETESTEXECUTOR_H
133 changes: 63 additions & 70 deletions tests/src/QZXingTests/DecodeValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ DecodeValidator::DecodeValidator() : decoder(), decoderCorrelationMap(), testRes
{
initializeDecoderCorrelation();
decoder.setTryHarder(true);
connect(&decoder, SIGNAL(tagFoundAdvanced(const QString&, const QString&, const QString&)),
this, SLOT(tagFound(const QString&, const QString&, const QString&)));

connect(&decoder, SIGNAL(decodingFinished(bool)),
this, SLOT(decodingFinished(bool)));

}

void DecodeValidator::initializeDecoderCorrelation()
Expand Down Expand Up @@ -51,23 +57,23 @@ QString DecodeValidator::getDataFromTextFile(const QString &filePath)

std::shared_ptr<ValidationStats> DecodeValidator::testDecodeWithExpectedOutput(QZXing::DecoderFormat enabledDecoder, const QImage &imageToDecode, const QString &expectedOutput)
{
std::shared_ptr<ValidationStats> stats_ = std::make_shared<ValidationStats>();
std::shared_ptr<ValidationStats> stats = std::make_shared<ValidationStats>();

decoder.setDecoder(enabledDecoder);
// decoder.setDecoder(enabledDecoder);

QString result = decoder.decodeImage(imageToDecode);
result.replace("\r\n","\n");

stats_->setElaspedTime(decoder.getProcessTimeOfLastDecoding());
stats_->setOperationSuccess(result != "");
stats_->setResultMatch(expectedOutput != "" && result == expectedOutput);
stats->setElaspedTime(decoder.getProcessTimeOfLastDecoding());
stats->setOperationSuccess(result != "");
stats->setResultMatch(expectedOutput != "" && result == expectedOutput);

if(!stats_->getResultMatch() && stats_->getOperationSuccess()) {
if(!stats->getResultMatch() && stats->getOperationSuccess()) {
qDebug() << "Expected: " << expectedOutput;
qDebug() << "Decoded: " << result;
}

return stats_;
return stats;
}

QZXing::DecoderFormat DecodeValidator::getDecoderForFolder(const QString &folderName)
Expand All @@ -87,79 +93,50 @@ QZXing::DecoderFormat DecodeValidator::getDecoderForFolder(const QString &folder

void DecodeValidator::printResults()
{
std::map<QZXing::DecoderFormat, std::vector<std::shared_ptr<ValidationStats>>>::iterator it;

qDebug() << LOG_SECTOR_TITLE ("# Test Results");

size_t finalSuccessful = 0;
size_t finalFailed = 0;
size_t finalInconsistent = 0;

for(it=testResults.begin(); it != testResults.end(); it++) {
QString decoderStr = QZXing::decoderFormatToString(it->first);
std::vector<std::shared_ptr<ValidationStats>> &resPerDecoder = it->second;

size_t successfulTestCount = 0;
QVector<QString> failedResultLogs;
QVector<QString> inconsistentResultLogs;

for(size_t i=0; i<resPerDecoder.size(); i++) {
if(resPerDecoder[i]->getOperationSuccess())
successfulTestCount++;
else
failedResultLogs.push_back(resPerDecoder[i]->getImagePath());

if(resPerDecoder[i]->getOperationSuccess() && !resPerDecoder[i]->getResultMatch())
inconsistentResultLogs.push_back(resPerDecoder[i]->getImagePath());
}

qDebug() << "Decoder: [" << decoderStr << "]"
<< ", successful: [" << successfulTestCount << "]"
<< ", failed: [" << failedResultLogs.size() << "]"
<< ", inconsistencies: [" << inconsistentResultLogs.size() << "]";

finalSuccessful += successfulTestCount;
finalFailed += failedResultLogs.size();
finalInconsistent += inconsistentResultLogs.size();

if(failedResultLogs.size())
qDebug() << " failed image files:";

for(int i=0; i<failedResultLogs.size(); i++)
qDebug() << '\t' << failedResultLogs[i];

if(inconsistentResultLogs.size())
qDebug() << " inconsistent image files:";

for(int i=0; i<inconsistentResultLogs.size(); i++)
qDebug() << '\t' << inconsistentResultLogs[i];
}

qDebug() << LOG_SECTOR_TITLE ("# Total Results");
qDebug() << "Total: [" << (finalSuccessful + finalFailed + finalInconsistent) << "]"
<< ", successful: [" << finalSuccessful << "]"
<< ", failed: [" << finalFailed << "]"
<< ", inconsistencies: [" << finalInconsistent << "]";
std::map<QString, std::shared_ptr<ValidationStats>>::iterator it;
for(it=results.begin(); it != results.end(); it++) {
std::shared_ptr<ValidationStats> &results = it->second;

QFileInfo file(it->first);
qDebug().noquote()<< file.dir().dirName() << "/" << file.fileName() << " | "
<< (results->getOperationSuccess() ? "Decode Success" : "Decode Failed") << " | "
<< results->getDecodedFormat();

if(results->getOperationSuccess())
finalSuccessful++;
else
finalFailed++;

if(!results->getResultMatch())
finalInconsistent++;
}
qDebug() << "Total: [" << (results.size()) << "]"
<< ", successful: [" << finalSuccessful << "]"
<< ", failed: [" << finalFailed << "]"
<< ", inconsistencies: [" << finalInconsistent << "]";
}

std::shared_ptr<ValidationStats> DecodeValidator::testDecodeWithExpectedOutput(QZXing::DecoderFormat enabledDecoder, const QString &imageToDecodePath, const QString &expectedOutputFilePath)
{
QImage tmpImage = QImage(imageToDecodePath);
QString expectedOutput = getDataFromTextFile(expectedOutputFilePath);
QString fmtFile = expectedOutputFilePath.left(expectedOutputFilePath.lastIndexOf('.')).append(".fmt");
QString expectedFormat = getDataFromTextFile(fmtFile).trimmed();
current_stats = std::make_shared<ValidationStats>();
current_stats->setImagePath(imageToDecodePath);
current_stats->setExpectedOutput(expectedOutput);
current_stats->setExpectedFormat(expectedFormat);

QString result = decoder.decodeImage(tmpImage);
result.replace("\r\n","\n");

std::shared_ptr<ValidationStats> stats_ = testDecodeWithExpectedOutput(enabledDecoder, tmpImage, expectedOutput);

stats_->setImagePath(imageToDecodePath);
stats_->setExpectedOutput(expectedOutput);

qDebug() << "Operation success: " << stats_->getOperationSuccess()
<< "\t, Result Match: " << stats_->getResultMatch()
<< "\t, Path: " << stats_->getImagePath();

if(!stats_->getOperationSuccess() && stats_->getResultMatch())
qDebug() << "\t[Warning]...";
current_stats->setElaspedTime(decoder.getProcessTimeOfLastDecoding());

return stats_;
return current_stats;
}

void DecodeValidator::decodeAllImagesInForderWithValidator(QZXing::DecoderFormat enabledDecoder, const QString &folderPath)
Expand All @@ -169,11 +146,12 @@ void DecodeValidator::decodeAllImagesInForderWithValidator(QZXing::DecoderFormat
while (dirIt.hasNext()) {
dirIt.next();
QFileInfo fileInfo(dirIt.filePath());
if (fileInfo.isFile() && fileInfo.suffix() != "txt") {
if (fileInfo.isFile() && fileInfo.suffix() != "txt" && fileInfo.suffix() != "fmt") {
QString imagePath = dirIt.filePath();
qDebug()<<"Decoding : "<<imagePath;
QString expectedOutputTextFile = fileInfo.absoluteDir().absolutePath() + "/" + fileInfo.baseName() + ".txt";

testResults[enabledDecoder].push_back(testDecodeWithExpectedOutput(enabledDecoder, imagePath, expectedOutputTextFile));
testDecodeWithExpectedOutput(enabledDecoder, imagePath, expectedOutputTextFile);
}
}
}
Expand All @@ -200,4 +178,19 @@ void DecodeValidator::executeTests(const QString &folderPath)
printResults();
}

void DecodeValidator::tagFound(const QString &tag, const QString &format, const QString &charSet)
{
current_stats->setDecodedFormat(format);
current_stats->setResultMatch(tag == current_stats->getExpectedOutput() &&
format == current_stats->getExpectedFormat() );

}

void DecodeValidator::decodingFinished(bool result)
{
current_stats->setOperationSuccess(result);
results[current_stats->getImagePath()] = current_stats;
}



Loading