mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
WIP.
This commit is contained in:
parent
72f198fe00
commit
15989e3a89
8 changed files with 87 additions and 10 deletions
|
@ -12,9 +12,17 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
ImageComparer::ImageComparer() {
|
||||
_ssimResults = new SSIMResults();
|
||||
}
|
||||
|
||||
ImageComparer::~ImageComparer() {
|
||||
delete _ssimResults;
|
||||
}
|
||||
|
||||
// Computes SSIM - see https://en.wikipedia.org/wiki/Structural_similarity
|
||||
// The value is computed for the luminance component and the average value is returned
|
||||
double ImageComparer::compareImages(QImage resultImage, QImage expectedImage) const {
|
||||
double ImageComparer::compareImages(const QImage& resultImage, const QImage& expectedImage) const {
|
||||
const int L = 255; // (2^number of bits per pixel) - 1
|
||||
|
||||
const double K1 { 0.01 };
|
||||
|
@ -96,6 +104,7 @@ double ImageComparer::compareImages(QImage resultImage, QImage expectedImage) co
|
|||
double numerator = (2.0 * mP * mQ + c1) * (2.0 * sigPQ + c2);
|
||||
double denominator = (mP * mP + mQ * mQ + c1) * (sigsqP + sigsqQ + c2);
|
||||
|
||||
_ssimResults->results.push_back(numerator / denominator);
|
||||
ssim += numerator / denominator;
|
||||
++windowCounter;
|
||||
|
||||
|
@ -106,5 +115,12 @@ double ImageComparer::compareImages(QImage resultImage, QImage expectedImage) co
|
|||
y = 0;
|
||||
}
|
||||
|
||||
_ssimResults->width = (int)(expectedImage.width() / WIN_SIZE);
|
||||
_ssimResults->height = (int)(expectedImage.height() / WIN_SIZE);
|
||||
|
||||
return ssim / windowCounter;
|
||||
};
|
||||
};
|
||||
|
||||
SSIMResults* ImageComparer::getSSIMResults() {
|
||||
return _ssimResults;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,21 @@
|
|||
#ifndef hifi_ImageComparer_h
|
||||
#define hifi_ImageComparer_h
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QImage>
|
||||
|
||||
class ImageComparer {
|
||||
public:
|
||||
double compareImages(QImage resultImage, QImage expectedImage) const;
|
||||
ImageComparer();
|
||||
~ImageComparer();
|
||||
|
||||
double compareImages(const QImage& resultImage, const QImage& expectedImage) const;
|
||||
SSIMResults* getSSIMResults();
|
||||
|
||||
private:
|
||||
SSIMResults* _ssimResults;
|
||||
};
|
||||
|
||||
#endif // hifi_ImageComparer_h
|
||||
|
|
|
@ -99,3 +99,35 @@ void MismatchWindow::on_abortTestsButton_clicked() {
|
|||
QPixmap MismatchWindow::getComparisonImage() {
|
||||
return _diffPixmap;
|
||||
}
|
||||
|
||||
QPixmap MismatchWindow::getSSIMResultsImage(SSIMResults* ssimResults) {
|
||||
// This is an optimization, as QImage.setPixel() is embarrassingly slow
|
||||
const int ELEMENT_SIZE { 8 };
|
||||
unsigned char* buffer = new unsigned char[(ssimResults->height * ELEMENT_SIZE) * (ssimResults->width * ELEMENT_SIZE ) * 3];
|
||||
|
||||
|
||||
// loop over each SSIM result (a double in [-1.0 .. 1.0]
|
||||
int i { 0 };
|
||||
for (int y = 0; y < ssimResults->height; ++y) {
|
||||
for (int x = 0; x < ssimResults->width; ++x) {
|
||||
////QRgb pixelP = expectedImage.pixel(QPoint(x, y));
|
||||
|
||||
////// Convert to luminance
|
||||
////double p = R_Y * qRed(pixelP) + G_Y * qGreen(pixelP) + B_Y * qBlue(pixelP);
|
||||
|
||||
////// The intensity value is modified to increase the brightness of the displayed image
|
||||
////double absoluteDifference = fabs(p - q) / 255.0;
|
||||
////double modifiedDifference = sqrt(absoluteDifference);
|
||||
|
||||
////int difference = (int)(modifiedDifference * 255.0);
|
||||
|
||||
////buffer[3 * (x + y * expectedImage.width()) + 0] = difference;
|
||||
////buffer[3 * (x + y * expectedImage.width()) + 1] = difference;
|
||||
////buffer[3 * (x + y * expectedImage.width()) + 2] = difference;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return QPixmap();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ public:
|
|||
UserResponse getUserResponse() { return _userResponse; }
|
||||
|
||||
QPixmap computeDiffPixmap(QImage expectedImage, QImage resultImage);
|
||||
|
||||
QPixmap getComparisonImage();
|
||||
QPixmap getSSIMResultsImage(SSIMResults* ssimResults);
|
||||
|
||||
private slots:
|
||||
void on_passTestButton_clicked();
|
||||
|
|
|
@ -40,7 +40,7 @@ Nitpick::Nitpick(QWidget* parent) : QMainWindow(parent) {
|
|||
|
||||
_ui.plainTextEdit->setReadOnly(true);
|
||||
|
||||
setWindowTitle("Nitpick - v3.0.0");
|
||||
setWindowTitle("Nitpick - v3.0.1");
|
||||
|
||||
clientProfiles << "VR-High" << "Desktop-High" << "Desktop-Low" << "Mobile-Touch" << "VR-Standalone";
|
||||
_ui.clientProfileComboBox->insertItems(0, clientProfiles);
|
||||
|
|
|
@ -100,12 +100,14 @@ int Test::compareImageLists() {
|
|||
};
|
||||
|
||||
_mismatchWindow.setTestResult(testResult);
|
||||
|
||||
QPixmap ssimResultsPixMap = _mismatchWindow.getSSIMResultsImage(_imageComparer.getSSIMResults());
|
||||
|
||||
if (similarityIndex < THRESHOLD) {
|
||||
++numberOfFailures;
|
||||
|
||||
if (!isInteractiveMode) {
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), true);
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), ssimResultsPixMap, true);
|
||||
} else {
|
||||
_mismatchWindow.exec();
|
||||
|
||||
|
@ -113,7 +115,7 @@ int Test::compareImageLists() {
|
|||
case USER_RESPONSE_PASS:
|
||||
break;
|
||||
case USE_RESPONSE_FAIL:
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), true);
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), ssimResultsPixMap, true);
|
||||
break;
|
||||
case USER_RESPONSE_ABORT:
|
||||
keepOn = false;
|
||||
|
@ -124,7 +126,7 @@ int Test::compareImageLists() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), false);
|
||||
appendTestResultsToFile(testResult, _mismatchWindow.getComparisonImage(), ssimResultsPixMap, false);
|
||||
}
|
||||
|
||||
_progressBar->setValue(i);
|
||||
|
@ -156,7 +158,7 @@ int Test::checkTextResults() {
|
|||
return testsFailed.length();
|
||||
}
|
||||
|
||||
void Test::appendTestResultsToFile(TestResult testResult, QPixmap comparisonImage, bool hasFailed) {
|
||||
void Test::appendTestResultsToFile(const TestResult& testResult, const QPixmap& comparisonImage, const QPixmap& ssimResultsImage, bool hasFailed) {
|
||||
// Critical error if Test Results folder does not exist
|
||||
if (!QDir().exists(_testResultsFolderPath)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Folder " + _testResultsFolderPath + " not found");
|
||||
|
@ -216,6 +218,14 @@ void Test::appendTestResultsToFile(TestResult testResult, QPixmap comparisonImag
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
// Create the SSIM results image
|
||||
sourceFile = testResult._pathname + testResult._actualImageFilename;
|
||||
destinationFile = resultFolderPath + "/" + "SSIM results.png";
|
||||
if (!QFile::copy(sourceFile, destinationFile)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to copy " + sourceFile + " to " + destinationFile);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
comparisonImage.save(resultFolderPath + "/" + "Difference Image.png");
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
|
||||
void includeTest(QTextStream& textStream, const QString& testPathname);
|
||||
|
||||
void appendTestResultsToFile(TestResult testResult, QPixmap comparisonImage, bool hasFailed);
|
||||
void appendTestResultsToFile(const TestResult& testResult, const QPixmap& comparisonImage, const QPixmap& ssimResultsImage, bool hasFailed);
|
||||
void appendTestResultsToFile(QString testResultFilename, bool hasFailed);
|
||||
|
||||
bool createTestResultsFolderPath(const QString& directory);
|
||||
|
@ -116,7 +116,7 @@ private:
|
|||
const QString TEST_RESULTS_FOLDER { "TestResults" };
|
||||
const QString TEST_RESULTS_FILENAME { "TestResults.txt" };
|
||||
|
||||
const double THRESHOLD{ 0.935 };
|
||||
const double THRESHOLD{ 0.98 };
|
||||
|
||||
QDir _imageDirectory;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef hifi_common_h
|
||||
#define hifi_common_h
|
||||
|
||||
#include <vector>
|
||||
#include <QtCore/QString>
|
||||
|
||||
class TestResult {
|
||||
|
@ -39,4 +40,11 @@ const double R_Y = 0.212655f;
|
|||
const double G_Y = 0.715158f;
|
||||
const double B_Y = 0.072187f;
|
||||
|
||||
class SSIMResults {
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
std::vector<double> results;
|
||||
};
|
||||
|
||||
#endif // hifi_common_h
|
Loading…
Reference in a new issue