zadanie - 13 (segmentacja)

This commit is contained in:
Patrycjusz Mania 2021-06-23 20:20:06 +02:00
parent 1e1c4c2a5e
commit 151ca36c2c
2 changed files with 194 additions and 4 deletions

View File

@ -22,9 +22,56 @@ PNM* HoughLines::transform()
int threshold = getParameter("threshold").toInt(); int threshold = getParameter("threshold").toInt();
bool drawWholeLines = getParameter("draw_whole_lines").toBool(); bool drawWholeLines = getParameter("draw_whole_lines").toBool();
PNM* newImage = new PNM(image->copy()); PNM* newImage = new PNM(image->width(), image->height(), QImage::Format_Mono);
newImage->fill(Qt::color1);
int width = image->width();
int height = image->height();
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; EdgeLaplacian edgeLaplacian(image);
edgeLaplacian.setParameter("size", 3);
PNM* laplacianImage = edgeLaplacian.transform();
BinarizationGradient binarizationGradient(laplacianImage);
PNM* binaryImage = binarizationGradient.transform();
Hough hough(binaryImage);
hough.setParameter("theta_density", 3);
hough.setParameter("skip_edge_detection", true);
PNM* houghImage = hough.transform();
int theta = houghImage->width();
int p = houghImage->height();
QPainter* qPainter = new QPainter(newImage);
qPainter->setPen(Qt::color1);
for (int x = 0; x < theta; x++)
for (int y = 0; y < p; y++) {
QRgb pixel = houghImage->pixel(x,y);
int v = qGray(pixel);
if (v > threshold) {
int r = y - p/2;
float rTheta = (x/3.0)*M_PI / 180.0;
float sinTheta = sin(rTheta);
float cosTheta = cos(rTheta);
int x1 = 0;
int y1 = r/sinTheta;
int x2 = width - 1;
int y2 = (r - (width-1) * cosTheta)/sinTheta;
QLine line = QLine(x1, y1, x2, y2);
qPainter->drawLine(line);
}
}
if (!drawWholeLines) {
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
if (qGray(binaryImage->pixel(x,y)) == 0)
newImage->setPixel(x,y,Qt::color0);
}
}
return newImage; return newImage;
} }

View File

@ -2,6 +2,7 @@
#include "conversion_grayscale.h" #include "conversion_grayscale.h"
#include "blur_gaussian.h" #include "blur_gaussian.h"
#include "blur_uniform.h"
#include <queue> #include <queue>
@ -28,7 +29,149 @@ QPoint* Segmentation::neighbourhood(QPoint p)
PNM* Segmentation::transform() PNM* Segmentation::transform()
{ {
qDebug() << Q_FUNC_INFO << "Not implemented yet!"; int width = image->width();
int height = image->height();
return 0; PNM* newImage = new PNM(width, height, QImage::Format_RGB32);
ConversionGrayscale conversionGrayscale(image);
PNM* grayImage = conversionGrayscale.transform();
BlurUniform blur(grayImage);
grayImage = blur.transform();
math::matrix<int> lab (width, height);
math::matrix<int> dist (width, height);
int curlab = 0;
std::queue<QPoint> fifo;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
lab[i][j] = INIT;
dist[i][j] = 0;
}
}
std::list<int> hSorted;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
hSorted.push_back(qGray(grayImage->pixel(i,j)));
}
}
hSorted.sort();
hSorted.unique();
int curDist = 0;
for (std::list<int>::iterator h = hSorted.begin(); h != hSorted.end(); h++) {
for (int p_i = 0; p_i < width; p_i++) {
for (int p_j = 0; p_j < height; p_j++) {
if (qGray(image->pixel(p_i,p_j)) == *h) {
lab[p_i][p_j] = MASK;
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
if (x != 0 || y !=0) {
int q_i = p_i+x;
int q_j = p_j+y;
if (q_i >= 0 && q_j >= 0 && q_i < width && q_j < height) {
if (lab[q_i][q_j] > 0 || lab[q_i][q_j] == WSHED) {
dist[p_i][p_j] = 1;
fifo.push(QPoint(p_i,p_j));
}
}
}
}
}
}
}
}
curDist = 1;
fifo.push(QPoint(-1,-1));
while(true) {
QPoint p = fifo.front();
fifo.pop();
if (p.x() == -1 && p.y()==-1) {
if (fifo.empty()) {
break;
} else {
fifo.push(QPoint(-1, -1));
curDist += 1;
p = fifo.front();
fifo.pop();
}
}
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
if (x != 0 || y != 0) {
int p_i = p.x();
int p_j = p.y();
int q_i = p_i + x;
int q_j = p_j + y;
if (q_i >= 0 && q_j >= 0 && q_i < width && q_j < height) {
if ((dist[q_i][q_j] < curDist) && (lab[q_i][q_j] > 0 || lab[q_i][q_j] == WSHED)) {
if (lab[q_i][q_j] > 0) {
if (lab[p_i][p_j] == MASK or lab[p_i][p_j] == WSHED) {
lab[p_i][p_j] = lab[q_i][q_j];
} else if (lab[p_i][p_j] != lab[q_i][q_j]) {
lab[p_i][p_j] = WSHED;
}
} else if (lab[p_i][p_j] == MASK) {
lab[p_i][p_j] = WSHED;
}
} else if (lab[q_i][q_j] == MASK && dist[q_i][q_j] == 0) {
dist[q_i][q_j] = curDist + 1;
fifo.push(QPoint(q_i,q_j));
}
}
}
}
}
}
for (int p_i = 0; p_i < width; p_i++) {
for (int p_j = 0; p_j < height; p_j++) {
if (qGray(image->pixel(p_i,p_j)) == *h) {
dist[p_i][p_j] = 0;
if (lab[p_i][p_j] == MASK) {
curlab += 1;
fifo.push(QPoint(p_i,p_j));
lab[p_i][p_j] = curlab;
while (!fifo.empty()) {
QPoint q = fifo.front();
fifo.pop();
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
if (x != 0 || y != 0) {
int q_i = q.x();
int q_j = q.y();
int r_i = q_i + x;
int r_j = q_j + y;
if (r_i >= 0 && r_j >= 0 && r_i < width && r_j < height) {
if (lab[r_i][r_j] == MASK) {
fifo.push(QPoint(r_i, r_j));
lab[r_i][r_j] = curlab;
}
}
}
}
}
}
}
}
}
}
}
float max = lab.max();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int value = (lab[i][j]) * 255.0/max;
int color = QColor(value, value, value).rgb();
newImage->setPixel(i, j, color);
}
}
return newImage;
} }