From a606c55e0840304155bb6d5a101d75f77eeda749 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Aug 2015 14:42:36 +0300 Subject: [PATCH 01/15] Prototype for second practice. --- CMakeLists.txt | 1 + sample_zhiltsov/CMakeLists.txt | 7 ++ sample_zhiltsov/application.cpp | 123 ++++++++++++++++++++++++++++++++ sample_zhiltsov/application.hpp | 49 +++++++++++++ sample_zhiltsov/main.cpp | 44 ++++++++++++ sample_zhiltsov/processing.cpp | 18 +++++ sample_zhiltsov/processing.hpp | 9 +++ 7 files changed, 251 insertions(+) create mode 100644 sample_zhiltsov/CMakeLists.txt create mode 100644 sample_zhiltsov/application.cpp create mode 100644 sample_zhiltsov/application.hpp create mode 100644 sample_zhiltsov/main.cpp create mode 100644 sample_zhiltsov/processing.cpp create mode 100644 sample_zhiltsov/processing.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a1949c..23a9cbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(LIBRARY_DEPS ${OpenCV_LIBS}) # BUILD add_subdirectory(sample_template) +add_subdirectory(sample_zhiltsov) # Add you directory here # add_subdirectory(sample_YOUR_NAME) diff --git a/sample_zhiltsov/CMakeLists.txt b/sample_zhiltsov/CMakeLists.txt new file mode 100644 index 0000000..c5fe81b --- /dev/null +++ b/sample_zhiltsov/CMakeLists.txt @@ -0,0 +1,7 @@ +set(target "sample_zhiltsov") + +file(GLOB hdrs "*.hpp") +file(GLOB srcs "*.cpp") + +add_executable(${target} ${srcs} ${hdrs}) +target_link_libraries(${target} ${LIBRARY_DEPS}) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp new file mode 100644 index 0000000..4cc18d1 --- /dev/null +++ b/sample_zhiltsov/application.cpp @@ -0,0 +1,123 @@ +#include "application.hpp" +#include "processing.hpp" + +#include + +using namespace cv; + +int Application::parseArguments(int argc, const char **argv, + Application::Parameters ¶ms) +{ + if (argc < 2) + { + return 1; + } + params.imgFileName = std::string(argv[1]); + return 0; +} + +int Application::getFrame(const std::string &fileName, Mat& src) +{ + src = imread(fileName); + if (src.empty()) + { + return 1; + } + return 0; +} + +int Application::processFrame(const Mat& src, Mat& dst) +{ + processor.processFrame(src, dst); + + if (dst.empty()) + { + return 1; + } + + return 0; +} + +int Application::drawButtons(Mat &display) +{ + guiState.onButtonPlace = Rect(20, display.rows - 60, 120, 40); + guiState.offButtonPlace = Rect(160, display.rows - 60, 120, 40); + rectangle(display, guiState.onButtonPlace, + Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.offButtonPlace, + Scalar(128, 128, 128), CV_FILLED); + + putText(display, "on", + Point(guiState.onButtonPlace.x + guiState.onButtonPlace.width / 2 - 15, + guiState.onButtonPlace.y + guiState.onButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "off", + Point(guiState.offButtonPlace.x + guiState.offButtonPlace.width / 2 - 20, + guiState.offButtonPlace.y + guiState.offButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + + return 0; +} + +int Application::showFrame(const std::string &caption, + const Mat& src, Mat& dst) +{ + if (guiState.state == OffFilter) + { + src.copyTo(dst); + } + else if (guiState.state == OnFilter) + { + processFrame(src, dst); + } + else + { + return 1; + } + + Mat display(src.rows, src.cols + dst.cols, src.type()); + Mat srcRoi = display(Rect(0, 0, src.cols, src.rows)); + src.copyTo(srcRoi); + Mat dstRoi = display(Rect(src.cols, 0, dst.cols, dst.rows)); + dst.copyTo(dstRoi); + + drawButtons(display); + + namedWindow(caption); + imshow(caption, display); + setMouseCallback(caption, onButtonsOnOffClick, &guiState); + char key = waitKey(1); + + return key; +} + +void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData) +{ + if (eventId != EVENT_LBUTTONDOWN) + { + return; + } + Application::GUIElementsState *elems = + (Application::GUIElementsState *)userData; + if (onButtonClicked(elems->onButtonPlace, x, y)) + { + elems->state = Application::OnFilter; + return; + } + if (onButtonClicked(elems->offButtonPlace, x, y)) + { + elems->state = Application::OffFilter; + return; + } +} + +bool onButtonClicked(cv::Rect buttonPlace, int x, int y) +{ + if (x < buttonPlace.x || x > buttonPlace.x + buttonPlace.width || + y < buttonPlace.y || y > buttonPlace.y + buttonPlace.height) + { + return false; + } + return true; +} + diff --git a/sample_zhiltsov/application.hpp b/sample_zhiltsov/application.hpp new file mode 100644 index 0000000..862cc3f --- /dev/null +++ b/sample_zhiltsov/application.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include + +#include "processing.hpp" + +bool onButtonClicked(cv::Rect buttonPlace, int x, int y); +void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData); + +class Application +{ + public: + enum WindowState + { + OnFilter, + OffFilter + }; + struct Parameters + { + std::string imgFileName; + }; + struct GUIElementsState + { + WindowState state; + cv::Rect onButtonPlace; + cv::Rect offButtonPlace; + }; + int parseArguments(int argc, const char **argv, Parameters ¶ms); + int getFrame(const std::string &fileName, cv::Mat& src); + int processFrame(const cv::Mat& src, cv::Mat& dst); + int showFrame(const std::string &caption, + const cv::Mat& src, cv::Mat& dst); + friend void onButtonsOnOffClick(int eventId, int x, int y, + int flags, void *userData); + Application() + { + guiState.state = OnFilter; + }; + + private: + Processing processor; + GUIElementsState guiState; + + int drawButtons(cv::Mat &display); + + friend bool onButtonClicked(cv::Rect buttonPlace, int x, int y); +}; diff --git a/sample_zhiltsov/main.cpp b/sample_zhiltsov/main.cpp new file mode 100644 index 0000000..43ff041 --- /dev/null +++ b/sample_zhiltsov/main.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include "application.hpp" + +using namespace std; +using namespace cv; + +enum ErrorCode { + OK, + WRONG_ARGUMENTS, + WRONG_INPUT, + CANT_PROCESS +}; + +int main(int argc, const char **argv) +{ + Application app; + Application::Parameters params; + + if (app.parseArguments(argc, argv, params) != 0) + { + cout << "sample_template " << endl; + cout << " - image name for filtering" << endl; + return WRONG_ARGUMENTS; + } + + Mat src; + if (app.getFrame(params.imgFileName, src) != 0) + { + cout << "Error: \'src\' image is null or empty!" << endl; + return WRONG_INPUT; + } + + const std::string caption = "OpenCV Sample"; + char key = 0; + Mat dst(src.rows, src.cols, src.type()); + while (key != 27) // Esc + { + key = app.showFrame(caption, src, dst); + } + + return OK; +} diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp new file mode 100644 index 0000000..bd51a88 --- /dev/null +++ b/sample_zhiltsov/processing.cpp @@ -0,0 +1,18 @@ +#include "processing.hpp" + +#include + +using namespace cv; + +void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) +{ + src.copyTo(dst); + + cv::Rect region(src.rows/4, src.cols/4, src.rows/2, src.cols/2); + Mat roi = dst(region); + + const int kSize = 11; + medianBlur(roi, roi, kSize); + + rectangle(dst, region, Scalar(255, 0, 0)); +} diff --git a/sample_zhiltsov/processing.hpp b/sample_zhiltsov/processing.hpp new file mode 100644 index 0000000..65f29fc --- /dev/null +++ b/sample_zhiltsov/processing.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +class Processing +{ + public: + void processFrame(const cv::Mat& src, cv::Mat& dst); +}; From ae08598692671c5b00ca20948dcb0c85f90372cd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Aug 2015 15:15:31 +0300 Subject: [PATCH 02/15] 7th task completed. --- sample_zhiltsov/processing.cpp | 9 ++++++++- sample_zhiltsov/processing.hpp | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index bd51a88..9ca4c76 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -1,6 +1,8 @@ #include "processing.hpp" #include +#include +#include using namespace cv; @@ -8,7 +10,12 @@ void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) { src.copyTo(dst); - cv::Rect region(src.rows/4, src.cols/4, src.rows/2, src.cols/2); + region.x = src.rows/4 + region.x * std::abs(sin((float)clock())) * 0.1; + region.y = src.cols/4 + region.y * std::abs(cos((float)clock())) * 0.1; + + region.width = src.rows/2 + region.width * std::abs(sin((float)clock())) * 0.1; + region.height = src.cols/2 + region.height * std::abs(cos((float)clock())) * 0.1; + Mat roi = dst(region); const int kSize = 11; diff --git a/sample_zhiltsov/processing.hpp b/sample_zhiltsov/processing.hpp index 65f29fc..bd69f6b 100644 --- a/sample_zhiltsov/processing.hpp +++ b/sample_zhiltsov/processing.hpp @@ -6,4 +6,6 @@ class Processing { public: void processFrame(const cv::Mat& src, cv::Mat& dst); + private: + cv::Rect region; }; From 6ee1dfacfb631d69a464867fadf81996098b7ab8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Aug 2015 15:48:21 +0300 Subject: [PATCH 03/15] 8th task completed. --- sample_zhiltsov/application.cpp | 27 +++++++++++++++++++++++++++ sample_zhiltsov/application.hpp | 7 +++++++ 2 files changed, 34 insertions(+) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index 4cc18d1..f9b4caf 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -2,6 +2,7 @@ #include "processing.hpp" #include +#include using namespace cv; @@ -42,10 +43,14 @@ int Application::drawButtons(Mat &display) { guiState.onButtonPlace = Rect(20, display.rows - 60, 120, 40); guiState.offButtonPlace = Rect(160, display.rows - 60, 120, 40); + guiState.saveButtonPlace = Rect(300, display.rows - 60, 120, 40); + rectangle(display, guiState.onButtonPlace, Scalar(128, 128, 128), CV_FILLED); rectangle(display, guiState.offButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.saveButtonPlace, + Scalar(128, 128, 128), CV_FILLED); putText(display, "on", Point(guiState.onButtonPlace.x + guiState.onButtonPlace.width / 2 - 15, @@ -55,6 +60,10 @@ int Application::drawButtons(Mat &display) Point(guiState.offButtonPlace.x + guiState.offButtonPlace.width / 2 - 20, guiState.offButtonPlace.y + guiState.offButtonPlace.height / 2 + 10), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "save", + Point(guiState.saveButtonPlace.x + guiState.saveButtonPlace.width / 2 - 20, + guiState.saveButtonPlace.y + guiState.saveButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); return 0; } @@ -86,6 +95,10 @@ int Application::showFrame(const std::string &caption, namedWindow(caption); imshow(caption, display); setMouseCallback(caption, onButtonsOnOffClick, &guiState); + + butonSaveClickHandleArgs.dstBuf = &dst; + + setMouseCallback(caption, onButtonSaveClick, this); char key = waitKey(1); return key; @@ -111,6 +124,20 @@ void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData) } } +void onButtonSaveClick(int eventId, int x, int y, int flsgs, void *userData) +{ + if (eventId != EVENT_LBUTTONDOWN) + { + return; + } + Application* app = static_cast(userData); + if (onButtonClicked(app->guiState.saveButtonPlace, x, y)) + { + imwrite(std::to_string((long long)clock()) + ".png", *app->butonSaveClickHandleArgs.dstBuf); + return; + } +} + bool onButtonClicked(cv::Rect buttonPlace, int x, int y) { if (x < buttonPlace.x || x > buttonPlace.x + buttonPlace.width || diff --git a/sample_zhiltsov/application.hpp b/sample_zhiltsov/application.hpp index 862cc3f..65bf4bf 100644 --- a/sample_zhiltsov/application.hpp +++ b/sample_zhiltsov/application.hpp @@ -26,6 +26,7 @@ class Application WindowState state; cv::Rect onButtonPlace; cv::Rect offButtonPlace; + cv::Rect saveButtonPlace; }; int parseArguments(int argc, const char **argv, Parameters ¶ms); int getFrame(const std::string &fileName, cv::Mat& src); @@ -34,6 +35,8 @@ class Application const cv::Mat& src, cv::Mat& dst); friend void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData); + friend void onButtonSaveClick(int eventId, int x, int y, + int flags, void *userData); Application() { guiState.state = OnFilter; @@ -42,6 +45,10 @@ class Application private: Processing processor; GUIElementsState guiState; + struct ButonSaveClickHandleArgs { + cv::Mat* dstBuf; + }; + ButonSaveClickHandleArgs butonSaveClickHandleArgs; int drawButtons(cv::Mat &display); From f7ab402976e68c465658309d9136ead6398699dd Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Tue, 18 Aug 2015 16:52:45 +0300 Subject: [PATCH 04/15] Update processing.cpp Fixed compilation bug. --- sample_zhiltsov/processing.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index 9ca4c76..f5816b0 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -3,6 +3,7 @@ #include #include #include +#include using namespace cv; From e0d97c09e8bd0b5300a96a0ba9baecf1270f1183 Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Tue, 18 Aug 2015 16:54:29 +0300 Subject: [PATCH 05/15] Update processing.cpp Minor fix. --- sample_zhiltsov/processing.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index f5816b0..9ca4c76 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -3,7 +3,6 @@ #include #include #include -#include using namespace cv; From 9b47a90c2078e68f8a9c4559c3066522d073b98f Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Tue, 18 Aug 2015 16:55:00 +0300 Subject: [PATCH 06/15] Update application.cpp Compilation fix. --- sample_zhiltsov/application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index f9b4caf..635b95e 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -3,6 +3,7 @@ #include #include +#include using namespace cv; From 07fc3b92456fd9dc59cf192b4fa6a480e2c08db0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Aug 2015 17:23:45 +0300 Subject: [PATCH 07/15] 9th task completed. --- sample_zhiltsov/application.cpp | 92 +++++++++++++++++++++----------- sample_zhiltsov/application.hpp | 15 +++--- sample_zhiltsov/processing.cpp | 94 ++++++++++++++++++++++++++++++++- sample_zhiltsov/processing.hpp | 14 +++++ 4 files changed, 177 insertions(+), 38 deletions(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index f9b4caf..ae64f59 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -3,6 +3,7 @@ #include #include +#include using namespace cv; @@ -45,12 +46,18 @@ int Application::drawButtons(Mat &display) guiState.offButtonPlace = Rect(160, display.rows - 60, 120, 40); guiState.saveButtonPlace = Rect(300, display.rows - 60, 120, 40); - rectangle(display, guiState.onButtonPlace, - Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.offButtonPlace, - Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.saveButtonPlace, - Scalar(128, 128, 128), CV_FILLED); + guiState.filterBlurButtonPlace = Rect(20, display.rows - 120, 120, 40); + guiState.filterCannyButtonPlace = Rect(160, display.rows - 120, 120, 40); + guiState.filterPixelizeButtonPlace = Rect(300, display.rows - 120, 120, 40); + guiState.filterGrayscaleButtonPlace = Rect(440, display.rows - 120, 120, 40); + + rectangle(display, guiState.onButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.offButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.saveButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.filterBlurButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.filterCannyButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.filterPixelizeButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.filterGrayscaleButtonPlace, Scalar(128, 128, 128), CV_FILLED); putText(display, "on", Point(guiState.onButtonPlace.x + guiState.onButtonPlace.width / 2 - 15, @@ -64,12 +71,27 @@ int Application::drawButtons(Mat &display) Point(guiState.saveButtonPlace.x + guiState.saveButtonPlace.width / 2 - 20, guiState.saveButtonPlace.y + guiState.saveButtonPlace.height / 2 + 10), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "Canny", + Point(guiState.filterCannyButtonPlace.x + guiState.filterCannyButtonPlace.width / 2 - 20, + guiState.filterCannyButtonPlace.y + guiState.filterCannyButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "Blur", + Point(guiState.filterBlurButtonPlace.x + guiState.filterBlurButtonPlace.width / 2 - 20, + guiState.filterBlurButtonPlace.y + guiState.filterBlurButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "Pixelize", + Point(guiState.filterPixelizeButtonPlace.x + guiState.filterPixelizeButtonPlace.width / 2 - 20, + guiState.filterPixelizeButtonPlace.y + guiState.filterPixelizeButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "Grayscale", + Point(guiState.filterGrayscaleButtonPlace.x + guiState.filterGrayscaleButtonPlace.width / 2 - 20, + guiState.filterGrayscaleButtonPlace.y + guiState.filterGrayscaleButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); return 0; } -int Application::showFrame(const std::string &caption, - const Mat& src, Mat& dst) +int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) { if (guiState.state == OffFilter) { @@ -94,46 +116,56 @@ int Application::showFrame(const std::string &caption, namedWindow(caption); imshow(caption, display); - setMouseCallback(caption, onButtonsOnOffClick, &guiState); - butonSaveClickHandleArgs.dstBuf = &dst; + butonClickHandleArgs.dstBuf = &dst; + setMouseCallback(caption, onButtonClick, this); - setMouseCallback(caption, onButtonSaveClick, this); char key = waitKey(1); return key; } -void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData) +void onButtonClick(int eventId, int x, int y, int flsgs, void *userData) { - if (eventId != EVENT_LBUTTONDOWN) - { - return; - } - Application::GUIElementsState *elems = - (Application::GUIElementsState *)userData; - if (onButtonClicked(elems->onButtonPlace, x, y)) + if (eventId != EVENT_LBUTTONDOWN) + { + return; + } + Application* app = static_cast(userData); + + if (onButtonClicked(app->guiState.onButtonPlace, x, y)) { - elems->state = Application::OnFilter; + app->guiState.state = Application::OnFilter; return; } - if (onButtonClicked(elems->offButtonPlace, x, y)) + if (onButtonClicked(app->guiState.offButtonPlace, x, y)) { - elems->state = Application::OffFilter; + app->guiState.state = Application::OffFilter; return; } -} - -void onButtonSaveClick(int eventId, int x, int y, int flsgs, void *userData) -{ - if (eventId != EVENT_LBUTTONDOWN) + if (onButtonClicked(app->guiState.saveButtonPlace, x, y)) { + imwrite(std::to_string((long long)clock()) + ".png", *app->butonClickHandleArgs.dstBuf); return; } - Application* app = static_cast(userData); - if (onButtonClicked(app->guiState.saveButtonPlace, x, y)) + if (onButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Blur); + return; + } + if (onButtonClicked(app->guiState.filterCannyButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Canny); + return; + } + if (onButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Grayscale); + return; + } + if (onButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y)) { - imwrite(std::to_string((long long)clock()) + ".png", *app->butonSaveClickHandleArgs.dstBuf); + app->processor.setFilterType(FilterType::Pixelize); return; } } diff --git a/sample_zhiltsov/application.hpp b/sample_zhiltsov/application.hpp index 65bf4bf..d6c6f29 100644 --- a/sample_zhiltsov/application.hpp +++ b/sample_zhiltsov/application.hpp @@ -27,28 +27,31 @@ class Application cv::Rect onButtonPlace; cv::Rect offButtonPlace; cv::Rect saveButtonPlace; + cv::Rect filterGrayscaleButtonPlace; + cv::Rect filterPixelizeButtonPlace; + cv::Rect filterCannyButtonPlace; + cv::Rect filterBlurButtonPlace; }; int parseArguments(int argc, const char **argv, Parameters ¶ms); int getFrame(const std::string &fileName, cv::Mat& src); int processFrame(const cv::Mat& src, cv::Mat& dst); int showFrame(const std::string &caption, const cv::Mat& src, cv::Mat& dst); - friend void onButtonsOnOffClick(int eventId, int x, int y, - int flags, void *userData); - friend void onButtonSaveClick(int eventId, int x, int y, - int flags, void *userData); + friend void onButtonClick(int eventId, int x, int y, int flags, void *userData); Application() { guiState.state = OnFilter; + processor.setFilterType(FilterType::Blur); }; private: Processing processor; GUIElementsState guiState; - struct ButonSaveClickHandleArgs { + struct ButonClickHandleArgs + { cv::Mat* dstBuf; }; - ButonSaveClickHandleArgs butonSaveClickHandleArgs; + ButonClickHandleArgs butonClickHandleArgs; int drawButtons(cv::Mat &display); diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index 9ca4c76..839bb40 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -6,6 +6,11 @@ using namespace cv; +void Processing::setFilterType(int value) +{ + filterType = value; +} + void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) { src.copyTo(dst); @@ -18,8 +23,93 @@ void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) Mat roi = dst(region); - const int kSize = 11; - medianBlur(roi, roi, kSize); + switch (filterType) { + case FilterType::Blur: + { + const int kSize = 11; + medianBlur(roi, roi, kSize); + break; + } + case FilterType::Grayscale: + { + Mat newRoi = roi.clone(); + cvtColor(newRoi, newRoi, CV_BGR2GRAY); + std::vector channels(3); + channels[0] = newRoi; + channels[1] = newRoi; + channels[2] = newRoi; + merge(channels, roi); + break; + } + case FilterType::Pixelize: + { + pixelize(roi, roi); + break; + } + case FilterType::Canny: + { + const Size kSize(11, 11); + GaussianBlur(roi, roi, kSize, 5, 10); + + Mat newRoi = roi.clone(); + cvtColor(roi, newRoi, CV_BGR2GRAY); + + Canny(newRoi, newRoi, 10, 1); + + std::vector channels(3); + channels[0] = newRoi; + channels[1] = newRoi; + channels[2] = newRoi; + merge(channels, roi); + + break; + } + + default: { throw "Filter is not specefied."; } + } rectangle(dst, region, Scalar(255, 0, 0)); } + +/* + * Copy-pasted from: http://opencv-code.com/tutorials/photo-to-colored-dot-patterns-with-opencv/ +*/ +void Processing::pixelize(const Mat& src, Mat& dst) +{ + cv::Mat cir = cv::Mat::zeros(src.size(), CV_8UC1); + int bsize = 10; + + for (int i = 0; i < src.rows; i += bsize) + { + for (int j = 0; j < src.cols; j += bsize) + { + cv::Rect rect = cv::Rect(j, i, bsize, bsize) & + cv::Rect(0, 0, src.cols, src.rows); + + cv::Mat sub_dst(dst, rect); + sub_dst.setTo(cv::mean(src(rect))); + + cv::circle( + cir, + cv::Point(j+bsize/2, i+bsize/2), + bsize/2-1, + CV_RGB(255,255,255), -1, CV_AA + ); + } + } + + cv::Mat cir_32f; + cir.convertTo(cir_32f, CV_32F); + cv::normalize(cir_32f, cir_32f, 0, 1, cv::NORM_MINMAX); + + cv::Mat dst_32f; + dst.convertTo(dst_32f, CV_32F); + + std::vector channels; + cv::split(dst_32f, channels); + for (int i = 0; i < channels.size(); ++i) + channels[i] = channels[i].mul(cir_32f); + + cv::merge(channels, dst_32f); + dst_32f.convertTo(dst, CV_8U); +} \ No newline at end of file diff --git a/sample_zhiltsov/processing.hpp b/sample_zhiltsov/processing.hpp index bd69f6b..9a46c17 100644 --- a/sample_zhiltsov/processing.hpp +++ b/sample_zhiltsov/processing.hpp @@ -2,10 +2,24 @@ #include +struct FilterType { + enum { + Grayscale, + Pixelize, + Canny, + Blur + }; +}; + class Processing { public: void processFrame(const cv::Mat& src, cv::Mat& dst); + + void setFilterType(int filterType); private: cv::Rect region; + int filterType; + + void pixelize(const cv::Mat& src, cv::Mat& dst); }; From 640184aeadc175ec37f1008069d2dc35bfeac5ee Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Aug 2015 17:36:51 +0300 Subject: [PATCH 08/15] Compilation fix. --- sample_zhiltsov/application.cpp | 18 +++++++++--------- sample_zhiltsov/application.hpp | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index ae64f59..6116612 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -125,7 +125,7 @@ int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) return key; } -void onButtonClick(int eventId, int x, int y, int flsgs, void *userData) +void Application::onButtonClick(int eventId, int x, int y, int flsgs, void *userData) { if (eventId != EVENT_LBUTTONDOWN) { @@ -133,44 +133,44 @@ void onButtonClick(int eventId, int x, int y, int flsgs, void *userData) } Application* app = static_cast(userData); - if (onButtonClicked(app->guiState.onButtonPlace, x, y)) + if (isButtonClicked(app->guiState.onButtonPlace, x, y)) { app->guiState.state = Application::OnFilter; return; } - if (onButtonClicked(app->guiState.offButtonPlace, x, y)) + if (isButtonClicked(app->guiState.offButtonPlace, x, y)) { app->guiState.state = Application::OffFilter; return; } - if (onButtonClicked(app->guiState.saveButtonPlace, x, y)) + if (isButtonClicked(app->guiState.saveButtonPlace, x, y)) { imwrite(std::to_string((long long)clock()) + ".png", *app->butonClickHandleArgs.dstBuf); return; } - if (onButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) + if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) { app->processor.setFilterType(FilterType::Blur); return; } - if (onButtonClicked(app->guiState.filterCannyButtonPlace, x, y)) + if (isButtonClicked(app->guiState.filterCannyButtonPlace, x, y)) { app->processor.setFilterType(FilterType::Canny); return; } - if (onButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y)) + if (isButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y)) { app->processor.setFilterType(FilterType::Grayscale); return; } - if (onButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y)) + if (isButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y)) { app->processor.setFilterType(FilterType::Pixelize); return; } } -bool onButtonClicked(cv::Rect buttonPlace, int x, int y) +bool Application::isButtonClicked(cv::Rect buttonPlace, int x, int y) { if (x < buttonPlace.x || x > buttonPlace.x + buttonPlace.width || y < buttonPlace.y || y > buttonPlace.y + buttonPlace.height) diff --git a/sample_zhiltsov/application.hpp b/sample_zhiltsov/application.hpp index d6c6f29..9bb0f31 100644 --- a/sample_zhiltsov/application.hpp +++ b/sample_zhiltsov/application.hpp @@ -37,7 +37,7 @@ class Application int processFrame(const cv::Mat& src, cv::Mat& dst); int showFrame(const std::string &caption, const cv::Mat& src, cv::Mat& dst); - friend void onButtonClick(int eventId, int x, int y, int flags, void *userData); + Application() { guiState.state = OnFilter; @@ -52,8 +52,8 @@ class Application cv::Mat* dstBuf; }; ButonClickHandleArgs butonClickHandleArgs; + static void onButtonClick(int eventId, int x, int y, int flags, void *userData); + static bool isButtonClicked(cv::Rect buttonPlace, int x, int y); int drawButtons(cv::Mat &display); - - friend bool onButtonClicked(cv::Rect buttonPlace, int x, int y); }; From f1a63c31d19706d9b2f533921a269c5cc3bbc6fc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Aug 2015 17:46:53 +0300 Subject: [PATCH 09/15] Compilation fix... --- sample_zhiltsov/application.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index 6116612..0eb9f1b 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -4,6 +4,7 @@ #include #include #include +#include using namespace cv; @@ -145,7 +146,9 @@ void Application::onButtonClick(int eventId, int x, int y, int flsgs, void *user } if (isButtonClicked(app->guiState.saveButtonPlace, x, y)) { - imwrite(std::to_string((long long)clock()) + ".png", *app->butonClickHandleArgs.dstBuf); + std::stringstream ss; + ss << clock() << ".png"; + imwrite(ss.str(), *app->butonClickHandleArgs.dstBuf); return; } if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) From 82c25d6a9856f9fd4bb69762c3af817f7b91d810 Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Wed, 19 Aug 2015 22:08:45 +0300 Subject: [PATCH 10/15] Code style fixes --- sample_zhiltsov/application.cpp | 170 ++++++++++++++------------------ sample_zhiltsov/application.hpp | 47 ++++----- sample_zhiltsov/processing.cpp | 151 +++++++++++++++------------- sample_zhiltsov/processing.hpp | 35 ++++--- 4 files changed, 198 insertions(+), 205 deletions(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index 0eb9f1b..3b05eaf 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -8,8 +8,12 @@ using namespace cv; -int Application::parseArguments(int argc, const char **argv, - Application::Parameters ¶ms) +Application::Application() +{ + guiState.state = WindowState::OnFilter; +} + +int Application::parseArguments(int argc, const char** argv, Application::Parameters& params) { if (argc < 2) { @@ -19,7 +23,7 @@ int Application::parseArguments(int argc, const char **argv, return 0; } -int Application::getFrame(const std::string &fileName, Mat& src) +int Application::getFrame(const std::string& fileName, Mat& src) { src = imread(fileName); if (src.empty()) @@ -41,71 +45,49 @@ int Application::processFrame(const Mat& src, Mat& dst) return 0; } -int Application::drawButtons(Mat &display) +void create_button(const std::string& text, const Rect& rect, Mat& display) +{ + rectangle(display, guiState.onButtonPlace, Scalar(128, 128, 128), CV_FILLED); + putText(display, text, + Point(rect.x + rect.width / 2 - 15, + rect.y + rect.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, CV_COLOR(0, 0, 0), 2); +} + +int Application::drawButtons(Mat& display) { guiState.onButtonPlace = Rect(20, display.rows - 60, 120, 40); guiState.offButtonPlace = Rect(160, display.rows - 60, 120, 40); - guiState.saveButtonPlace = Rect(300, display.rows - 60, 120, 40); + guiState.saveButtonPlace = Rect(300, display.rows - 60, 120, 40); - guiState.filterBlurButtonPlace = Rect(20, display.rows - 120, 120, 40); - guiState.filterCannyButtonPlace = Rect(160, display.rows - 120, 120, 40); - guiState.filterPixelizeButtonPlace = Rect(300, display.rows - 120, 120, 40); - guiState.filterGrayscaleButtonPlace = Rect(440, display.rows - 120, 120, 40); + guiState.filterBlurButtonPlace = Rect(20, display.rows - 120, 120, 40); + guiState.filterCannyButtonPlace = Rect(160, display.rows - 120, 120, 40); + guiState.filterPixelizeButtonPlace = Rect(300, display.rows - 120, 120, 40); + guiState.filterGrayscaleButtonPlace = Rect(440, display.rows - 120, 120, 40); - rectangle(display, guiState.onButtonPlace, Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.offButtonPlace, Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.saveButtonPlace, Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.filterBlurButtonPlace, Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.filterCannyButtonPlace, Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.filterPixelizeButtonPlace, Scalar(128, 128, 128), CV_FILLED); - rectangle(display, guiState.filterGrayscaleButtonPlace, Scalar(128, 128, 128), CV_FILLED); - - putText(display, "on", - Point(guiState.onButtonPlace.x + guiState.onButtonPlace.width / 2 - 15, - guiState.onButtonPlace.y + guiState.onButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); - putText(display, "off", - Point(guiState.offButtonPlace.x + guiState.offButtonPlace.width / 2 - 20, - guiState.offButtonPlace.y + guiState.offButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); - putText(display, "save", - Point(guiState.saveButtonPlace.x + guiState.saveButtonPlace.width / 2 - 20, - guiState.saveButtonPlace.y + guiState.saveButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); - putText(display, "Canny", - Point(guiState.filterCannyButtonPlace.x + guiState.filterCannyButtonPlace.width / 2 - 20, - guiState.filterCannyButtonPlace.y + guiState.filterCannyButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); - putText(display, "Blur", - Point(guiState.filterBlurButtonPlace.x + guiState.filterBlurButtonPlace.width / 2 - 20, - guiState.filterBlurButtonPlace.y + guiState.filterBlurButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); - putText(display, "Pixelize", - Point(guiState.filterPixelizeButtonPlace.x + guiState.filterPixelizeButtonPlace.width / 2 - 20, - guiState.filterPixelizeButtonPlace.y + guiState.filterPixelizeButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); - putText(display, "Grayscale", - Point(guiState.filterGrayscaleButtonPlace.x + guiState.filterGrayscaleButtonPlace.width / 2 - 20, - guiState.filterGrayscaleButtonPlace.y + guiState.filterGrayscaleButtonPlace.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + create_button("on", guiState.onButtonPlace, display); + create_button("off", guiState.offButtonPlace, display); + create_button("save", guiState.saveButtonPlace, display); + create_button("Canny", guiState.filterCannyButtonPlace, display); + create_button("Blur", guiState.filterBlurButtonPlace, display); + create_button("Pixelize", guiState.filterPixelizeButtonPlace, display); + create_button("Grayscale", guiState.filterGrayscaleButtonPlace, display); return 0; } int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) { - if (guiState.state == OffFilter) - { + switch (guiState.state) { + case WindowState::OffFilter: src.copyTo(dst); - } - else if (guiState.state == OnFilter) - { + break; + + case WindowState::OnFilter: processFrame(src, dst); - } - else - { - return 1; - } + break; + + default: { throw std::exception("Unexpected window state."); } Mat display(src.rows, src.cols + dst.cols, src.type()); Mat srcRoi = display(Rect(0, 0, src.cols, src.rows)); @@ -118,8 +100,8 @@ int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) namedWindow(caption); imshow(caption, display); - butonClickHandleArgs.dstBuf = &dst; - setMouseCallback(caption, onButtonClick, this); + buttonClickHandleArgs.dstBuf = &dst; + setMouseCallback(caption, onButtonClick, this); char key = waitKey(1); @@ -128,52 +110,52 @@ int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) void Application::onButtonClick(int eventId, int x, int y, int flsgs, void *userData) { - if (eventId != EVENT_LBUTTONDOWN) - { - return; - } - Application* app = static_cast(userData); - - if (isButtonClicked(app->guiState.onButtonPlace, x, y)) + if (eventId != EVENT_LBUTTONDOWN) + { + return; + } + Application* app = static_cast(userData); + + if (isButtonClicked(app->guiState.onButtonPlace, x, y)) { - app->guiState.state = Application::OnFilter; + app->guiState.state = WindowState::OnFilter; return; } if (isButtonClicked(app->guiState.offButtonPlace, x, y)) { - app->guiState.state = Application::OffFilter; + app->guiState.state = WindowState::OffFilter; + return; + } + if (isButtonClicked(app->guiState.saveButtonPlace, x, y)) + { + std::stringstream ss; + ss << clock() << ".png"; + imwrite(ss.str(), *app->butonClickHandleArgs.dstBuf); + return; + } + if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Blur); + return; + } + if (isButtonClicked(app->guiState.filterCannyButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Canny); + return; + } + if (isButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Grayscale); + return; + } + if (isButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y)) + { + app->processor.setFilterType(FilterType::Pixelize); return; } - if (isButtonClicked(app->guiState.saveButtonPlace, x, y)) - { - std::stringstream ss; - ss << clock() << ".png"; - imwrite(ss.str(), *app->butonClickHandleArgs.dstBuf); - return; - } - if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) - { - app->processor.setFilterType(FilterType::Blur); - return; - } - if (isButtonClicked(app->guiState.filterCannyButtonPlace, x, y)) - { - app->processor.setFilterType(FilterType::Canny); - return; - } - if (isButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y)) - { - app->processor.setFilterType(FilterType::Grayscale); - return; - } - if (isButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y)) - { - app->processor.setFilterType(FilterType::Pixelize); - return; - } } -bool Application::isButtonClicked(cv::Rect buttonPlace, int x, int y) +bool Application::isButtonClicked(const Rect& buttonPlace, int x, int y) { if (x < buttonPlace.x || x > buttonPlace.x + buttonPlace.width || y < buttonPlace.y || y > buttonPlace.y + buttonPlace.height) diff --git a/sample_zhiltsov/application.hpp b/sample_zhiltsov/application.hpp index 9bb0f31..80e90b0 100644 --- a/sample_zhiltsov/application.hpp +++ b/sample_zhiltsov/application.hpp @@ -6,13 +6,11 @@ #include "processing.hpp" -bool onButtonClicked(cv::Rect buttonPlace, int x, int y); -void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData); class Application { - public: - enum WindowState +public: + enum class WindowState { OnFilter, OffFilter @@ -26,34 +24,31 @@ class Application WindowState state; cv::Rect onButtonPlace; cv::Rect offButtonPlace; - cv::Rect saveButtonPlace; - cv::Rect filterGrayscaleButtonPlace; - cv::Rect filterPixelizeButtonPlace; - cv::Rect filterCannyButtonPlace; - cv::Rect filterBlurButtonPlace; + cv::Rect saveButtonPlace; + cv::Rect filterGrayscaleButtonPlace; + cv::Rect filterPixelizeButtonPlace; + cv::Rect filterCannyButtonPlace; + cv::Rect filterBlurButtonPlace; }; - int parseArguments(int argc, const char **argv, Parameters ¶ms); - int getFrame(const std::string &fileName, cv::Mat& src); + int parseArguments(int argc, const char** argv, Parameters& params); + int getFrame(const std::string& fileName, cv::Mat& src); int processFrame(const cv::Mat& src, cv::Mat& dst); - int showFrame(const std::string &caption, + int showFrame(const std::string& caption, const cv::Mat& src, cv::Mat& dst); - Application() - { - guiState.state = OnFilter; - processor.setFilterType(FilterType::Blur); - }; - - private: + Application(); +private: Processing processor; GUIElementsState guiState; - struct ButonClickHandleArgs - { - cv::Mat* dstBuf; - }; - ButonClickHandleArgs butonClickHandleArgs; - static void onButtonClick(int eventId, int x, int y, int flags, void *userData); - static bool isButtonClicked(cv::Rect buttonPlace, int x, int y); + struct ButtonClickHandleArgs + { + cv::Mat* dstBuf; + }; + ButtonClickHandleArgs buttonClickHandleArgs; + int drawButtons(cv::Mat &display); + + static void onButtonClick(int eventId, int x, int y, int flags, void* userData); + static bool isButtonClicked(const cv::Rect& buttonPlace, int x, int y); }; diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index 839bb40..0ba31b5 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -2,114 +2,123 @@ #include #include -#include +#include using namespace cv; -void Processing::setFilterType(int value) +Processing::Processing(const FilterType& filterType_) : + filterType(filterType_) +{} + +void Processing::setFilterType(const FilterType& value) { - filterType = value; + filterType = value; +} + +void Processing::updateRoiPosition() +{ + region.x = src.rows/4 + region.x * std::abs(sin((double)clock())) * 0.1; + region.y = src.cols/4 + region.y * std::abs(cos((double)clock())) * 0.1; + + region.width = src.rows/2 + region.width * std::abs(sin((double)clock())) * 0.1; + region.height = src.cols/2 + region.height * std::abs(cos((double)clock())) * 0.1; } void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) { src.copyTo(dst); + const Mat roi = dst(region); + + switch (filterType) { + case FilterType::Blur: + applyBlurFilter(roi, roi); + break; + + case FilterType::Grayscale: + applyGrayscaleFilter(roi, roi); + break; + + case FilterType::Pixelize: + applyPixelizeFilter(roi, roi); + break; + + case FilterType::Canny: + applyCabbyFilter(roi, roi); + break; + + default: { throw std::exception("Unexpected filter type."); } + } - region.x = src.rows/4 + region.x * std::abs(sin((float)clock())) * 0.1; - region.y = src.cols/4 + region.y * std::abs(cos((float)clock())) * 0.1; - - region.width = src.rows/2 + region.width * std::abs(sin((float)clock())) * 0.1; - region.height = src.cols/2 + region.height * std::abs(cos((float)clock())) * 0.1; - - Mat roi = dst(region); - - switch (filterType) { - case FilterType::Blur: - { - const int kSize = 11; - medianBlur(roi, roi, kSize); - break; - } - case FilterType::Grayscale: - { - Mat newRoi = roi.clone(); - cvtColor(newRoi, newRoi, CV_BGR2GRAY); - std::vector channels(3); - channels[0] = newRoi; - channels[1] = newRoi; - channels[2] = newRoi; - merge(channels, roi); - break; - } - case FilterType::Pixelize: - { - pixelize(roi, roi); - break; - } - case FilterType::Canny: - { - const Size kSize(11, 11); - GaussianBlur(roi, roi, kSize, 5, 10); - - Mat newRoi = roi.clone(); - cvtColor(roi, newRoi, CV_BGR2GRAY); - - Canny(newRoi, newRoi, 10, 1); - - std::vector channels(3); - channels[0] = newRoi; - channels[1] = newRoi; - channels[2] = newRoi; - merge(channels, roi); - - break; - } - - default: { throw "Filter is not specefied."; } - } - - rectangle(dst, region, Scalar(255, 0, 0)); + rectangle(dst, region, CV_RGB(255, 0, 0)); } /* * Copy-pasted from: http://opencv-code.com/tutorials/photo-to-colored-dot-patterns-with-opencv/ */ -void Processing::pixelize(const Mat& src, Mat& dst) +void Processing::applyPixelizeFilter(const Mat& src, Mat& dst) { - cv::Mat cir = cv::Mat::zeros(src.size(), CV_8UC1); - int bsize = 10; + Mat cir = cv::Mat::zeros(src.size(), CV_8UC1); + const int bsize = 10; for (int i = 0; i < src.rows; i += bsize) { for (int j = 0; j < src.cols; j += bsize) { - cv::Rect rect = cv::Rect(j, i, bsize, bsize) & - cv::Rect(0, 0, src.cols, src.rows); + Rect rect = Rect(j, i, bsize, bsize) & + Rect(0, 0, src.cols, src.rows); - cv::Mat sub_dst(dst, rect); + Mat sub_dst(dst, rect); sub_dst.setTo(cv::mean(src(rect))); - cv::circle( + circle( cir, - cv::Point(j+bsize/2, i+bsize/2), + Point(j+bsize/2, i+bsize/2), bsize/2-1, CV_RGB(255,255,255), -1, CV_AA ); } } - cv::Mat cir_32f; + Mat cir_32f; cir.convertTo(cir_32f, CV_32F); - cv::normalize(cir_32f, cir_32f, 0, 1, cv::NORM_MINMAX); + normalize(cir_32f, cir_32f, 0, 1, NORM_MINMAX); - cv::Mat dst_32f; + Mat dst_32f; dst.convertTo(dst_32f, CV_32F); - std::vector channels; - cv::split(dst_32f, channels); + std::vector channels; + split(dst_32f, channels); for (int i = 0; i < channels.size(); ++i) channels[i] = channels[i].mul(cir_32f); - cv::merge(channels, dst_32f); + merge(channels, dst_32f); dst_32f.convertTo(dst, CV_8U); +} + +void Processing::applyCannyFilter(const Mat& src, Mat& dst) +{ + const Size kSize(11, 11); + GaussianBlur(src, dst, kSize, 5, 10); + + Mat newRoi = dst.clone(); + cvtColor(dst, newRoi, CV_BGR2GRAY); + Canny(newRoi, newRoi, 10, 1); + + const std::vector channels {newRoi, noewRoi, newRoi}; + merge(channels, dst); +} + +void Processing::applyGrayscaleFilter(const Mat& src, Mat& dst) +{ + Mat newRoi = src.clone(); + cvtColor(newRoi, newRoi, CV_BGR2GRAY); + + const std::vector channels {newRoi, noewRoi, newRoi}; + merge(channels, dst); +} + +void Processing::applyBlurFilter(const Mat& src, Mat& dst) +{ + const int kSize = 11; + medianBlur(roi, roi, kSize); } \ No newline at end of file diff --git a/sample_zhiltsov/processing.hpp b/sample_zhiltsov/processing.hpp index 9a46c17..1a414d3 100644 --- a/sample_zhiltsov/processing.hpp +++ b/sample_zhiltsov/processing.hpp @@ -2,24 +2,31 @@ #include -struct FilterType { - enum { - Grayscale, - Pixelize, - Canny, - Blur - }; -}; class Processing { - public: +public: + enum class FilterType { + Grayscale, + Pixelize, + Canny, + Blur + }; + + + Processing(const FilterType& filterType = FilterType::Blur); + void processFrame(const cv::Mat& src, cv::Mat& dst); - void setFilterType(int filterType); - private: - cv::Rect region; - int filterType; + void setFilterType(const FilterType& filterType); +private: + cv::Rect region; + FilterType filterType; + + void applyPixelizeFilter(const cv::Mat& src, cv::Mat& dst); + void applyCannyFilter(const cv::Mat& src, cv::Mat& dst); + void applyGrayscaleFilter(const cv::Mat& src, cv::Mat& dst); + void applyBlurFilter(const cv::Mat& src, cv::Mat& dst); - void pixelize(const cv::Mat& src, cv::Mat& dst); + void updateRoiPosition(); }; From 3ba9ed141dd8d3da3ea03374fe5adeb9d853e72f Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Wed, 19 Aug 2015 22:26:17 +0300 Subject: [PATCH 11/15] C++11 is again disabled =(. Fixes. --- sample_zhiltsov/application.hpp | 13 +++++++++---- sample_zhiltsov/processing.cpp | 19 ++++++++++++------- sample_zhiltsov/processing.hpp | 22 ++++++++++++++-------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/sample_zhiltsov/application.hpp b/sample_zhiltsov/application.hpp index 80e90b0..f03f9ff 100644 --- a/sample_zhiltsov/application.hpp +++ b/sample_zhiltsov/application.hpp @@ -10,18 +10,23 @@ class Application { public: - enum class WindowState + struct WindowState { - OnFilter, - OffFilter + enum + { + OnFilter, + OffFilter + }; }; + typedef int WindowState_t; + struct Parameters { std::string imgFileName; }; struct GUIElementsState { - WindowState state; + WindowState_t state; cv::Rect onButtonPlace; cv::Rect offButtonPlace; cv::Rect saveButtonPlace; diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index 0ba31b5..171f685 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -2,15 +2,14 @@ #include #include -#include using namespace cv; -Processing::Processing(const FilterType& filterType_) : +Processing::Processing(const FilterType_t& filterType_) : filterType(filterType_) {} -void Processing::setFilterType(const FilterType& value) +void Processing::setFilterType(const FilterType_t& value) { filterType = value; } @@ -43,7 +42,7 @@ void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) break; case FilterType::Canny: - applyCabbyFilter(roi, roi); + applyCannyFilter(roi, roi); break; default: { throw std::exception("Unexpected filter type."); } @@ -104,7 +103,10 @@ void Processing::applyCannyFilter(const Mat& src, Mat& dst) cvtColor(dst, newRoi, CV_BGR2GRAY); Canny(newRoi, newRoi, 10, 1); - const std::vector channels {newRoi, noewRoi, newRoi}; + const std::vector channels; + channels.push_back(newRoi); + channels.push_back(newRoi); + channels.push_back(newRoi); merge(channels, dst); } @@ -113,12 +115,15 @@ void Processing::applyGrayscaleFilter(const Mat& src, Mat& dst) Mat newRoi = src.clone(); cvtColor(newRoi, newRoi, CV_BGR2GRAY); - const std::vector channels {newRoi, noewRoi, newRoi}; + const std::vector channels; + channels.push_back(newRoi); + channels.push_back(newRoi); + channels.push_back(newRoi); merge(channels, dst); } void Processing::applyBlurFilter(const Mat& src, Mat& dst) { const int kSize = 11; - medianBlur(roi, roi, kSize); + medianBlur(src, dst, kSize); } \ No newline at end of file diff --git a/sample_zhiltsov/processing.hpp b/sample_zhiltsov/processing.hpp index 1a414d3..4585106 100644 --- a/sample_zhiltsov/processing.hpp +++ b/sample_zhiltsov/processing.hpp @@ -6,22 +6,28 @@ class Processing { public: - enum class FilterType { - Grayscale, - Pixelize, - Canny, - Blur + /* Wanted scoped enum here */ + struct FilterType + { + enum + { + Grayscale, + Pixelize, + Canny, + Blur + }; }; + typedef int FilterType_t; - Processing(const FilterType& filterType = FilterType::Blur); + Processing(const FilterType_t& filterType = FilterType::Blur); void processFrame(const cv::Mat& src, cv::Mat& dst); - void setFilterType(const FilterType& filterType); + void setFilterType(const FilterType_t& filterType); private: cv::Rect region; - FilterType filterType; + FilterType_t filterType; void applyPixelizeFilter(const cv::Mat& src, cv::Mat& dst); void applyCannyFilter(const cv::Mat& src, cv::Mat& dst); From f00e459aa72cea846c36bbe2b54616ab83771a1e Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Wed, 19 Aug 2015 22:35:05 +0300 Subject: [PATCH 12/15] Error fixes --- sample_zhiltsov/application.cpp | 8 ++++---- sample_zhiltsov/processing.cpp | 10 +++++----- sample_zhiltsov/processing.hpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index 3b05eaf..44e957a 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -47,11 +47,11 @@ int Application::processFrame(const Mat& src, Mat& dst) void create_button(const std::string& text, const Rect& rect, Mat& display) { - rectangle(display, guiState.onButtonPlace, Scalar(128, 128, 128), CV_FILLED); + rectangle(display, rect, Scalar(128, 128, 128), CV_FILLED); putText(display, text, Point(rect.x + rect.width / 2 - 15, rect.y + rect.height / 2 + 10), - FONT_HERSHEY_SIMPLEX, 1.0, CV_COLOR(0, 0, 0), 2); + FONT_HERSHEY_SIMPLEX, 1.0, CV_RGB(0, 0, 0), 2); } int Application::drawButtons(Mat& display) @@ -87,7 +87,7 @@ int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) processFrame(src, dst); break; - default: { throw std::exception("Unexpected window state."); } + default: { throw "Unexpected window state."; } Mat display(src.rows, src.cols + dst.cols, src.type()); Mat srcRoi = display(Rect(0, 0, src.cols, src.rows)); @@ -108,7 +108,7 @@ int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) return key; } -void Application::onButtonClick(int eventId, int x, int y, int flsgs, void *userData) +void Application::onButtonClick(int eventId, int x, int y, int flsgs, void* userData) { if (eventId != EVENT_LBUTTONDOWN) { diff --git a/sample_zhiltsov/processing.cpp b/sample_zhiltsov/processing.cpp index 171f685..9e89d15 100644 --- a/sample_zhiltsov/processing.cpp +++ b/sample_zhiltsov/processing.cpp @@ -14,7 +14,7 @@ void Processing::setFilterType(const FilterType_t& value) filterType = value; } -void Processing::updateRoiPosition() +void Processing::updateRoiPosition(const cv::Mat& src) { region.x = src.rows/4 + region.x * std::abs(sin((double)clock())) * 0.1; region.y = src.cols/4 + region.y * std::abs(cos((double)clock())) * 0.1; @@ -26,7 +26,7 @@ void Processing::updateRoiPosition() void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) { src.copyTo(dst); - const Mat roi = dst(region); + Mat roi = dst(region); switch (filterType) { case FilterType::Blur: @@ -45,7 +45,7 @@ void Processing::processFrame(const cv::Mat& src, cv::Mat& dst) applyCannyFilter(roi, roi); break; - default: { throw std::exception("Unexpected filter type."); } + default: { throw "Unexpected filter type."; } } rectangle(dst, region, CV_RGB(255, 0, 0)); @@ -103,7 +103,7 @@ void Processing::applyCannyFilter(const Mat& src, Mat& dst) cvtColor(dst, newRoi, CV_BGR2GRAY); Canny(newRoi, newRoi, 10, 1); - const std::vector channels; + std::vector channels; channels.push_back(newRoi); channels.push_back(newRoi); channels.push_back(newRoi); @@ -115,7 +115,7 @@ void Processing::applyGrayscaleFilter(const Mat& src, Mat& dst) Mat newRoi = src.clone(); cvtColor(newRoi, newRoi, CV_BGR2GRAY); - const std::vector channels; + std::vector channels; channels.push_back(newRoi); channels.push_back(newRoi); channels.push_back(newRoi); diff --git a/sample_zhiltsov/processing.hpp b/sample_zhiltsov/processing.hpp index 4585106..d809f96 100644 --- a/sample_zhiltsov/processing.hpp +++ b/sample_zhiltsov/processing.hpp @@ -34,5 +34,5 @@ class Processing void applyGrayscaleFilter(const cv::Mat& src, cv::Mat& dst); void applyBlurFilter(const cv::Mat& src, cv::Mat& dst); - void updateRoiPosition(); + void updateRoiPosition(const cv::Mat& src); }; From 7faf827b81e13db0a8081475df1774fec38e340e Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Wed, 19 Aug 2015 22:37:33 +0300 Subject: [PATCH 13/15] Fixes --- sample_zhiltsov/application.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index 44e957a..d0e8291 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -78,7 +78,8 @@ int Application::drawButtons(Mat& display) int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) { - switch (guiState.state) { + switch (guiState.state) + { case WindowState::OffFilter: src.copyTo(dst); break; @@ -88,6 +89,7 @@ int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst) break; default: { throw "Unexpected window state."; } + } Mat display(src.rows, src.cols + dst.cols, src.type()); Mat srcRoi = display(Rect(0, 0, src.cols, src.rows)); From 58a30baab1945be5659a766c5bf950059a09bc0c Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Wed, 19 Aug 2015 22:41:31 +0300 Subject: [PATCH 14/15] Fixes --- sample_zhiltsov/application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index d0e8291..b021316 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -132,7 +132,7 @@ void Application::onButtonClick(int eventId, int x, int y, int flsgs, void* user { std::stringstream ss; ss << clock() << ".png"; - imwrite(ss.str(), *app->butonClickHandleArgs.dstBuf); + imwrite(ss.str(), *app->buttonClickHandleArgs.dstBuf); return; } if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) From 029fddf2bc146c05bcd12d8bccbe7ed9b42253d9 Mon Sep 17 00:00:00 2001 From: zhiltsov-max Date: Wed, 19 Aug 2015 22:47:06 +0300 Subject: [PATCH 15/15] Fixes --- sample_zhiltsov/application.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sample_zhiltsov/application.cpp b/sample_zhiltsov/application.cpp index b021316..3d8325e 100644 --- a/sample_zhiltsov/application.cpp +++ b/sample_zhiltsov/application.cpp @@ -137,22 +137,22 @@ void Application::onButtonClick(int eventId, int x, int y, int flsgs, void* user } if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y)) { - app->processor.setFilterType(FilterType::Blur); + app->processor.setFilterType(Processing::FilterType::Blur); return; } if (isButtonClicked(app->guiState.filterCannyButtonPlace, x, y)) { - app->processor.setFilterType(FilterType::Canny); + app->processor.setFilterType(Processing::FilterType::Canny); return; } if (isButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y)) { - app->processor.setFilterType(FilterType::Grayscale); + app->processor.setFilterType(Processing::FilterType::Grayscale); return; } if (isButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y)) { - app->processor.setFilterType(FilterType::Pixelize); + app->processor.setFilterType(Processing::FilterType::Pixelize); return; } }