1
0

Zadanie 4

This commit is contained in:
Jarosław Wieczorek 2021-03-20 17:56:06 +01:00
parent f1744a95c9
commit b778d1bbd7
9 changed files with 474 additions and 16 deletions

View File

@ -0,0 +1,46 @@
#include "blur_gaussian.h"
BlurGaussian::BlurGaussian(PNM* img) :
Convolution(img)
{
}
BlurGaussian::BlurGaussian(PNM* img, ImageViewer* iv) :
Convolution(img, iv)
{
}
PNM* BlurGaussian::transform()
{
emit message("Blurring...");
int size = getParameter("size").toInt();
radius = (size/2)+1;
sigma = getParameter("sigma").toDouble();
return convolute(getMask(size, Normalize), RepeatEdge);
}
math::matrix<float> BlurGaussian::getMask(int size, Mode)
{
math::matrix<float> mask(size, size);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
mask(i,j) = getGauss(i-radius, j-radius, sigma);
}
}
return mask;
}
float BlurGaussian::getGauss(int x, int y, float sigma)
{
// Calculate a two-dimensional Gaussian function:
return (1 / (2 * M_PI * pow(sigma, 2))) * exp(-(pow(x, 2) + pow(y, 2)) / (2 * pow(sigma, 2)));
}

View File

@ -0,0 +1,40 @@
#include "blur_linear.h"
BlurLinear::BlurLinear(PNM* img) :
Convolution(img)
{
}
BlurLinear::BlurLinear(PNM* img, ImageViewer* iv) :
Convolution(img, iv)
{
}
PNM* BlurLinear::transform()
{
int maskSize = getParameter("size").toInt();
QList<QVariant> tmpMask = getParameter("mask").toList();
bool normalize = getParameter("normalize").toBool();
math::matrix<float> mask(maskSize, maskSize);
int maskValCount = 0;
for (int i=0; i < maskSize; i++)
{
for (int j=0; j < maskSize; j++)
{
if (normalize)
{
mask[i][j] = tmpMask.at(maskValCount).toDouble() / Convolution::sum(mask);
maskValCount++;
}
else
{
mask[i][j] = tmpMask.at(maskValCount).toDouble();
maskValCount++;
}
}
}
return convolute(mask, RepeatEdge);
}

View File

@ -0,0 +1,25 @@
#include "blur_uniform.h"
BlurUniform::BlurUniform(PNM* img) :
Convolution(img)
{
}
BlurUniform::BlurUniform(PNM* img, ImageViewer* iv) :
Convolution(img, iv)
{
}
math::matrix<float> BlurUniform::getMask(int size, Mode)
{
math::matrix<float> mask(size, size);
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
mask[i][j] = 1;
}
}
return mask;
}

View File

@ -0,0 +1,173 @@
#include "convolution.h"
/** Overloaded constructor */
Convolution::Convolution(PNM* img) :
Transformation(img)
{
}
Convolution::Convolution(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
/** Returns a convoluted form of the image */
PNM* Convolution::transform()
{
return convolute(getMask(3, Normalize), RepeatEdge);
}
/** Returns a sizeXsize matrix with the center point equal 1.0 */
math::matrix<float> Convolution::getMask(int size, Mode mode = Normalize)
{
math::matrix<float> mask(size, size);
// Get center of image
int center = size/2;
// Get mask
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
if (i==j && i == center && j == center)
{
mask[i][j] = 1;
}
else
{
mask[i][j] = 0;
}
}
}
return mask;
}
/** Does the convolution process for all pixels using the given mask. */
PNM* Convolution::convolute(math::matrix<float> mask, Mode mode = RepeatEdge)
{
int width = image->width(),
height = image->height();
PNM* newImage = new PNM(width, height, image->format());
float weight = Convolution::sum(mask);
math::matrix<float> reflection = Convolution::reflection(mask);
for (int x=0; x < width ; x++)
{
for (int y=0; y < height; y++)
{
math::matrix<float> rAcc = Convolution::join(getWindow(x, y, mask.rowno(), Transformation::RChannel, mode), reflection);
math::matrix<float> gAcc = Convolution::join(getWindow(x, y, mask.rowno(), Transformation::GChannel, mode), reflection);
math::matrix<float> bAcc = Convolution::join(getWindow(x, y, mask.rowno(), Transformation::BChannel, mode), reflection);
float rAccSum = Convolution::sum(rAcc);
float gAccSum = Convolution::sum(gAcc);
float bAccSum = Convolution::sum(bAcc);
if (weight != 0)
{
rAccSum = rAccSum / weight;
gAccSum = gAccSum / weight;
bAccSum = bAccSum / weight;
}
// Calculate Red Accumulate Sum
if (rAccSum < 0)
{
rAccSum = 0;
}
else if (rAccSum > 255)
{
rAccSum = 255;
}
// Calculate Green Accumulate Sum
if (gAccSum < 0)
{
gAccSum = 0;
}
else if (gAccSum > 255)
{
gAccSum = 255;
}
// Calculate Blue Accumulate Sum
if (bAccSum < 0)
{
bAccSum = 0;
}
else if(bAccSum > 255)
{
bAccSum = 255;
}
// Create pixel
QColor newPixel = QColor(rAccSum, gAccSum, bAccSum);
// Set pixel
newImage->setPixel(x,y, newPixel.rgb());
}
}
return newImage;
}
/** Joins to matrices by multiplying the A[i,j] with B[i,j].
* Warning! Both Matrices must be squares with the same size!
*/
const math::matrix<float> Convolution::join(math::matrix<float> A, math::matrix<float> B)
{
int size = A.rowno();
math::matrix<float> C(size, size);
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
// Multiplication
C[i][j] = A[i][j] * B[i][j];
}
}
return C;
}
/** Sums all of the matrixes elements */
const float Convolution::sum(const math::matrix<float> A)
{
float sum = 0.0;
int size = A.rowno();
for (int i=0; i<size; i++)
{
for (int j=0; j<size; j++)
{
// Summation
sum = sum + A[i][j];
}
}
return sum;
}
/** Returns reflected version of a matrix */
const math::matrix<float> Convolution::reflection(const math::matrix<float> A)
{
int size = A.rowno();
math::matrix<float> C(size, size);
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
C[i][j] = A[size-i-1][size-j-1];
}
}
return C;
}

