1
0

Zadanie 5

This commit is contained in:
Jarosław Wieczorek 2021-03-28 14:03:07 +02:00
parent 19acd3708d
commit dd3358b103
12 changed files with 692 additions and 6 deletions

View File

@ -0,0 +1,72 @@
#include "bin_gradient.h"
using namespace std;
BinarizationGradient::BinarizationGradient(PNM* img) :
Transformation(img)
{
}
BinarizationGradient::BinarizationGradient(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* BinarizationGradient::transform()
{
int width = image->width();
int height = image->height();
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
// Create variables
// The pixel value at point (i,j)
float I=0;
// The first component of the gradient at point (i,j)
float Gx=0;
// The second component of the gradient at point (i,j)
float Gy=0;
for (int x=0; x < width; x++)
{
for(int y=0; y < height; y++)
{
// Get current pixel value
QRgb pixel = image->pixel(x, y);
I = qGray(pixel);
// Calculate Gx
Gx = Gx + (I * qGray(image->pixel(x+1, y)) - I * qGray(image->pixel(x-1, y)));
//Calculate Gy
Gy = Gy + (I * qGray(image->pixel(x, y+1)) - I * qGray(image->pixel(x, y-1)));
}
}
// Calculate T
float T = (max(Gx, Gy) * I) / max(Gx, Gy);
// Iterate over pixels
for (int x=0; x < width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
if(qGray(pixel) > T)
{
newImage->setPixel(x, y, Qt::color1);
}
else
{
newImage->setPixel(x, y, Qt::color0);
}
}
}
return newImage;
}

View File

