Zadanie 4
This commit is contained in:
parent
f1744a95c9
commit
b778d1bbd7
46
04/do_sprawdzenia/cpp/blur_gaussian.cpp
Normal file
46
04/do_sprawdzenia/cpp/blur_gaussian.cpp
Normal 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)));
|
||||
|
||||
}
|
||||
|
40
04/do_sprawdzenia/cpp/blur_linear.cpp
Normal file
40
04/do_sprawdzenia/cpp/blur_linear.cpp
Normal 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);
|
||||
}
|
25
04/do_sprawdzenia/cpp/blur_uniform.cpp
Normal file
25
04/do_sprawdzenia/cpp/blur_uniform.cpp
Normal 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;
|
||||
}
|
173
04/do_sprawdzenia/cpp/convolution.cpp
Normal file
173
04/do_sprawdzenia/cpp/convolution.cpp
Normal 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;
|
||||
}
|
@ -25,15 +25,22 @@ math::matrix<float> BlurGaussian::getMask(int size, Mode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,23 @@ PNM* BlurLinear::transform()
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -14,7 +14,12 @@ math::matrix<float> BlurUniform::getMask(int size, Mode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -22,8 +22,24 @@ math::matrix<float> Convolution::getMask(int size, Mode mode = Normalize)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -35,8 +51,66 @@ PNM* Convolution::convolute(math::matrix<float> mask, Mode mode = RepeatEdge)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -48,7 +122,15 @@ const math::matrix<float> Convolution::join(math::matrix<float> A, math::matrix<
|
||||
int size = A.rowno();
|
||||
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;
|
||||
}
|
||||
@ -58,10 +140,17 @@ const float Convolution::sum(const math::matrix<float> A)
|
||||
{
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +160,14 @@ const math::matrix<float> Convolution::reflection(const math::matrix<float> A)
|
||||
int size = A.rowno();
|
||||
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;
|
||||
}
|
||||
|
@ -103,8 +103,14 @@ QRgb Transformation::getPixel(int x, int y, Mode mode)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@ -114,8 +120,15 @@ QRgb Transformation::getPixelCyclic(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);
|
||||
}
|
||||
|
||||
@ -126,7 +139,19 @@ QRgb Transformation::getPixelNull(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);
|
||||
}
|
||||
@ -138,8 +163,33 @@ math::matrix<float> Transformation::getWindow(int x, int y, int 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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user