Skip to content

Commit

Permalink
4.3.8: fix #7: Histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
zvezdochiot committed May 6, 2021
1 parent ae9cacf commit 55aede6
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 83 deletions.
142 changes: 60 additions & 82 deletions src/tools/histogram-viewer/histogram_viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
Copyright (C) 2020 Arindam Chaudhuri <ksharindam@gmail.com>
*/
#include "histogram_viewer.h"
#include <cmath>
#include <QPainter>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QCheckBox>
#include <QDialogButtonBox>


#define PLUGIN_NAME "Histogram Viewer"
Expand All @@ -18,133 +12,117 @@ Q_EXPORT_PLUGIN2(histogram-viewer, ToolPlugin);

//********* ---------- Histogram Viewer --------- ********** //

void getHistogram(QImage &img, uint hist_r[], uint hist_g[], uint hist_b[], uint hist_y[])
void getHistogram(QImage &img, uint hist_r[], uint hist_g[], uint hist_b[])
{
int w = img.width();
int h = img.height();
int x, y, r, g, b;

for (int y=0; y<h; y++) {
for (y = 0; y < h; y++)
{
QRgb *row = (QRgb*) img.constScanLine(y);
for (int x=0; x<w; x++) {
int r = qRed(row[x]);
int g = qGreen(row[x]);
int b = qBlue(row[x]);
int Y = r*0.2126f + g*0.7152f + b*0.0722f;
for (x=0; x<w; x++)
{
r = qRed(row[x]);
g = qGreen(row[x]);
b = qBlue(row[x]);
++hist_r[r];
++hist_g[g];
++hist_b[b];
++hist_y[Y];
}
}
}

template<typename T>
QImage histogramImage(T histogram[], QColor color, int hist_w, int hist_h)
template<typename T> QImage histogramImage(T histr[], T histg[], T histb[], int hist_w, int hist_h, bool logarithmic)
{
// get maximum in each histogram
T max_val=0;
for (int i=0; i<256; i++) {
if (histogram[i] > max_val) max_val = histogram[i];
T max_val = 0;
int i, j, i1, x, ro, go, bo;
float factorh, factorl, factorw;
float r, g, b, k, ix, kx;
for (i = 0; i < 256; i++)
{
if (histr[i] > max_val) max_val = histr[i];
if (histg[i] > max_val) max_val = histg[i];
if (histb[i] > max_val) max_val = histb[i];
}
// create histogram image and draw histogram
double factor = (double)hist_h / max_val;
factorh = (float)max_val / (float)hist_h;
factorl = (max_val > 0) ? (float)max_val / log((float)max_val + 1.0f) : 1.0f;
factorw = 256.0f / (float)hist_w;

QImage hist_img(hist_w+2, hist_h+2, QImage::Format_RGB32);
hist_img.fill(Qt::white);
QImage hist_img(hist_w, hist_h, QImage::Format_RGB32);

QPainter painter(&hist_img);
// draw outline and grid
painter.drawRect(0,0, hist_w+1, hist_h+1);
painter.setPen(QColor(220,220,220));
for (int i=1; i<5; i++) {
painter.drawLine(QPoint(i*255/5,1), QPoint(i*255/5,hist_h));
}
// draw histogram bars
painter.setPen(color);
for (int i=0; i<256; i++) {
int line_height = factor*histogram[i];
if (line_height==0)
continue;
QPoint start(i+1, 1);
QPoint end(i+1, line_height);
painter.drawLine(start, end);
for (j = 0; j < hist_h; j++)
{
QRgb *row = (QRgb*)hist_img.constScanLine(j);
for (x = 0; x < hist_w; x++)
{
ix = factorw * x;
i = (int)ix;
i1 = ((i + 1) < hist_w) ? (i + 1) : i;
kx = ix - i;
k = (float)max_val - (float)j * factorh;
r = ((1.0f - kx) * (float)histr[i] + kx * (float)histr[i1]);
g = ((1.0f - kx) * (float)histg[i] + kx * (float)histg[i1]);
b = ((1.0f - kx) * (float)histb[i] + kx * (float)histb[i1]);
if (logarithmic)
{
r = log(r + 1.0f) * factorl;
g = log(g + 1.0f) * factorl;
b = log(b + 1.0f) * factorl;
}
ro = (r > k) ? 255 : 0;
go = (g > k) ? 255 : 0;
bo = (b > k) ? 255 : 0;
row[x] = qRgb(ro, go, bo);
}
}
painter.end();
// flip, because Y axis has reverse direction in QImage
QTransform tfm;
tfm.rotate(180, Qt::XAxis);
return hist_img.transformed(tfm);
return hist_img;
}


//--------- **************** Histogram Dialog ****************---------
HistogramDialog:: HistogramDialog(QWidget *parent, QImage &image) : QDialog(parent)
{
this->setWindowTitle("R G B and Luminance(Y) Histogram");
this->setWindowTitle("R G B Histogram");
this->resize(540, 400);

QGridLayout *gridLayout = new QGridLayout(this);
gridLayout = new QGridLayout(this);

histLabel = new QLabel(this);
histLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
gridLayout->addWidget(histLabel, 0, 0, 1, 2);
// container for holding buttons
QWidget *container = new QWidget(this);
container = new QWidget(this);
gridLayout->addWidget(container, 1, 0, 1, 1);

QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this);
buttonBox = new QDialogButtonBox(Qt::Horizontal, this);
buttonBox->setStandardButtons(QDialogButtonBox::Close);
gridLayout->addWidget(buttonBox, 1, 1, 1, 1);

QHBoxLayout *hLayout = new QHBoxLayout(container);
hLayout = new QHBoxLayout(container);
container->setLayout(hLayout);

QCheckBox *logBtn = new QCheckBox("Logarithmic", this);
logBtn = new QCheckBox("Logarithmic", this);
hLayout->addWidget(logBtn);

connect(logBtn, SIGNAL(clicked(bool)), this, SLOT(drawHistogram(bool)));
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

// generate histograms
getHistogram(image, hist_r, hist_g, hist_b, hist_y);
getHistogram(image, hist_r, hist_g, hist_b);
drawHistogram(false);
}

void
HistogramDialog:: drawHistogram(bool logarithmic)
void HistogramDialog:: drawHistogram(bool logarithmic)
{
int hist_w = 256;
int hist_h = 160;
QImage imgR, imgG, imgB, imgY;
if (not logarithmic) {
imgR = histogramImage(hist_r, Qt::red, hist_w, hist_h);
imgG = histogramImage(hist_g, Qt::green, hist_w, hist_h);
imgB = histogramImage(hist_b, Qt::blue, hist_w, hist_h);
imgY = histogramImage(hist_y, QColor(127,127,127), hist_w, hist_h);
}
else { // logarithmic histograms
double loghist[4][256] = {};
for (int i=0; i<256; i++) {
loghist[0][i] = log(hist_r[i]);
loghist[1][i] = log(hist_g[i]);
loghist[2][i] = log(hist_b[i]);
loghist[3][i] = log(hist_y[i]);
}
imgR = histogramImage(loghist[0], Qt::red, hist_w, hist_h);
imgG = histogramImage(loghist[1], Qt::green, hist_w, hist_h);
imgB = histogramImage(loghist[2], Qt::blue, hist_w, hist_h);
imgY = histogramImage(loghist[3], QColor(127,127,127), hist_w, hist_h);
}

QImage img(hist_w*2+3, hist_h*2+3, QImage::Format_RGB32);
img.fill(Qt::white);
QPainter painter(&img);
painter.drawImage(0, 0, imgR);
painter.drawImage(hist_w+1, 0, imgG);
painter.drawImage(0, hist_h+1, imgB);
painter.drawImage(hist_w+1, hist_h+1, imgY);
painter.end();
int hist_w = 512;
int hist_h = 320;
QImage img;
img = histogramImage(hist_r, hist_g, hist_b, hist_w, hist_h, logarithmic);

histLabel->setPixmap(QPixmap::fromImage(img));
}
Expand Down
11 changes: 10 additions & 1 deletion src/tools/histogram-viewer/histogram_viewer.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#pragma once
#include "plugin.h"
#include <cmath>
#include <QDialog>
#include <QLabel>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QCheckBox>
#include <QDialogButtonBox>

class ToolPlugin : public QObject, Plugin
{
Expand All @@ -27,8 +32,12 @@ class HistogramDialog : public QDialog
uint hist_r[256] = {};
uint hist_g[256] = {};
uint hist_b[256] = {};
uint hist_y[256] = {};
//widgets
QGridLayout *gridLayout;
QWidget *container;
QDialogButtonBox *buttonBox;
QHBoxLayout *hLayout;
QCheckBox *logBtn;
QLabel *histLabel;

HistogramDialog(QWidget *parent, QImage &image);
Expand Down

0 comments on commit 55aede6

Please sign in to comment.