https://doi.org/10.5201/ipol.2014.98
Tip revision: a774add2f966ff371462ab88d6efb6d525c7b7e4 authored by Software Heritage on 12 July 2013, 00:00:00 UTC
ipol: Deposit 1240 in collection ipol
ipol: Deposit 1240 in collection ipol
Tip revision: a774add
imdiff_ipol.cpp
/*
* Copyright 2009-2015 IPOL Image Processing On Line http://www.ipol.im/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Visualizes the difference between two images in such a way that
* the intensity range is linearly transformed from [-20, 20] to [0, 255] for
* visualization purposes. Values outside this range are saturated to 0 and 255,
* respectively. It also computes the Root Mean Squared Error:
*
* @f$ RMSE = \frac{1}{3} \sum_{m=1}^{3} \sqrt{\frac{\sum_{p\in I}
* (u(p)-v(p))^2}{N^2}} @f$,
*
* where @f$ I @f$ denotes the discrete grid and @f$ N^2 @f$ is the number of
* pixels of both images.
*
*/
/**
* @file imdiff_ipol.cpp
* @brief Main executable file
*
* @author Joan Duran <joan.duran@uib.es>
*/
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include "io_png.h"
// Usage: imdiff_ipol image1.png image2.png difference.png
int main(int argc, char **argv)
{
if(argc < 4)
{
printf("usage: imdiff_ipol image1.png image2.png difference.png\n");
printf("image1.png :: first image.\n");
printf("image2.png :: second image.\n");
printf("difference.png :: difference image.\n");
return EXIT_FAILURE;
}
// Read first input
size_t nx, ny, nc;
float *d_v = NULL;
d_v = io_png_read_f32(argv[1], &nx, &ny, &nc);
if (!d_v)
{
fprintf(stderr, "Error - %s not found or not a correct png image.\n", argv[1]);
return EXIT_FAILURE;
}
if (nc == 2) // We do not use the alpha channel if grayscale image
nc = 1;
if (nc > 3) // We do not use the alpha channel if RGB image
nc = 3;
// Read second input
size_t nx2, ny2, nc2;
float *d_v2 = NULL;
d_v2 = io_png_read_f32(argv[2], &nx2, &ny2, &nc2);
if (!d_v2)
{
fprintf(stderr, "Error - %s not found or not a correct png image.\n",
argv[2]);
return EXIT_FAILURE;
}
if (nc2 == 2) // We do not use the alpha channel if grayscale image
nc2 = 1;
if (nc2 > 3) // We do not use the alpha channel if RGB image
nc2 = 3;
if (nx != nx2 || ny != ny2)
{
// Check if both images have same size
fprintf(stderr, "Error - %s and %s sizes don't match.\n", argv[1],
argv[2]);
return EXIT_FAILURE;
}
if (nc != nc2)
{
// Check if both images have same number of channels
fprintf(stderr, "Error - %s and %s channels don't match.\n", argv[1],
argv[2]);
return EXIT_FAILURE;
}
// Image variables
int d_w = (int) nx;
int d_h = (int) ny;
int d_c = (int) nc;
int d_wh = d_w * d_h;
int d_whc = d_c * d_wh;
// Image vectors
float **image1 = new float*[d_c];
float **image2 = new float*[d_c];
for(int c = 0; c < d_c; c++)
{
image1[c] = &d_v[c*d_wh];
image2[c] = &d_v2[c*d_wh];
}
// Compute RMSE
float fRMSE = 0.0f;
for(int c = 0; c < d_c ; c++)
{
float fDist = 0.0f;
for(int i = 0; i < d_wh; i++)
{
float dif = image1[c][i] - image2[c][i];
fDist += dif * dif;
}
fDist /= (float) d_wh;
fRMSE += sqrt(fDist);
}
fRMSE /= (float) d_c;
printf("RMSE: %2.2f\n", fRMSE);
// Compute image difference. Convert from [-20, 20] to [0,255]
float *difference = new float[d_whc];
for(int i = 0; i < d_whc; i++)
{
float fValue = d_v[i] - d_v2[i];
fValue = (fValue + 20.0f) * 255.0f / 40.0f;
if (fValue < 0.0) fValue = 0.0f;
if (fValue > 255.0) fValue = 255.0f;
difference[i] = fValue;
}
// Saving difference as png image
if (io_png_write_f32(argv[3], difference, (size_t) d_w, (size_t) d_h,
(size_t) d_c) != 0)
fprintf(stderr, "Error - Failed to save png image %s.\n", argv[3]);
// Free memory
free(d_v);
free(d_v2);
delete[] difference;
return EXIT_SUCCESS;
}