View File

@ -25,15 +25,22 @@ math::matrix<float> BlurGaussian::getMask(int size, Mode)
{ {
math::matrix<float> mask(size, size); math::matrix<float> mask(size, size);
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
mask(i,j) = getGauss(i-radius, j-radius, sigma);
}
}
return mask; return mask;
} }
float BlurGaussian::getGauss(int x, int y, float sigma) float BlurGaussian::getGauss(int x, int y, float sigma)
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; // Calculate a two-dimensional Gaussian function:
return (1 / (2 * M_PI * pow(sigma, 2))) * exp(-(pow(x, 2) + pow(y, 2)) / (2 * pow(sigma, 2)));
return 0;
} }

View File

@ -18,7 +18,23 @@ PNM* BlurLinear::transform()
math::matrix<float> mask(maskSize, maskSize); math::matrix<float> mask(maskSize, maskSize);
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int maskValCount = 0;
for (int i=0; i < maskSize; i++)
{
for (int j=0; j < maskSize; j++)
{
if (normalize)
{
mask[i][j] = tmpMask.at(maskValCount).toDouble() / Convolution::sum(mask);
maskValCount++;
}
else
{
mask[i][j] = tmpMask.at(maskValCount).toDouble();
maskValCount++;
}
}
}
return convolute(mask, RepeatEdge); return convolute(mask, RepeatEdge);
} }

View File

@ -14,7 +14,12 @@ math::matrix<float> BlurUniform::getMask(int size, Mode)
{ {
math::matrix<float> mask(size, size); math::matrix<float> mask(size, size);
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
mask[i][j] = 1;
}
}
return mask; return mask;
} }

View File

