diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d16e137..11e7a85 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -6,6 +6,7 @@ set(AIGO_SRCS settings.cpp state.cpp image.cpp + mask.cpp ) #find SDL and its related libraries diff --git a/lib/image.cpp b/lib/image.cpp index fccf352..6ab1439 100644 --- a/lib/image.cpp +++ b/lib/image.cpp @@ -12,17 +12,70 @@ namespace Image ((uint32_t*)image->pixels)[i] = 0xffffffff; else ((uint32_t*)image->pixels)[i] = 0xff000000; - //gray | (gray << 8) | (gray << 16); + //gray | (gray << 8) | (gray << 16); } } + void dilation(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask) + { + for (int y = mask->size / 2; y < dest->h - mask->size / 2; ++y) + { + for (int x = mask->size / 2; x < dest->w - mask->size / 2; ++x) + { + bool whiteFound = false; + for (int i = 0; i < mask->size && !whiteFound; ++i) + { + for (int j = 0; j < mask->size && !whiteFound; ++j) + { + if (mask->mask[i*mask->size + j] && + PXR(PX(src, x - mask->size / 2 + i, y - mask->size / 2 + j)) + ) + { + whiteFound = true; + } + } + } + if (whiteFound) + ((uint32_t*)dest->pixels)[y*dest->w+x] = 0xffffffff; + else + ((uint32_t*)dest->pixels)[y*dest->w+x] = 0xff000000; + } + } + } + + void erosion(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask) + { + for (int y = mask->size / 2; y < dest->h - mask->size / 2; ++y) + { + for (int x = mask->size / 2; x < dest->w - mask->size / 2; ++x) + { + bool blackFound = false; + for (int i = 0; i < mask->size && !blackFound; ++i) + { + for (int j = 0; j < mask->size && !blackFound; ++j) + { + if (mask->mask[i*mask->size + j] && + !PXR(PX(src, x - mask->size / 2 + i, y - mask->size / 2 + j)) + ) + { + blackFound = true; + } + } + } + if (blackFound) + ((uint32_t*)dest->pixels)[y*dest->w+x] = 0xff000000; + else + ((uint32_t*)dest->pixels)[y*dest->w+x] = 0xffffffff; + } + } + } SDL_Surface *copySurface(SDL_Surface *s) { SDL_Surface *copy = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, - s->format->BitsPerPixel, - s->format->Rmask, s->format->Gmask, - s->format->Bmask, s->format->Amask); + s->format->BitsPerPixel, + s->format->Rmask, s->format->Gmask, + s->format->Bmask, s->format->Amask); SDL_BlitSurface(s, NULL, copy, NULL); return copy; } diff --git a/lib/image.h b/lib/image.h index aff3205..43d003f 100644 --- a/lib/image.h +++ b/lib/image.h @@ -2,6 +2,7 @@ #define _IMAGE_H_ #include +#include "mask.h" // get pixel/something in array p of size w*h #define PX_(p, x, y, w, h) ((p)[(x)+(y)*(w)]) @@ -22,6 +23,8 @@ namespace Image { void threshold(SDL_Surface *image, int lowerBound, int upperBound); + void erosion(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask); + void dilation(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask); SDL_Surface *copySurface(SDL_Surface *s); } diff --git a/qt/aigoqt.cpp b/qt/aigoqt.cpp index f78e1f9..ed527e9 100644 --- a/qt/aigoqt.cpp +++ b/qt/aigoqt.cpp @@ -10,9 +10,11 @@ AigoQt::AigoQt(QWidget *parent) cam = new Quickcam("/dev/video0"); timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(updateImage())); + connect(timer, SIGNAL(timeout()), this, SLOT(on_buttonDrawPoints_clicked())); timer->start(10); + copy = Image::copySurface(cam->getSurface()); + } AigoQt::~AigoQt( void ) @@ -24,7 +26,17 @@ void AigoQt::updateImage( void ) { cam->update(); SDL_Surface *s = cam->getSurface(); - Image::threshold(s, sliderBlack->value(), sliderWhite->value()); + + Image::threshold(s, blackImageThreshold->value(), whiteImageThreshold->value()); + SDL_BlitSurface(s, NULL, copy, NULL); + + Mask::mask *mask = Mask::createCircleMask(4); + + if (checkErosion->isChecked()) Image::erosion(s, copy, mask); + if (checkDilation->isChecked()) Image::dilation(s, copy, mask); + + delete mask; + image->setPixmap(QPixmap::fromImage(QImage((uchar*)s->pixels, s->w, s->h, QImage::Format_RGB32))); //on_buttonGenerateState_clicked(); } diff --git a/qt/aigoqt.h b/qt/aigoqt.h index fad6d49..de68e0a 100644 --- a/qt/aigoqt.h +++ b/qt/aigoqt.h @@ -34,6 +34,8 @@ class AigoQt : public QMainWindow, public Ui::AigoQt Settings settings; + SDL_Surface *copy; + }; diff --git a/qt/main.ui b/qt/main.ui index a62707c..e2cadd1 100644 --- a/qt/main.ui +++ b/qt/main.ui @@ -5,8 +5,8 @@ 0 0 - 880 - 728 + 942 + 825 @@ -20,62 +20,21 @@ 6 - - - - - 700 - 550 - - - - Preview - - - - - 40 - 40 - 640 - 480 - - - - - 640 - 480 - - - - - 640 - 480 - - - - - - - - - - + + - White threshold + Black threshold(image) - - + + - Black threshold + White threshold (image) - - - 100 @@ -89,9 +48,6 @@ - - - 100 @@ -113,7 +69,68 @@ - + + + + Black threshold(state) + + + + + + + White threshold (state) + + + + + + + 100 + + + 1000 + + + 10 + + + 50 + + + 200 + + + Qt::Horizontal + + + + + + + 100 + + + 1000 + + + Qt::Horizontal + + + + + + + + + + + + + + + + @@ -154,6 +171,20 @@ + + + + Erosion + + + + + + + Dilation + + + @@ -170,6 +201,44 @@ + + + + + 700 + 550 + + + + Preview + + + + + 40 + 40 + 640 + 480 + + + + + 640 + 480 + + + + + 640 + 480 + + + + + + + + @@ -177,7 +246,7 @@ 0 0 - 880 + 942 29 @@ -212,12 +281,12 @@ display(int) - 702 - 618 + 720 + 668 - 727 - 618 + 870 + 667 @@ -228,12 +297,12 @@ display(int) - 542 - 612 + 702 + 668 - 834 - 619 + 870 + 667 @@ -244,12 +313,12 @@ display(int) - 701 - 638 + 716 + 698 - 749 - 640 + 870 + 696 @@ -260,12 +329,76 @@ display(int) - 561 - 645 + 707 + 698 - 825 - 640 + 870 + 696 + + + + + whiteImageThreshold + sliderMoved(int) + lcdNumber_3 + display(int) + + + 698 + 729 + + + 736 + 722 + + + + + whiteImageThreshold + valueChanged(int) + lcdNumber_3 + display(int) + + + 574 + 725 + + + 813 + 724 + + + + + blackImageThreshold + valueChanged(int) + lcdNumber_4 + display(int) + + + 604 + 754 + + + 735 + 759 + + + + + blackImageThreshold + sliderMoved(int) + lcdNumber_4 + display(int) + + + 561 + 753 + + + 816 + 752