qjpeg/plugins/PSNR.cpp
author viric@mandarina
Fri, 12 Dec 2008 16:07:09 +0000
changeset 251 4aa28098b2c2
parent 234 e78ee672b1ab
permissions -rw-r--r--
Arreglo un greu problema al càlcul de la PSNR (girava files i columnes)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
234
e78ee672b1ab Licensing GPLv2
viric@llimona
parents: 148
diff changeset
     1
/*
e78ee672b1ab Licensing GPLv2
viric@llimona
parents: 148
diff changeset
     2
    QJpegRest - An interactive JPEG decoder, with restoration algorithms
e78ee672b1ab Licensing GPLv2
viric@llimona
parents: 148
diff changeset
     3
    Copyright (C) 2007  Lluís Batlle i Rossell
e78ee672b1ab Licensing GPLv2
viric@llimona
parents: 148
diff changeset
     4
e78ee672b1ab Licensing GPLv2
viric@llimona
parents: 148
diff changeset
     5
    Please find the license in the provided LICENSE file.
e78ee672b1ab Licensing GPLv2
viric@llimona
parents: 148
diff changeset
     6
*/
109
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
     7
#include <ActionType.h>
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
     8
#include <MeasureResult.h>
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
     9
#include <Actions.h>
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    10
#include <ActionCreator.h>
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    11
#include <ActionManager.h>
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    12
#include <GrayImage.h>
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    13
#include <cmath>
109
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    14
#include <ARGBImage.h>
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    15
#include <cstdio>
109
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    16
#include "PSNR.h"
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    17
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    18
PSNR::PSNR()
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    19
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    20
    name = "PSNR";
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    21
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    22
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    23
void PSNR::prepare(const ARGBImage *img1, const ARGBImage *img2)
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    24
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    25
    rgbimg1 = img1;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    26
    rgbimg2 = img2;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    27
    type = ARGB;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    28
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    29
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    30
void PSNR::prepare(const GrayImage *img1, const GrayImage *img2)
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    31
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    32
    gray1 = img1;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    33
    gray2 = img2;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    34
    type = Gray;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    35
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    36
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    37
/* Given an original and an approximation value,
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    38
   returns  Signal_Power/Noise_Power */
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    39
static inline int se_single(int original, int approximation)
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    40
{
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    41
	return (original - approximation) * (original - approximation);
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    42
}
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    43
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    44
float PSNR::fromGray()
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    45
{
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    46
    int row, column;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    47
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    48
    int sum;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    49
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    50
    sum = 0;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    51
    for (row = 0; row < gray1->getHeight(); row++)
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    52
        for (column = 0; column < gray1->getWidth(); column++)
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    53
        {
251
4aa28098b2c2 Arreglo un greu problema al càlcul de la PSNR (girava files i columnes)
viric@mandarina
parents: 234
diff changeset
    54
            sum += se_single(gray1->getPixel(column, row), gray2->getPixel(column, row));
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    55
        }
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    56
    float mean = (float) sum / (float) (gray1->getHeight() * gray1->getWidth());
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    57
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    58
    return 255. / sqrt(mean);
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    59
}
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    60
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    61
void PSNR::fromARGB(float psnrs[3])
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    62
{
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    63
    int row, column;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    64
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    65
    int sumR, sumG, sumB;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    66
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    67
    sumR = sumG = sumB = 0;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    68
    for (row = 0; row < rgbimg1->getHeight(); row++)
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    69
        for (column = 0; column < rgbimg1->getWidth(); column++)
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    70
        {
251
4aa28098b2c2 Arreglo un greu problema al càlcul de la PSNR (girava files i columnes)
viric@mandarina
parents: 234
diff changeset
    71
            unsigned int pixel1 = rgbimg1->getIntPixel(column, row);
4aa28098b2c2 Arreglo un greu problema al càlcul de la PSNR (girava files i columnes)
viric@mandarina
parents: 234
diff changeset
    72
            unsigned int pixel2 = rgbimg2->getIntPixel(column, row);
115
a2cc9c678dda PSNRs and GBIMs are calculated fine. There is a terrible code doubling anyway.
viric@llimona
parents: 113
diff changeset
    73
            sumR += se_single(rgbimg1->getR(pixel1), rgbimg2->getR(pixel2));
a2cc9c678dda PSNRs and GBIMs are calculated fine. There is a terrible code doubling anyway.
viric@llimona
parents: 113
diff changeset
    74
            sumG += se_single(rgbimg1->getG(pixel1), rgbimg2->getG(pixel2));
a2cc9c678dda PSNRs and GBIMs are calculated fine. There is a terrible code doubling anyway.
viric@llimona
parents: 113
diff changeset
    75
            sumB += se_single(rgbimg1->getB(pixel1), rgbimg2->getB(pixel2));
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    76
        }
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    77
    int sizes = rgbimg1->getHeight() * rgbimg1->getWidth();
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    78
    float meanR = (float) sumR / (float) sizes;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    79
    float meanG = (float) sumG / (float) sizes;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    80
    float meanB = (float) sumB / (float) sizes;
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    81
    fprintf(stderr,"means: %f %f %f, size: %i\n", meanR, meanG, meanB, sizes);
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    82
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    83
    psnrs[0] = 255. / std::sqrt(meanR);
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    84
    psnrs[1] = 255. / std::sqrt(meanG);
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    85
    psnrs[2] = 255. / std::sqrt(meanB);
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    86
}
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    87
109
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    88
MeasureResult * PSNR::apply()
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    89
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
    90
    MeasureResult *res = new MeasureResult();
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    91
    if (type == Gray)
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    92
    {
148
a553b5b9206c The measures are shown as text now. Informing on images measured and measure method.
viric@mandarina
parents: 115
diff changeset
    93
        res->text += QString("Gray: \%1 dB\n").arg(fromGray());
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    94
    } else {
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    95
        float psnrs[3];
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
    96
        fromARGB(psnrs);
148
a553b5b9206c The measures are shown as text now. Informing on images measured and measure method.
viric@mandarina
parents: 115
diff changeset
    97
        res->text += QString("Red: \%1 dB\n").arg(psnrs[0]);
a553b5b9206c The measures are shown as text now. Informing on images measured and measure method.
viric@mandarina
parents: 115
diff changeset
    98
        res->text += QString("Green: \%1 dB\n").arg(psnrs[1]);
a553b5b9206c The measures are shown as text now. Informing on images measured and measure method.
viric@mandarina
parents: 115
diff changeset
    99
        res->text += QString("Blue: \%1 dB\n").arg(psnrs[2]);
113
8c10c5618938 The PSNR calculator should work now. Although the numbers are different from imgerror.
viric@mandarina
parents: 111
diff changeset
   100
    }
111
5d4ec367e379 The measure results are shown in an Mdi child window.
viric@mandarina
parents: 109
diff changeset
   101
    return res;
109
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   102
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   103
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   104
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   105
PSNRCreator::PSNRCreator()
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   106
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   107
    type = e_Compare;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   108
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   109
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   110
bool PSNRCreator::isapplicable(const JPEGParameters &p)
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   111
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   112
    return true;
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   113
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   114
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   115
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   116
void PSNRCreator::init()
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   117
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   118
    ActionCreator *a = new PSNRCreator();
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   119
    ActionManager::sreg("PSNR", a);
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   120
}
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   121
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   122
Compare * PSNRCreator::createCompare() const
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   123
{
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   124
    return new PSNR();
2c1295905aff Added a context menu for images, so measures can be applied. Also a fake Compare (PSNR) is added.
viric@llimona
parents:
diff changeset
   125
}