@ -22,8 +22,24 @@ math::matrix<float> Convolution::getMask(int size, Mode mode = Normalize)
{ {
math::matrix<float> mask(size, size); math::matrix<float> mask(size, size);
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; // Get center of image
int center = size/2;
// Get mask
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
if (i==j && i == center && j == center)
{
mask[i][j] = 1;
}
else
{
mask[i][j] = 0;
}
}
}
return mask; return mask;
} }
@ -35,8 +51,66 @@ PNM* Convolution::convolute(math::matrix<float> mask, Mode mode = RepeatEdge)
PNM* newImage = new PNM(width, height, image->format()); PNM* newImage = new PNM(width, height, image->format());
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; float weight = Convolution::sum(mask);
math::matrix<float> reflection = Convolution::reflection(mask);
for (int x=0; x < width ; x++)
{
for (int y=0; y < height; y++)
{
math::matrix<float> rAcc = Convolution::join(getWindow(x, y, mask.rowno(), Transformation::RChannel, mode), reflection);
math::matrix<float> gAcc = Convolution::join(getWindow(x, y, mask.rowno(), Transformation::GChannel, mode), reflection);
math::matrix<float> bAcc = Convolution::join(getWindow(x, y, mask.rowno(), Transformation::BChannel, mode), reflection);
float rAccSum = Convolution::sum(rAcc);
float gAccSum = Convolution::sum(gAcc);
float bAccSum = Convolution::sum(bAcc);
if (weight != 0)
{
rAccSum = rAccSum / weight;
gAccSum = gAccSum / weight;
bAccSum = bAccSum / weight;
}
// Calculate Red Accumulate Sum
if (rAccSum < 0)
{
rAccSum = 0;
}
else if (rAccSum > 255)
{
rAccSum = 255;
}
// Calculate Green Accumulate Sum
if (gAccSum < 0)
{
gAccSum = 0;
}
else if (gAccSum > 255)
{
gAccSum = 255;
}
// Calculate Blue Accumulate Sum
if (bAccSum < 0)
{
bAccSum = 0;
}
else if(bAccSum > 255)
{
bAccSum = 255;
}
// Create pixel
QColor newPixel = QColor(rAccSum, gAccSum, bAccSum);
// Set pixel
newImage->setPixel(x,y, newPixel.rgb());
}
}
return newImage; return newImage;
} }
@ -48,7 +122,15 @@ const math::matrix<float> Convolution::join(math::matrix<float> A, math::matrix<
int size = A.rowno(); int size = A.rowno();
math::matrix<float> C(size, size); math::matrix<float> C(size, size);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
// Multiplication
C[i][j] = A[i][j] * B[i][j];
}
}
return C; return C;
} }
@ -58,10 +140,17 @@ const float Convolution::sum(const math::matrix<float> A)
{ {
float sum = 0.0; float sum = 0.0;
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int size = A.rowno();
for (int i=0; i<size; i++)
{
for (int j=0; j<size; j++)
{
// Summation
sum = sum + A[i][j];
}
}
return sum; return sum;
} }
@ -71,7 +160,14 @@ const math::matrix<float> Convolution::reflection(const math::matrix<float> A)
int size = A.rowno(); int size = A.rowno();
math::matrix<float> C(size, size); math::matrix<float> C(size, size);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
C[i][j] = A[size-i-1][size-j-1];
}
}
return C; return C;
} }

View File

@ -103,8 +103,14 @@ QRgb Transformation::getPixel(int x, int y, Mode mode)
*/ */
QRgb Transformation::getPixelCyclic(int x, int y) QRgb Transformation::getPixelCyclic(int x, int y)
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int width = image->width();
int height = image->height();
// Return a pixel by looping the image
x = x % width;
y = y % height;
// Return pixel
return image->pixel(x,y); return image->pixel(x,y);
} }
@ -114,8 +120,15 @@ QRgb Transformation::getPixelCyclic(int x, int y)
*/ */
QRgb Transformation::getPixelNull(int x, int y) QRgb Transformation::getPixelNull(int x, int y)
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int width = image->width();
int height = image->height();
// Return black as a pixel when out of range
if (x > width || x < 0 || y > height || y < 0){
return Qt::black;
}
// Return pixel
return image->pixel(x,y); return image->pixel(x,y);
} }
@ -126,7 +139,19 @@ QRgb Transformation::getPixelNull(int x, int y)
*/ */
QRgb Transformation::getPixelRepeat(int x, int y) QRgb Transformation::getPixelRepeat(int x, int y)
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int width = image->width();
int height = image->height();
// Copy nearest edge pixel
if (x<0 && y<0) return image->pixel(0,0);
else if (x>=width && y<0) return image->pixel(width-1,0);
else if (x>=width && y>=height) return image->pixel(width-1,height-1);
else if (x<0 && y>=height) return image->pixel(0,height-1);
else if (x<0) return image->pixel(0,y);
else if (y<0) return image->pixel(x,0);
else if (x>=width) return image->pixel(width-1,y);
else if (y>=height) return image->pixel(x,height-1);
else return image->pixel(x,y);
return image->pixel(x,y); return image->pixel(x,y);
} }
@ -138,8 +163,33 @@ math::matrix<float> Transformation::getWindow(int x, int y, int size,
{ {
math::matrix<float> window(size,size); math::matrix<float> window(size,size);
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; // Calculate center
int center = size/2;
// Get window
for (int i=0; i < size; i++)
{
for (int j=0; j < size; j++)
{
QRgb pixelVal = getPixel(x-center+i, y-center+j, mode);
if (channel == RChannel)
{
window[i][j] = qRed(pixelVal);
}
else if (channel == GChannel)
{
window[i][j] = qGreen(pixelVal);
}
else if (channel == BChannel)
{
window[i][j] = qBlue(pixelVal);
}
else if (channel == LChannel)
{
window[i][j] = qGray(pixelVal);
}
}
}
return window; return window;
} }