1
0
lpo-image-processing/03/do_sprawdzenia/cpp/histogram.cpp

137 lines
3.2 KiB
C++

#include "histogram.h"
#include <QDebug>
#include <QPainter>
#include <cmath>
Histogram::Histogram(QImage* image)
{
R = new QHash<int, int>;
G = new QHash<int, int>;
B = new QHash<int, int>;
L = new QHash<int, int>;
generate(image);
}
Histogram::~Histogram()
{
delete R;
delete G;
delete B;
delete L;
}
void Histogram::generate(QImage* image)
{
int width = image->width();
int height = image->height();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
QRgb pixel = image->pixel(x,y);
// Get color values
int r = Histogram::R->value(qRed(pixel));
int g = Histogram::G->value(qGreen(pixel));
int b = Histogram::B->value(qBlue(pixel));
int l = Histogram::L->value(qGray(pixel));
// Insert color values
Histogram::R->insert(qRed(pixel), r+1);
Histogram::G->insert(qGreen(pixel), g+1);
Histogram::B->insert(qBlue(pixel), b+1);
Histogram::L->insert(qGray(pixel), l+1);
}
}
}
/** Returns the maximal value of the histogram in the given channel */
int Histogram::maximumValue(Channel selectedChannel = RGB)
{
// Create and set max value
int max = 0;
// Iterate over values
for(int i = 0; i < R->size(); i++)
{
if(R->value(i) > max)
{
max = R->value(i);
}
}
for(int i = 0; i < G->size(); i++)
{
if(G->value(i) > max)
{
max = G->value(i);
}
}
for(int i = 0; i < B->size(); i++)
{
if(B->value(i) > max)
{
max = B->value(i);
}
}
for(int i = 0; i < L->size(); i++)
{
if(L->value(i) > max)
{
max = L->value(i);
}
}
return max;
}
/** Returns a pointer to the given channel QHash<int, int> */
QHash<int, int>* Histogram::get(Channel channel = LChannel)
{
if (channel==LChannel) return L;
if (channel==RChannel) return R;
if (channel==GChannel) return G;
if (channel==BChannel) return B;
return 0;
}
/**
* Returns a 255 by 100 QImage containing a Histogram for the given channel.
* The background is transparent (Alpha 0, RGB=255) */
QImage Histogram::getImage(Channel channel = LChannel, QBrush pen = Qt::gray)
{
// Create blank QImage and fill it with transparent background:
QImage histImage(255, 100, QImage::Format_ARGB32);
histImage.fill(0);
QPainter painter(&histImage);
painter.setBrush(Qt::transparent);
painter.setPen(Qt::transparent);
painter.drawRect(0,0,255,100);
// Calculate the aspect ratio using the maximal value of the color histograms
int maximum = (channel == LChannel ? maximumValue(LChannel) : maximumValue(RGB));
float ratio = 100.0/float(maximum);
// Preparing the painter:
painter.setBrush(pen);
painter.setPen(pen.color());
int h;
// Draw histogram
QHash<int, int>* hist = get(channel);
QHash<int, int>::const_iterator cit = hist->begin();
while (cit != hist->end())
{
h = 100 - floor(ratio*cit.value());
painter.drawLine(cit.key(), h, cit.key(), 100);
++cit;
}
return histImage;
}