1
0

Zadanie 9

This commit is contained in:
Jarosław Wieczorek 2021-04-06 23:29:35 +02:00
parent e1cc7ef031
commit fe76bebf75
10 changed files with 331 additions and 14 deletions

View File

@ -0,0 +1,55 @@
#include "edge_sobel.h"
#include <iostream>
EdgeSobel::EdgeSobel(PNM* img, ImageViewer* iv) :
EdgeGradient(img, iv)
{
prepareMatrices();
}
EdgeSobel::EdgeSobel(PNM* img) :
EdgeGradient(img)
{
prepareMatrices();
}
void EdgeSobel::prepareMatrices()
{
g_x = math::matrix<float>(3, 3, {-1, 0, 1, -2, 0, 2, -1, 0, 1});
g_y = math::matrix<float>(3, 3, {-1, -2, -1, 0, 0, 0, 1, 2, 1});
}
math::matrix<float>* EdgeSobel::rawHorizontalDetection()
{
int width = image->width();
int height = image->height();
math::matrix<float>* x_gradient = new math::matrix<float>(width, height);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
(*x_gradient)(i, j) = sum(join(g_x, getWindow(i, j, 3, LChannel, RepeatEdge)));
}
}
return x_gradient;
}
math::matrix<float>* EdgeSobel::rawVerticalDetection()
{
int width = image->width();
int height = image->height();
math::matrix<float>* y_gradient = new math::matrix<float>(width, height);
math::matrix<float> window;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
(*y_gradient)(i, j) = sum(join(g_y, getWindow(i, j, 3, LChannel, RepeatEdge)));
}
}
return y_gradient;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,24 @@
#include "map_height.h"
#include "conversion_grayscale.h"
MapHeight::MapHeight(PNM* img) :
Transformation(img)
{
}
MapHeight::MapHeight(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* MapHeight::transform()
{
int width = image->width();
int height = image->height();
PNM* newImage = new PNM(width, height, image->format());
ConversionGrayscale* grayscale = new ConversionGrayscale(image);
newImage = grayscale->transform();
return newImage;
}

View File

@ -0,0 +1,83 @@
#include "map_horizon.h"
#include "map_height.h"
MapHorizon::MapHorizon(PNM* img) :
Transformation(img)
{
}
MapHorizon::MapHorizon(PNM* img, ImageViewer* iv) :
Transformation(img, iv)
{
}
PNM* MapHorizon::transform()
{
int width = image->width(),
height = image->height();
double scale = getParameter("scale").toDouble();
int sun_alpha = getParameter("alpha").toInt();
int dx, dy;
switch (getParameter("direction").toInt())
{
case NORTH: dx = 0; dy = -1; break;
case SOUTH: dx = 0; dy = 1; break;
case EAST: dx = 1; dy = 0; break;
case WEST: dx = -1; dy = 0; break;
default:
qWarning() << "Unknown direction!";
dx = 0;
dy = -1;
}
PNM* newImage = new PNM(width, height, image->format());
MapHeight* mapHeight = new MapHeight(image);
image = mapHeight->transform();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
double alpha = 0;
int current_h = qGray(image->pixel(i, j));
for (int k = i + dx, l = j + dy; k < width && l < height && k >= 0 && l >= 0; k = k + dx, l = l + dy)
{
int ray_h = qGray(image->pixel(k, l));
if (current_h < ray_h)
{
double dist = sqrt(pow(k - i, 2) + pow(l - j, 2)) * scale;
double ray_alpha = atan((ray_h - current_h) / dist);
if (ray_alpha > alpha)
{
alpha = ray_alpha;
}
}
}
double delta = alpha - sun_alpha * M_PI / 180;
if (delta > 0)
{
double val = cos(delta) * 255;
QColor color = QColor(val, val, val);
newImage->setPixel(i, j, color.rgb());
}
else
{
QColor color = QColor(255, 255, 255);
newImage->setPixel(i, j, color.rgb());
}
}
}
return newImage;
}

View File

@ -0,0 +1,61 @@
#include "map_normal.h"
#include "edge_sobel.h"
#include "map_height.h"
#include <iostream>
MapNormal::MapNormal(PNM* img) :
Convolution(img)
{
}
MapNormal::MapNormal(PNM* img, ImageViewer* iv) :
Convolution(img, iv)
{
}
PNM* MapNormal::transform()
{
int width = image->width();
int height = image->height();
// The power constant of the generated normal map.
double strength = getParameter("strength").toDouble();
PNM* newImage = new PNM(width, height, image->format());
MapHeight* mh = new MapHeight(image);
PNM* image = mh->transform();
EdgeSobel* es = new EdgeSobel(image);
math::matrix<float>* Gx = es->rawHorizontalDetection();
math::matrix<float>* Gy = es->rawVerticalDetection();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
// For each pixel (i,j), determine the coordinates of the vector d
float dx = (*Gx)(i, j) / 255;
float dy = (*Gy)(i, j) / 255;
float dz = 1.0 / strength;
// Normalise the vector d
double dw = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2));
// Scale these values to the interval
dx = dx / dw;
dy = dy / dw;
dz = dz / dw;
dx = (dx + 1.0) * (255 / strength);
dy = (dy + 1.0) * (255 / strength);
dz = (dz + 1.0) * (255 / strength);
QColor newPixel = QColor(dx, dy, dz);
newImage->setPixel(i, j, newPixel.rgb());
}
}
return newImage;
}

