From 37c653d065d07693113739e32e487f8534e57ae2 Mon Sep 17 00:00:00 2001 From: Dawid Pietrykowski Date: Tue, 2 May 2023 20:43:57 +0200 Subject: [PATCH] WIP Morphology --- QT/morphology/f.png | Bin 0 -> 7239 bytes QT/morphology/main.cpp | 33 ++++ QT/morphology/morphology.pro | 20 +++ QT/morphology/mywindow.cpp | 313 +++++++++++++++++++++++++++++++++++ QT/morphology/mywindow.h | 136 +++++++++++++++ QT/morphology/mywindow.ui | 141 ++++++++++++++++ QT/morphology/p.png | Bin 0 -> 9808 bytes 7 files changed, 643 insertions(+) create mode 100644 QT/morphology/f.png create mode 100644 QT/morphology/main.cpp create mode 100644 QT/morphology/morphology.pro create mode 100644 QT/morphology/mywindow.cpp create mode 100644 QT/morphology/mywindow.h create mode 100644 QT/morphology/mywindow.ui create mode 100644 QT/morphology/p.png diff --git a/QT/morphology/f.png b/QT/morphology/f.png new file mode 100644 index 0000000000000000000000000000000000000000..4557e758a1022a984f6c78b5360b981101863218 GIT binary patch literal 7239 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 V#p002ovPDHLkV1mO<7CZm| literal 0 HcmV?d00001 diff --git a/QT/morphology/main.cpp b/QT/morphology/main.cpp new file mode 100644 index 0000000..2a67e1f --- /dev/null +++ b/QT/morphology/main.cpp @@ -0,0 +1,33 @@ +// Glowny plik aplikacji, utworzony automatycznie przez QtCreator +// W wiekszosci przypadkow nie musimy tu nic zmieniac + +// Dolaczamy plik naglowkowy klasy QApplication +#include + +// Dolaczamy plik naglowkowy klasy glownego widgetu (okna) aplikacji +#include "mywindow.h" + +int main(int argc, char *argv[]) +{ + + // Tworzymy objekt QApplication. Zarzadza on zasobami calej aplikacji + // i jest niezbedny do stworzenia jakiejkolwiek aplikacji Qt posiadajacej GUI. + // Przekazujemy mu dwa argumenty argc i argv, poniewaz Qt moze rowniez + // przyjmowac argumenty z linii komend. + QApplication a(argc, argv); + + // Tworzymy obiekt klasy MyWindow - glownego okna naszej aplikacji. + // Jest to klasa zdefiniowana przez nas. + // Jej definicja znajduje sie w plikach mainwindow.h i mainwindow.cpp + MyWindow w; + +// w.setMouseTracking(true); + // Pokazujemy glowne okno aplikacji na ekranie. Domyslnie jest ono niewidoczne. + // Wszystkie widgety (elementy GUI) zawarte w glownym oknie beda rowniez widoczne. + w.show(); + + // Przekazujemy kontrole nad aplikacja do Qt. Program wchodzi w petle zdarzen + // tzn. zaczyna oczekiwac na akcje uzytkownika - klikniecia przycisku myszy, + // lub klawisza klawiatury itp. + return a.exec(); +} diff --git a/QT/morphology/morphology.pro b/QT/morphology/morphology.pro new file mode 100644 index 0000000..cf7f4b0 --- /dev/null +++ b/QT/morphology/morphology.pro @@ -0,0 +1,20 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-03-03T00:14:51 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = morphology +TEMPLATE = app + +OUTPUT += Console +SOURCES += main.cpp\ + mywindow.cpp + +HEADERS += mywindow.h + +FORMS += mywindow.ui diff --git a/QT/morphology/mywindow.cpp b/QT/morphology/mywindow.cpp new file mode 100644 index 0000000..25c6305 --- /dev/null +++ b/QT/morphology/mywindow.cpp @@ -0,0 +1,313 @@ +// Dolaczamy plik naglowkowy naszej klasy MyWindow +#include "mywindow.h" + +// Dolaczamy plik naglowkowy zawierajacy definicje GUI +// Plik ten jest generowany automatycznie +// z pliku XML "mywindow.ui" +#include "ui_mywindow.h" + +#include +#include +#include +#include +#include +#include // for float,double macros +#include +#include +#include + +#define PI 3.1415 + +std::vector matrixMul(std::vector p, std::vector m) +{ + std::vector res(3); + for(int i = 0; i < 3; i++) + { + res.push_back(0); + for(int j = 0; j < 3; j++) + { + res[i] += m[i * 3 + j] * p[j]; + } + } + return res; +} + +std::vector matrixMul3x3(std::vector m1, std::vector m2) +{ + std::vector res(9, 0); + for(int i = 0; i < 3; i++) + { + for(int j = 0; j < 3; j++) + { + for(int k = 0; k < 3; k++) + { + res[i * 3 + j] += m1[i * 3 + k] * m2[k * 3 + j]; + } + } + } + return res; +} + + +QColor mul(float v, QColor c){ + int red = (int)(c.red() * v); + if(red > 255) red = 255; + int green = (int)(c.green() * v); + if(green > 255) green = 255; + int blue = (int)(c.blue() * v); + if(blue > 255) blue = 255; + return QColor(red, green, blue); +} + +QColor add(QColor c1, QColor c2){ + int red = (int)(c1.red() + c2.red()); + if(red > 255) red = 255; + int green = (int)(c1.green() + c2.green()); + if(green > 255) green = 255; + int blue = (int)(c1.blue() + c2.blue()); + if(blue > 255) blue = 255; + return QColor(red, green, blue); +} +// Definicja konstruktora, wywolujemy najpierw +// konstruktor klasy nadrzednej, nastepnie tworzymy +// obiekt klasy Ui_MyWindow reprezentujacy GUI +MyWindow::MyWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MyWindow) +{ + // Wywolujemy funkcje tworzaca elementy GUI + // Jej definicja znajduje sie w pliku "ui_mywindow.h" + ui->setupUi(this); + + // Pobieramy wymiary i wspolrzedne lewego gornego naroznika ramki + // i ustawiamy wartosci odpowiednich pol + // Uwaga: ramke "rysujFrame" wykorzystujemy tylko do + // wygodnego ustaiwenia tych wymiarow. Rysunek bedziemy wyswietlac + // bezposrednio w glownym oknie aplikacji. + szer = ui->rysujFrame->width(); + wys = ui->rysujFrame->height(); + poczX = ui->rysujFrame->x(); + poczY = ui->rysujFrame->y(); + + // Tworzymy obiekt klasy QImage, o odpowiedniej szerokosci + // i wysokosci. Ustawiamy format bitmapy na 32 bitowe RGB + // (0xffRRGGBB). + img = new QImage(szer,wys,QImage::Format_RGB32); + + loaded_img1 = new QImage("/home/davp/umk/2022_2023/GK/QT/alpha-blending/f.png"); + loaded_img2 = new QImage("/home/davp/umk/2022_2023/GK/QT/alpha-blending/f.png"); + + int width = loaded_img1->width(); + int height = loaded_img1->height(); + for(int x = 0; x < width; x++) + for(int y = 0; y < height; y++){ + QColor color = GetPixel(loaded_img1, x, y); + if((color.red() + color.green() + color.blue()) / 3.0f > 128.0f) + DrawPixel(loaded_img1, x, y, QColor(255, 255, 255)); + else + DrawPixel(loaded_img1, x, y, QColor(0, 0, 0)); + } + + UpdateImage(); + + update(); +} + +// Definicja destruktora +MyWindow::~MyWindow() +{ + delete ui; +} + +// Funkcja (slot) wywolywana po nacisnieciu przycisku "Wyjscie" (exitButton) +// Uwaga: polaczenie tej funkcji z sygnalem "clicked" +// emitowanym przez przycisk jest realizowane +// za pomoca funkcji QMetaObject::connectSlotsByName(MyWindow) +// znajdujacej sie w automatycznie generowanym pliku "ui_mywindow.h" +// Nie musimy wiec sami wywolywac funkcji "connect" +void MyWindow::on_exitButton_clicked() +{ + // qApp to globalny wskaznik do obiektu reprezentujacego aplikacje + // quit() to funkcja (slot) powodujaca zakonczenie aplikacji z kodem 0 (brak bledu) + qApp->quit(); +} + +void MyWindow::on_erosion_clicked(){ + Erosion(loaded_img1); + UpdateImage(); +} + +void MyWindow::on_dilation_clicked(){ + Dilation(loaded_img1); + UpdateImage(); +} + +void MyWindow::on_opening_clicked(){ + Open(loaded_img1); + UpdateImage(); +} + +void MyWindow::on_closing_clicked(){ + Close(loaded_img1); + UpdateImage(); +} + +void MyWindow::UpdateImage(){ + for(int x = 0; x < szer; x++) + for(int y = 0; y < wys; y++){ + float xw = (float) x / (float)szer; + float yh = (float) y / (float) wys; + DrawPixel(img, x, y, GetInterpolatedColor(loaded_img1, xw, yh)); + } + + update(); +} + +bool MyWindow::IsLit(QImage* im, int x, int y, int val){ + int width = im->width(); + int height = im->height(); + if(x < 0 || y < 0 || x >= width || y >= height) + return false; + QColor pix = GetPixel(im, x, y); + return pix.red() == val && pix.green() == val && pix.blue() == val; +} + +void MyWindow::Erosion(QImage* im){ + int width = im->width(); + int height = im->height(); + + memcpy(loaded_img2->bits(), loaded_img1->bits(), width * height * 4); + + for(int x = 0; x < width; x++) + for(int y = 0; y < height; y++){ + bool active = false; + for (int x2 = x - 1; x2 <= x + 1; x2++) + for (int y2 = y - 1; y2 <= y + 1; y2++) + if(IsLit(loaded_img1, x2, y2, 0)){ + DrawPixel(loaded_img2, x, y, QColor(0, 0, 0)); + break; + } + } + memcpy(loaded_img1->bits(), loaded_img2->bits(), width * height * 4); +} + +void MyWindow::Dilation(QImage* im){ + int width = im->width(); + int height = im->height(); + + memcpy(loaded_img2->bits(), loaded_img1->bits(), width * height * 4); + + for(int x = 0; x < width; x++) + for(int y = 0; y < height; y++){ + bool active = false; + for (int x2 = x - 1; x2 <= x + 1; x2++) + for (int y2 = y - 1; y2 <= y + 1; y2++) + if(IsLit(loaded_img1, x2, y2, 255)){ + DrawPixel(loaded_img2, x, y, QColor(255, 255, 255)); + break; + } + } + memcpy(loaded_img1->bits(), loaded_img2->bits(), width * height * 4); +} + +void MyWindow::Close(QImage* im){ + Dilation(im); + Erosion(im); +} + +void MyWindow::Open(QImage* im){ + Erosion(im); + Dilation(im); +} + +QColor MyWindow::GetPixel(QImage* img, int x, int y){ + QColor res; + int width = img->width(); + int height = img->height(); + if(x >= width || y >= height || x < 0 || y < 0) + return res; + + unsigned char* ptr = img->bits(); + + res.setBlue(ptr[width*4*y + 4*x]); + res.setGreen(ptr[width*4*y + 4*x + 1]); + res.setRed(ptr[width*4*y + 4*x + 2]); + res.setAlpha(ptr[width*4*y + 4*x + 3]); + + return res; +} + + +QColor MyWindow::GetInterpolatedColor(QImage* img, float x, float y){ + float width = img->width(); + float height = img->height(); + float xw = (x * width); + float yw = (y * height); + int x_f = (int) (x * width); + int y_f = (int) (y * height); + int x_c = ceil(x * width); + int y_c = ceil(y * height); + float a = (xw - (float) x_f); + float b = ((yw) - (float) y_f); + + QColor P1 = GetPixel(img, x_f, y_c); + QColor P2 = GetPixel(img, x_c, y_c); + QColor P3 = GetPixel(img, x_c, y_f); + QColor P4 = GetPixel(img, x_f, y_f); + + QColor v1 = mul(1.0f - a, P1); + QColor v2 = mul(a, P2); + QColor v3 = mul(a, P3); + QColor v4 = mul(1.0f - a, P4); + QColor top = add(v1, v2); + QColor bottom = add(v3, v4); + QColor btop = mul(b, top); + QColor bbottom = mul(1.0f - b, bottom); + QColor res = add(btop, bbottom); + + return res; +} + +// Funkcja "odmalowujaca" komponent +void MyWindow::paintEvent(QPaintEvent*) +{ + // Obiekt klasy QPainter pozwala nam rysowac na komponentach + QPainter p(this); + + + UpdateImage(); + // Rysuje obrazek "img" w punkcie (poczX,poczY) + // (tu bedzie lewy gorny naroznik) + p.drawImage(poczX,poczY,*img); +} + + +void MyWindow::DrawPixel(QImage* im, int x, int y, QColor color){ + int width = im->width(); + int height = im->height(); + + if(x >= width || y >= height || x < 0 || y < 0) + return; + + unsigned char* ptr = im->bits(); + + ptr[width*4*y + 4*x] = color.blue(); + ptr[width*4*y + 4*x + 1] = color.green(); + ptr[width*4*y + 4*x + 2] = color.red(); + ptr[width*4*y + 4*x + 3] = color.alpha(); +} + + +void MyWindow::ClearImage(QImage *img){ + unsigned char* empty_val = (unsigned char*)malloc(4); + empty_val[0] = 0; + empty_val[1] = 0; + empty_val[2] = 0; + empty_val[3] = 255; + unsigned char* ptr = img->bits(); + for(int i = 0; i < img->width(); i++){ + for(int j = 0; j < img->height(); j++){ + memcpy(ptr + 4 * (i + j * img->width()), empty_val, 4); + } + } +} diff --git a/QT/morphology/mywindow.h b/QT/morphology/mywindow.h new file mode 100644 index 0000000..b6ac704 --- /dev/null +++ b/QT/morphology/mywindow.h @@ -0,0 +1,136 @@ +// Plik naglowkowy klasy MyWindow +// Obiekt tej klasy to glowne okno naszej aplikacji +// Szkielet tego pliku jest tworzony przez QtCreator +// Mozemy do niego dodac deklaracje wlasnych pol i metod + +#ifndef MYWINDOW_H +#define MYWINDOW_H + +// Dolaczamy plik naglowkowy klasy QMainWindow, +// Klasa QMainWindow posiada swoj wlasny layout. +// latwo mozna do niej dodac pasek menu, widzety dokujace, +// pasek narzedzi i pasek statusu. Na srodku okna +// wyswietlanego przez QMainWindow znajduje sie obszar, +// ktory mozna wypelnic roznymi widgetami. +#include + +// QPainter to klasa umozliwiajaca niskopoziomowe rysowanie +// na elementach GUI +#include + +// QImage to klasa pozwalajaca na niezalezna od sprzetu reprezentacje obrazu. +// Pozwala na bezposredni dostep do poszczegolnych pikseli, +// Bedziemy jej uzywali do tworzenia i przechowywania +// naszych rysunkow +#include + +// QMouseEvent to klasa obslugujaca zdarzenia zwiazane z myszka +// klikniecia, ruch myszka itp. +#include + +#include +#include // for float,double macros + +enum Mode {Line, Circle, Fill}; + +namespace Ui { + class MyWindow; +} + + +// MyWindow jest podklasa klasy QMainWindow. +class MyWindow : public QMainWindow +{ + // Q_OBJECT jest to makro, ktore musi sie znajdowac + // we wszystkich klasach definiujacych wlasne sygnaly i sloty + // W naszej klasie nie jest ono potrzebne, + // ale QtCreator dodaje je automatycznie do kazdej klasy. + Q_OBJECT + +public: + // Typowa deklaracja konstruktora w Qt. + // Parametr "parent" okresla rodzica komponenetu. + // W przypadku naszej klasy parametr ten wskazuje na null + // co oznacza, ze komponenet nie ma rodzica, jest to + // komponenet najwyzszego poziomu + explicit MyWindow(QWidget *parent = 0); + + // Deklaracja destruktora + ~MyWindow(); + +private: + // QtCreator pozwala na tworzenie GUI za pomoca graficznego kreatora. + // Skladniki interfejsu i ich wlasciwosci zapisane sa wowczas + // w pliku XML "nazwa_klasy.ui" + // Do poszczegolnych elementow GUI odwolujemy sie za pomoca zmiennej "ui" + Ui::MyWindow *ui; + + int mode; + + // Pole przechowujace obrazek + QImage *img; + + QImage *loaded_img1; + QImage *loaded_img2; + + // Pole przechowujace obrazek + QImage *img_tmp; + + QImage *active_img; + + // Pola przechowujace szerokosc i wysokosc rysunku + // oraz wspolrzedne jego lewego gornego naroznika + int szer; + int wys; + int poczX; + int poczY; + int startX, startY; + bool draw_finished; + int segment_count; + float alpha; + + float rotation_angle; + std::vector scale_vec; + std::vector translation_vec; + std::vector sh_vec; + + int tmp_point_id = 0; + int tmp_shape_id = 0; + + // Deklaracje funkcji + void czysc(); + void rysuj1(); + void rysuj2(); + + + void UpdateTempImage(); + void ApplyTempImage(); + + void ClearImage(QImage *img); + + QColor GetPixel(QImage* img, int x, int y); + void DrawPixel(QImage* img, int x, int y, QColor color); + QColor GetInterpolatedColor(QImage* img, float x, float y); + void UpdateImage(); + + + bool IsLit(QImage* im, int x, int y, int val); + void Erosion(QImage* im); + void Dilation(QImage* im); + void Close(QImage* im); + void Open(QImage* im); + + // Deklaracje slotow, czyli funkcji wywolywanych + // po wystapieniu zdarzen zwiazanych z GUI + // np. klikniecie na przycisk, ruch myszka +private slots: + void on_exitButton_clicked(); + void paintEvent(QPaintEvent*); + void on_erosion_clicked(); + void on_dilation_clicked(); + void on_opening_clicked(); + void on_closing_clicked(); + +}; + +#endif // MYWINDOW_H diff --git a/QT/morphology/mywindow.ui b/QT/morphology/mywindow.ui new file mode 100644 index 0000000..24aea87 --- /dev/null +++ b/QT/morphology/mywindow.ui @@ -0,0 +1,141 @@ + + + MyWindow + + + + 0 + 0 + 883 + 583 + + + + true + + + MyWindow + + + + + + 10 + 10 + 600 + 600 + + + + true + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + 630 + 10 + 241 + 201 + + + + Opcje + + + + + 90 + 30 + 75 + 23 + + + + Wyjście + + + + + + 30 + 80 + 80 + 25 + + + + Erozja + + + + + + 30 + 140 + 80 + 25 + + + + Otwarcie + + + + + + 140 + 80 + 80 + 25 + + + + Dylacja + + + + + + 140 + 140 + 80 + 25 + + + + Zamknięcie + + + + + + + + 0 + 0 + 883 + 22 + + + + + + TopToolBarArea + + + false + + + + + + + + diff --git a/QT/morphology/p.png b/QT/morphology/p.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ccea7fc51f4c4cf0a1c003565f65e566dfba08 GIT binary patch literal 9808 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