@ -0,0 +1,88 @@
#include "bin_iterbimodal.h"
#include "bin_manual.h"
#include "conversion_grayscale.h"
#include "histogram_equalization.h"
#include "../histogram.h"
BinarizationIterBimodal::BinarizationIterBimodal(PNM* img) :
Transformation(img)
{
}
BinarizationIterBimodal::BinarizationIterBimodal(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* BinarizationIterBimodal::transform()
{
int width = image->width();
int height = image->height();
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
// Create variables
HistogramEqualization* equalized_histogram = new HistogramEqualization(image);
BinarizationManual* binarization_manual;
int iter = 1;
// Threshold
int T = 128;
// New threshold
int T_new;
image = equalized_histogram->transform();
// Histogram table
hg = image->getHistogram()->get(Histogram::LChannel);
// Calculate new threshold
T_new = (avg_saturation(0, T-1) + avg_saturation(T, 255)) / 2;
while (T_new != T)
{
T = T_new;
T_new = (avg_saturation(0, T-1) + avg_saturation(T, 255)) / 2;
iter ++;
}
// Use manual binarization to binaryze image
binarization_manual = new BinarizationManual(image);
binarization_manual->setParameter("threshold", T);
// Return binary image
newImage = binarization_manual->transform();
return newImage;
}
int BinarizationIterBimodal::avg_saturation(int start, int end)
{
int i;
int value;
int sum;
int counter;
int result;
sum = 1;
counter = 1;
for (i = start; i <= end; i++)
{
// Get value
value = hg->value(i);
sum += value;
counter += value * i;
}
result = counter / sum;
return result;
}

View File

@ -0,0 +1,20 @@
#ifndef BIN_ITERBIMODAL_H
#define BIN_ITERBIMODAL_H
#include "transformation.h"
class BinarizationIterBimodal : public Transformation
{
public:
BinarizationIterBimodal(PNM*);
BinarizationIterBimodal(PNM*, ImageViewer*);
virtual PNM* transform();
QHash<int, int> * hg;
int avg_saturation(int, int);
};
#endif // BIN_ITERBIMODAL_H

View File

@ -0,0 +1,45 @@
#include "bin_manual.h"
BinarizationManual::BinarizationManual(PNM* img) :
Transformation(img)
{
}
BinarizationManual::BinarizationManual(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* BinarizationManual::transform()
{
int threshold = getParameter("threshold").toInt();
int width = image->width();
int height = image->height();
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
// Iterate over pixels
for (int x=0; x < width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
if(qGray(pixel) > threshold)
{
newImage->setPixel(x, y, Qt::color1);
}
else
{
newImage->setPixel(x, y, Qt::color0);
}
}
}
return newImage;
}

View File

@ -0,0 +1,69 @@
#include "bin_niblack.h"
#include "transformation.h"
BinarizationNiblack::BinarizationNiblack(PNM* img) :
Transformation(img)
{
}
BinarizationNiblack::BinarizationNiblack(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* BinarizationNiblack::transform()
{
int width = image->width();
int height = image->height();
int r = getParameter("r").toInt();
double a = getParameter("a").toDouble();
double arithmetic_mean = 0;
double variance = 0;
double standard_deviation = 0;
math::matrix<float> window;
int T;
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
for (int x=0; x < width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
//Get current window
window = getWindow(x, y, r, LChannel, RepeatEdge);
// Calculate arithmetic mean
arithmetic_mean = window.sum() / pow(r, 2);
// Calculate standard_deviation
for (int i = 0; i < r+1; i++){
for (int j = 0; i < r+1; i++){
variance += pow(window[i][j] - arithmetic_mean, 2);
}
}
variance /= pow(r, 2);
standard_deviation = sqrt(variance);
// Calculate threshold T
T = arithmetic_mean + a * standard_deviation;
if(qGray(pixel) > T)
{
newImage->setPixel(x, y, Qt::color1);
}
else
{
newImage->setPixel(x, y, Qt::color0);
}
}
}
return newImage;
}

View File

@ -0,0 +1,125 @@
#include "bin_otsu.h"
#include "histogram_equalization.h"
#include "../histogram.h"
BinarizationOtsu::BinarizationOtsu(PNM* img) :
Transformation(img)
{
}
BinarizationOtsu::BinarizationOtsu(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* BinarizationOtsu::transform()
{
int width = image->width();
int height = image->height();
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
HistogramEqualization* equalized_histogram = new HistogramEqualization(image);
QHash<int, int> * hg;
// Number od pixels in image
int N = width * height;
image = equalized_histogram->transform();
// Histogram table
hg = image->getHistogram()->get(Histogram::LChannel);
int value;
double bcv[256];
int sum_1 = 0;
int sum2 = 0;
double u_b;
double u_f;
double W_b;
double W_f;
for (int t=0; t < 255; t++)
{
for (int j=0; j < t; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum_1 += value;
}
W_b = sum_1 / pow(255, 2);
for (int j=0; j < t; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum2 += value * j;
}
if (sum_1 == 0)
{
u_b = 0;
}
else
{
u_b = sum2 / sum_1;
}
sum_1 = 0;
sum2 = 0;
for (int j=t; j < 255; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum_1 += value;
}
W_f = sum_1 / pow(255, 2);
for (int j=t; j < 255; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum2 += value * j;
}
if (sum_1 == 0)
{
u_f = 0;
}
else
{
u_f = sum2 / sum_1;
}
bcv[t]= W_b * W_f * pow(u_b - u_f, 2);
}
int T = 0;
for (int j=0; j< 255;j++)
{
if (bcv[j] > bcv[T])
{
T=j;
}
}
// Iterate over pixels
for (int x=0; x<width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
int l = qGray(pixel);
newImage->setPixel(x,y, l < T ? Qt::color0 : Qt::color1);
}
}
return newImage;
}

View File

@ -1,4 +1,5 @@
#include "bin_gradient.h"
using namespace std;
BinarizationGradient::BinarizationGradient(PNM* img) :
Transformation(img)
@ -17,7 +18,53 @@ PNM* BinarizationGradient::transform()
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
// Create variables
// The pixel value at point (i,j)
float I=0;
// The first component of the gradient at point (i,j)
float Gx=0;
// The second component of the gradient at point (i,j)
float Gy=0;
for (int x=0; x < width; x++)
{
for(int y=0; y < height; y++)
{
// Get current pixel value
QRgb pixel = image->pixel(x, y);
I = qGray(pixel);
// Calculate Gx
Gx = Gx + (I * qGray(image->pixel(x+1, y)) - I * qGray(image->pixel(x-1, y)));
//Calculate Gy
Gy = Gy + (I * qGray(image->pixel(x, y+1)) - I * qGray(image->pixel(x, y-1)));
}
}
// Calculate T
float T = (max(Gx, Gy) * I) / max(Gx, Gy);
// Iterate over pixels
for (int x=0; x < width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
if(qGray(pixel) > T)
{
newImage->setPixel(x, y, Qt::color1);
}
else
{
newImage->setPixel(x, y, Qt::color0);
}
}
}
return newImage;
}

View File

