Add diff flag for compare tool

This commit is contained in:
Pavel Krajcevski 2015-12-20 16:25:45 -05:00
parent be844246cf
commit f1151ff767
3 changed files with 103 additions and 7 deletions

View file

@ -97,6 +97,8 @@ namespace FasTC {
double ComputePSNR(Image<PixelType> *other);
double ComputeSSIM(Image<PixelType> *other);
Image<PixelType> Diff(Image<PixelType> *other);
double ComputeEntropy();
double ComputeMeanLocalEntropy();

View file

@ -48,6 +48,7 @@
#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>
@ -66,6 +67,29 @@ static inline T Clamp(const T &v, const T &a, const T &b) {
return ::std::min(::std::max(a, v), b);
}
template<typename T> inline T PixelAbs(const T &a);
template<> inline FasTC::IPixel PixelAbs<FasTC::IPixel>(const FasTC::IPixel &p) {
return FasTC::IPixel(fabs(p[0]));
}
template<> inline FasTC::Pixel PixelAbs<FasTC::Pixel>(const FasTC::Pixel &p) {
FasTC::Pixel result = p;
if (result.R() < 0) { result.R() = -result.R(); }
if (result.G() < 0) { result.G() = -result.G(); }
if (result.B() < 0) { result.B() = -result.B(); }
if (result.A() < 0) { result.A() = -result.A(); }
return result;
}
template<> inline FasTC::Color PixelAbs<FasTC::Color>(const FasTC::Color &p) {
FasTC::Color result = p;
if (result.R() < 0) { result.R() = -result.R(); }
if (result.G() < 0) { result.G() = -result.G(); }
if (result.B() < 0) { result.B() = -result.B(); }
if (result.A() < 0) { result.A() = -result.A(); }
return result;
}
// wtf
#ifdef _MSC_VER
template<typename T> T log2(T x) { return static_cast<T>(log((long double)x) / log(2.0)); }
@ -174,6 +198,35 @@ const PixelType & Image<PixelType>::operator()(uint32 i, uint32 j) const {
return m_Pixels[j * GetWidth() + i];
}
template<typename PixelType>
Image<PixelType> Image<PixelType>::Diff(Image<PixelType> *other) {
if (!other) {
std::cerr << "Image::Diff - ERROR: other == null" << std::endl;
assert(false);
}
if (GetWidth() != other->GetWidth() ||
GetHeight() != other->GetHeight()) {
std::cerr << "Image::Diff - ERROR: Images differ in dimension" << std::endl;
assert(false);
return *this;
}
this->ComputePixels();
other->ComputePixels();
Image<PixelType> result(GetWidth(), GetHeight());
for (int j = 0; j < GetHeight(); ++j) {
for (int i = 0; i < GetWidth(); ++i) {
result(i, j) = PixelAbs((*this)(i, j) - (*other)(i, j));
result(i, j).MakeOpaque();
}
}
// !SPEED! We do an unnecessary copy here...
return result;
}
template<typename PixelType>
double Image<PixelType>::ComputePSNR(Image<PixelType> *other) {
if(!other)

View file

@ -47,6 +47,7 @@
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <fstream>
#ifdef _MSC_VER
@ -59,27 +60,67 @@
#include "FasTC/TexComp.h"
#include "FasTC/ThreadSafeStreambuf.h"
static void PrintUsageAndExit() {
fprintf(stderr, "Usage: compare [-d] <img1> <img2>\n");
exit(1);
}
void gen_random(char *s, const int len) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
srand(time(NULL));
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}
int main(int argc, char **argv) {
if(argc != 3) {
fprintf(stderr, "Usage: compare <img1> <img2>\n");
return 1;
if(argc != 3 && argc != 4) {
PrintUsageAndExit();
}
ImageFile img1f (argv[1]);
bool diff_images = false;
int arg = 1;
if (strncmp(argv[arg], "-d", 2) == 0) {
diff_images = true;
arg++;
}
ImageFile img1f (argv[arg]);
if(!img1f.Load()) {
fprintf(stderr, "Error loading file: %s\n", argv[1]);
fprintf(stderr, "Error loading file: %s\n", argv[arg]);
return 1;
}
arg++;
ImageFile img2f (argv[2]);
ImageFile img2f (argv[arg]);
if(!img2f.Load()) {
fprintf(stderr, "Error loading file: %s\n", argv[2]);
fprintf(stderr, "Error loading file: %s\n", argv[arg]);
return 1;
}
arg++;
FasTC::Image<> &img1 = *img1f.GetImage();
FasTC::Image<> &img2 = *img2f.GetImage();
if (diff_images) {
FasTC::Image<> diff = img1.Diff(&img2);
char fname_buf [5 + 16 + 4]; // "diff-" + hash + ".png"
strncat(fname_buf, "diff-", 5);
gen_random(fname_buf + 5, 16);
strncat(fname_buf + 5 + 16, ".png", 4);
EImageFileFormat fmt = ImageFile::DetectFileFormat(fname_buf);
ImageFile cImgFile (fname_buf, fmt, diff);
cImgFile.Write();
}
double PSNR = img1.ComputePSNR(&img2);
if(PSNR > 0.0) {
fprintf(stdout, "PSNR: %.3f\n", PSNR);