Compare commits
2 Commits
664d4e19f9
...
96129bc8ab
Author | SHA1 | Date | |
---|---|---|---|
|
96129bc8ab | ||
|
7e1be18f0d |
@ -1,6 +1,6 @@
|
|||||||
#include "histogram_equalization.h"
|
#include "histogram_equalization.h"
|
||||||
|
|
||||||
#include "../histogram.h"
|
#include "../histogram.h"
|
||||||
#include <cmath> // Dla funkcji round
|
|
||||||
|
|
||||||
HistogramEqualization::HistogramEqualization(PNM* img) :
|
HistogramEqualization::HistogramEqualization(PNM* img) :
|
||||||
Transformation(img)
|
Transformation(img)
|
||||||
@ -14,44 +14,77 @@ HistogramEqualization::HistogramEqualization(PNM* img, ImageViewer* iv) :
|
|||||||
|
|
||||||
PNM* HistogramEqualization::transform()
|
PNM* HistogramEqualization::transform()
|
||||||
{
|
{
|
||||||
int width = image->width();
|
float width = image->width();
|
||||||
int height = image->height();
|
float height = image->height();
|
||||||
|
|
||||||
// Tworzymy nowy obiekt PNM do przechowywania przetworzonego obrazu
|
|
||||||
PNM* newImage = new PNM(width, height, image->format());
|
PNM* newImage = new PNM(width, height, image->format());
|
||||||
|
Histogram* histogram = image->getHistogram();
|
||||||
|
|
||||||
// Tworzymy histogram dla obecnego obrazu
|
QHash<int, int>* R = histogram->get(Histogram::RChannel);
|
||||||
Histogram* hist = image->getHistogram(); // Nie przekazujemy argumentów
|
QHash<int, int>* G = histogram->get(Histogram::GChannel);
|
||||||
|
QHash<int, int>* B = histogram->get(Histogram::BChannel);
|
||||||
|
QHash<int, int>* L = histogram->get(Histogram::LChannel);
|
||||||
|
|
||||||
// Pobieramy łączną liczbę pikseli na obrazie
|
// Probability tables
|
||||||
int totalPixels = width * height;
|
float redProb[255];
|
||||||
|
float greenProb[255];
|
||||||
|
float blueProb[255];
|
||||||
|
float greyProb[255];
|
||||||
|
|
||||||
// Tworzymy dystrybuantę
|
float pixelSum = width * height;
|
||||||
QVector<double> cdf(256, 0.0); // Inicjalizujemy wszystkie wartości na 0.0
|
for (int i = 0; i < 256; i++)
|
||||||
double sum = 0.0;
|
{
|
||||||
for (int i = 0; i < 256; ++i) {
|
redProb[i] = (R->value(i)) / (pixelSum);
|
||||||
sum += hist->get(Histogram::LChannel)->value(i) / static_cast<double>(totalPixels); // Używamy kanału luminancji
|
greenProb[i] = (G->value(i)) / (pixelSum);
|
||||||
cdf[i] = sum;
|
blueProb[i] = (B->value(i)) / (pixelSum);
|
||||||
|
greyProb[i] = (L->value(i)) / (pixelSum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalizujemy dystrybuantę do przedziału [0, 255]
|
// D look-up
|
||||||
QVector<int> lookupTable(256, 0);
|
float redD[255];
|
||||||
for (int i = 0; i < 256; ++i) {
|
float greenD[255];
|
||||||
lookupTable[i] = round(cdf[i] * 255);
|
float blueD[255];
|
||||||
|
float greyD[255];
|
||||||
|
|
||||||
|
// Create template values
|
||||||
|
float sumRed = 0;
|
||||||
|
float sumGreen = 0;
|
||||||
|
float sumBlue = 0;
|
||||||
|
float sumGrey = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 255; i++)
|
||||||
|
{
|
||||||
|
sumRed = redProb[i] + sumRed;
|
||||||
|
redD[i] = sumRed;
|
||||||
|
|
||||||
|
sumGreen = greenProb[i] + sumGreen;
|
||||||
|
greenD[i] = sumGreen;
|
||||||
|
|
||||||
|
sumBlue = blueProb[i] + sumBlue;
|
||||||
|
blueD[i] = sumBlue;
|
||||||
|
|
||||||
|
sumGrey= greyProb[i] + sumGrey;
|
||||||
|
greyD[i] = sumGrey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Przeprowadzamy wyrównywanie histogramu
|
for (int x = 0; x < image->width(); x++)
|
||||||
for (int y = 0; y < height; ++y) {
|
{
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int y = 0; y < image->height(); y++)
|
||||||
|
{
|
||||||
QRgb pixel = image->pixel(x, y);
|
QRgb pixel = image->pixel(x, y);
|
||||||
int grayValue = qGray(pixel); // Pobieramy wartość odcienia szarości
|
if (image->format() == QImage::Format_RGB32) {
|
||||||
|
newImage->setPixel(
|
||||||
// Używamy wartości z lookupTable jako nowej wartości odcienia szarości
|
x,
|
||||||
int newGrayValue = lookupTable[grayValue];
|
y,
|
||||||
QRgb newPixel = qRgb(newGrayValue, newGrayValue, newGrayValue); // Ustawiamy nową wartość dla każdego kanału RGB
|
QColor(
|
||||||
|
redD[qRed(pixel)] * 255,
|
||||||
// Ustawiamy nowy piksel na obrazie docelowym
|
greenD[qGreen(pixel)] * 255,
|
||||||
newImage->setPixel(x, y, newPixel);
|
blueD[qBlue(pixel)] * 255
|
||||||
|
).rgb());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newImage->setPixel(x, y, greyD[qGray(pixel)] * 255);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,42 +20,76 @@ PNM* HistogramStretching::transform()
|
|||||||
PNM* newImage = new PNM(width, height, image->format());
|
PNM* newImage = new PNM(width, height, image->format());
|
||||||
Histogram* histogram = image->getHistogram();
|
Histogram* histogram = image->getHistogram();
|
||||||
|
|
||||||
int minValue = -1;
|
int maxRed = 255, maxGreen = 255, maxBlue = 255, maxGrey = 255;
|
||||||
int maxValue = -1;
|
|
||||||
|
|
||||||
for (int y = 0; y < image->height(); ++y) {
|
int minRed = 0, minGreen = 0, minBlue = 0, minGrey = 0;
|
||||||
for (int x = 0; x < image->width(); ++x) {
|
|
||||||
if (histogram->get(Histogram::LChannel)->value(x + y * x) != 0)
|
QHash<int, int>* R = histogram->get(histogram->RChannel);
|
||||||
{
|
QHash<int, int>* G = histogram->get(histogram->GChannel);
|
||||||
minValue = histogram->get(Histogram::LChannel)->value(x + y * x);
|
QHash<int, int>* B = histogram->get(histogram->BChannel);
|
||||||
break;
|
QHash<int, int>* L = histogram->get(histogram->LChannel);
|
||||||
}
|
|
||||||
|
for (int i=0; i<256; i++)
|
||||||
|
{
|
||||||
|
if (R->value(minRed) == 0) {
|
||||||
|
minRed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G->value(minGreen) == 0) {
|
||||||
|
minGreen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (B->value(minBlue) == 0) {
|
||||||
|
minBlue++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (L->value(minGrey) == 0) {
|
||||||
|
minGrey++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = image->height(); y > 0; --y) {
|
for (int i=256; i>0; i--)
|
||||||
for (int x = image->width(); x < 0; --x) {
|
{
|
||||||
if (histogram->get(Histogram::LChannel)->value(x + y * x) != 0)
|
if (R->value(maxRed) == 0) {
|
||||||
{
|
maxRed--;
|
||||||
minValue = histogram->get(Histogram::LChannel)->value(x + y * x);
|
}
|
||||||
break;
|
|
||||||
}
|
if (G->value(maxGreen) == 0) {
|
||||||
|
maxGreen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (B->value(maxBlue) == 0) {
|
||||||
|
maxBlue--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (L->value(maxGrey) == 0) {
|
||||||
|
maxGrey--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = 0; y < image->height(); ++y) {
|
for (int x = 0; x < image->width(); x++) {
|
||||||
for (int x = 0; x < image->width(); ++x) {
|
for (int y = 0; y < image->height(); y++) {
|
||||||
QRgb pixel = image->pixel(x, y);
|
QRgb p = image->pixel(x, y);
|
||||||
|
|
||||||
int red = qRed(pixel);
|
if(image->format() == QImage::Format_RGB32) {
|
||||||
int green = qGreen(pixel);
|
int red = qRed(p);
|
||||||
int blue = qBlue(pixel);
|
int green = qGreen(p);
|
||||||
|
int blue = qBlue(p);
|
||||||
|
|
||||||
int stretchedRed = (255 * (red - minValue)) / (maxValue - minValue);
|
newImage->setPixel(
|
||||||
int stretchedGreen = (255 * (green - minValue)) / (maxValue - minValue);
|
x,
|
||||||
int stretchedBlue = (255 * (blue - minValue)) / (maxValue - minValue);
|
y,
|
||||||
|
QColor(
|
||||||
newImage->setPixel(x, y, qRgb(stretchedRed, stretchedGreen, stretchedBlue));
|
(255 / (maxRed - minRed)) * (red - minRed),
|
||||||
|
(255 / (maxGreen - minGreen)) * (green - minGreen),
|
||||||
|
(255 / (maxBlue - minBlue)) * (blue - minBlue)
|
||||||
|
).rgb());
|
||||||
|
} else {
|
||||||
|
newImage->setPixel(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
(255 / (maxGrey - minGrey)) * (qGray(p) - minGrey));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user