@ -1,9 +1,10 @@
#include "bin_iterbimodal.h"
#include "bin_manual.h"
#include "conversion_grayscale.h"
#include "histogram_equalization.h"
#include "../histogram.h"
BinarizationIterBimodal::BinarizationIterBimodal(PNM* img) :
Transformation(img)
{
@ -21,9 +22,66 @@ PNM* BinarizationIterBimodal::transform()
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
// Create variables
HistogramEqualization* equalized_histogram = new HistogramEqualization(image);
BinarizationManual* binarization_manual;
int iter = 1;
// Threshold
int T = 128;
// New threshold
int T_new;
image = equalized_histogram->transform();
// Histogram table
hg = image->getHistogram()->get(Histogram::LChannel);
// Calculate new threshold
T_new = (avg_saturation(0, T-1) + avg_saturation(T, 255)) / 2;
while (T_new != T)
{
T = T_new;
T_new = (avg_saturation(0, T-1) + avg_saturation(T, 255)) / 2;
iter ++;
}
// Use manual binarization to binaryze image
binarization_manual = new BinarizationManual(image);
binarization_manual->setParameter("threshold", T);
// Return binary image
newImage = binarization_manual->transform();
return newImage;
}
int BinarizationIterBimodal::avg_saturation(int start, int end)
{
int i;
int value;
int sum;
int counter;
int result;
sum = 1;
counter = 1;
for (i = start; i <= end; i++)
{
// Get value
value = hg->value(i);
sum += value;
counter += value * i;
}
result = counter / sum;
return result;
}

View File

@ -3,6 +3,7 @@
#include "transformation.h"
class BinarizationIterBimodal : public Transformation
{
public:
@ -10,6 +11,10 @@ public:
BinarizationIterBimodal(PNM*, ImageViewer*);
virtual PNM* transform();
QHash<int, int> * hg;
int avg_saturation(int, int);
};
#endif // BIN_ITERBIMODAL_H

View File

@ -19,7 +19,23 @@ PNM* BinarizationManual::transform()
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
// Iterate over pixels
for (int x=0; x < width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
if(qGray(pixel) > threshold)
{
newImage->setPixel(x, y, Qt::color1);
}
else
{
newImage->setPixel(x, y, Qt::color0);
}
}
}
return newImage;
}

View File

@ -1,4 +1,5 @@
#include "bin_niblack.h"
#include "transformation.h"
BinarizationNiblack::BinarizationNiblack(PNM* img) :
Transformation(img)
@ -18,9 +19,51 @@ PNM* BinarizationNiblack::transform()
int r = getParameter("r").toInt();
double a = getParameter("a").toDouble();
double arithmetic_mean = 0;
double variance = 0;
double standard_deviation = 0;
math::matrix<float> window;
int T;
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
for (int x=0; x < width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
//Get current window
window = getWindow(x, y, r, LChannel, RepeatEdge);
// Calculate arithmetic mean
arithmetic_mean = window.sum() / pow(r, 2);
// Calculate standard_deviation
for (int i = 0; i < r+1; i++){
for (int j = 0; i < r+1; i++){
variance += pow(window[i][j] - arithmetic_mean, 2);
}
}
variance /= pow(r, 2);
standard_deviation = sqrt(variance);
// Calculate threshold T
T = arithmetic_mean + a * standard_deviation;
if(qGray(pixel) > T)
{
newImage->setPixel(x, y, Qt::color1);
}
else
{
newImage->setPixel(x, y, Qt::color0);
}
}
}
return newImage;
}

View File

@ -19,8 +19,106 @@ PNM* BinarizationOtsu::transform()
int height = image->height();
PNM* newImage = new PNM(width, height, QImage::Format_Mono);
HistogramEqualization* equalized_histogram = new HistogramEqualization(image);
QHash<int, int> * hg;
// Number od pixels in image
int N = width * height;
image = equalized_histogram->transform();
// Histogram table
hg = image->getHistogram()->get(Histogram::LChannel);
int value;
double bcv[256];
int sum_1 = 0;
int sum2 = 0;
double u_b;
double u_f;
double W_b;
double W_f;
for (int t=0; t < 255; t++)
{
for (int j=0; j < t; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum_1 += value;
}
W_b = sum_1 / pow(255, 2);
for (int j=0; j < t; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum2 += value * j;
}
if (sum_1 == 0)
{
u_b = 0;
}
else
{
u_b = sum2 / sum_1;
}
sum_1 = 0;
sum2 = 0;
for (int j=t; j < 255; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum_1 += value;
}
W_f = sum_1 / pow(255, 2);
for (int j=t; j < 255; j++)
{
value = image->getHistogram()->get(Histogram::LChannel)->value(j);
sum2 += value * j;
}
if (sum_1 == 0)
{
u_f = 0;
}
else
{
u_f = sum2 / sum_1;
}
bcv[t]= W_b * W_f * pow(u_b - u_f, 2);
}
int T = 0;
for (int j=0; j< 255;j++)
{
if (bcv[j] > bcv[T])
{
T=j;
}
}
// Iterate over pixels
for (int x=0; x<width; x++)
{
for (int y=0; y < height; y++)
{
// Get current pixel
QRgb pixel = image->pixel(x, y);
int l = qGray(pixel);
newImage->setPixel(x,y, l < T ? Qt::color0 : Qt::color1);
}
}
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
return newImage;
}