View File

@ -1,4 +1,5 @@
#include "edge_sobel.h" #include "edge_sobel.h"
#include <iostream>
EdgeSobel::EdgeSobel(PNM* img, ImageViewer* iv) : EdgeSobel::EdgeSobel(PNM* img, ImageViewer* iv) :
EdgeGradient(img, iv) EdgeGradient(img, iv)
@ -20,18 +21,35 @@ void EdgeSobel::prepareMatrices()
math::matrix<float>* EdgeSobel::rawHorizontalDetection() math::matrix<float>* EdgeSobel::rawHorizontalDetection()
{ {
math::matrix<float>* x_gradient = new math::matrix<float>(this->image->width(), this->image->height()); int width = image->width();
int height = image->height();
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; math::matrix<float>* x_gradient = new math::matrix<float>(width, height);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
(*x_gradient)(i, j) = sum(join(g_x, getWindow(i, j, 3, LChannel, RepeatEdge)));
}
}
return x_gradient; return x_gradient;
} }
math::matrix<float>* EdgeSobel::rawVerticalDetection() math::matrix<float>* EdgeSobel::rawVerticalDetection()
{ {
math::matrix<float>* y_gradient = new math::matrix<float>(this->image->width(), this->image->height()); int width = image->width();
int height = image->height();
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; math::matrix<float>* y_gradient = new math::matrix<float>(width, height);
math::matrix<float> window;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
(*y_gradient)(i, j) = sum(join(g_y, getWindow(i, j, 3, LChannel, RepeatEdge)));
}
}
return y_gradient; return y_gradient;
} }

View File

@ -1,4 +1,5 @@
#include "map_height.h" #include "map_height.h"
#include "conversion_grayscale.h"
MapHeight::MapHeight(PNM* img) : MapHeight::MapHeight(PNM* img) :
Transformation(img) Transformation(img)
@ -12,12 +13,12 @@ MapHeight::MapHeight(PNM* img, ImageViewer* iv) :
PNM* MapHeight::transform() PNM* MapHeight::transform()
{ {
int width = image->width(), int width = image->width();
height = image->height(); int height = image->height();
PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8); PNM* newImage = new PNM(width, height, image->format());
ConversionGrayscale* grayscale = new ConversionGrayscale(image);
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
newImage = grayscale->transform();
return newImage; return newImage;
} }

View File

@ -33,9 +33,51 @@ PNM* MapHorizon::transform()
dy = -1; dy = -1;
} }
PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8); PNM* newImage = new PNM(width, height, image->format());
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; MapHeight* mapHeight = new MapHeight(image);
image = mapHeight->transform();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
double alpha = 0;
int current_h = qGray(image->pixel(i, j));
for (int k = i + dx, l = j + dy; k < width && l < height && k >= 0 && l >= 0; k = k + dx, l = l + dy)
{
int ray_h = qGray(image->pixel(k, l));
if (current_h < ray_h)
{
double dist = sqrt(pow(k - i, 2) + pow(l - j, 2)) * scale;
double ray_alpha = atan((ray_h - current_h) / dist);
if (ray_alpha > alpha)
{
alpha = ray_alpha;
}
}
}
double delta = alpha - sun_alpha * M_PI / 180;
if (delta > 0)
{
double val = cos(delta) * 255;
QColor color = QColor(val, val, val);
newImage->setPixel(i, j, color.rgb());
}
else
{
QColor color = QColor(255, 255, 255);
newImage->setPixel(i, j, color.rgb());
}
}
}
return newImage; return newImage;
} }

View File

@ -2,6 +2,7 @@
#include "edge_sobel.h" #include "edge_sobel.h"
#include "map_height.h" #include "map_height.h"
#include <iostream>
MapNormal::MapNormal(PNM* img) : MapNormal::MapNormal(PNM* img) :
Convolution(img) Convolution(img)
@ -15,14 +16,46 @@ MapNormal::MapNormal(PNM* img, ImageViewer* iv) :
PNM* MapNormal::transform() PNM* MapNormal::transform()
{ {
int width = image->width(), int width = image->width();
height = image->height(); int height = image->height();
// The power constant of the generated normal map.
double strength = getParameter("strength").toDouble(); double strength = getParameter("strength").toDouble();
PNM* newImage = new PNM(width, height, image->format()); PNM* newImage = new PNM(width, height, image->format());
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; MapHeight* mh = new MapHeight(image);
PNM* image = mh->transform();
EdgeSobel* es = new EdgeSobel(image);
math::matrix<float>* Gx = es->rawHorizontalDetection();
math::matrix<float>* Gy = es->rawVerticalDetection();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
// For each pixel (i,j), determine the coordinates of the vector d
float dx = (*Gx)(i, j) / 255;
float dy = (*Gy)(i, j) / 255;
float dz = 1.0 / strength;
// Normalise the vector d
double dw = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2));
// Scale these values to the interval
dx = dx / dw;
dy = dy / dw;
dz = dz / dw;
dx = (dx + 1.0) * (255 / strength);
dy = (dy + 1.0) * (255 / strength);
dz = (dz + 1.0) * (255 / strength);
QColor newPixel = QColor(dx, dy, dz);
newImage->setPixel(i, j, newPixel.rgb());
}
}
return newImage; return newImage;
} }