diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a1949c..5ab9257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ find_package(OpenCV REQUIRED) set(LIBRARY_DEPS ${OpenCV_LIBS}) # BUILD -add_subdirectory(sample_template) +add_subdirectory(sample_Renat) # Add you directory here # add_subdirectory(sample_YOUR_NAME) diff --git a/sample_template/CMakeLists.txt b/sample_Renat/CMakeLists.txt similarity index 100% rename from sample_template/CMakeLists.txt rename to sample_Renat/CMakeLists.txt diff --git a/sample_Renat/application.cpp b/sample_Renat/application.cpp new file mode 100644 index 0000000..f12cef2 --- /dev/null +++ b/sample_Renat/application.cpp @@ -0,0 +1,194 @@ +#include "application.hpp" +#include "processing.hpp" + +#include +#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); + resize(src, src, Size(500, 500)); + if (src.empty()) + { + return 1; + } + return 0; +} + +int Application::processFrame(const Mat& src, Mat& dst, int t, Processing::FilterType filter) +{ + processor.processFrame(src, dst, t, filter); + + 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); + guiState.saveButtonPlace = Rect(300, display.rows - 60, 120, 40); + guiState.grayButtonPlace = Rect(440, display.rows - 60, 120, 40); + guiState.pixButtonPlace = Rect(580, display.rows - 60, 120, 40); + guiState.cannyButtonPlace = Rect(720, 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); + rectangle(display, guiState.grayButtonPlace, + Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.pixButtonPlace, + Scalar(128, 128, 128), CV_FILLED); + rectangle(display, guiState.cannyButtonPlace, + Scalar(128, 128, 128), CV_FILLED); + + putText(display, "median", + Point(guiState.onButtonPlace.x + guiState.onButtonPlace.width / 2 - 35, + 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 - 30, + guiState.saveButtonPlace.y + guiState.saveButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "gray", + Point(guiState.grayButtonPlace.x + guiState.grayButtonPlace.width / 2 - 30, + guiState.grayButtonPlace.y + guiState.grayButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "pixel", + Point(guiState.pixButtonPlace.x + guiState.pixButtonPlace.width / 2 - 30, + guiState.pixButtonPlace.y + guiState.pixButtonPlace.height / 2 + 10), + FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 0), 2); + putText(display, "canny", + Point(guiState.cannyButtonPlace.x + guiState.cannyButtonPlace.width / 2 - 30, + guiState.cannyButtonPlace.y + guiState.cannyButtonPlace.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 t) +{ + if (guiState.state == OffFilter) + { + src.copyTo(dst); + } + else if (guiState.state == OnFilter) + { + if(guiState.filter == Processing::MEDIAN) + processFrame(src, dst, t, Processing::MEDIAN); + if(guiState.filter == Processing::CVT_CONVERT_GRAY) + processFrame(src, dst, t, Processing::CVT_CONVERT_GRAY); + if(guiState.filter == Processing::PIXELIZED) + processFrame(src, dst, t, Processing::PIXELIZED); + if(guiState.filter == Processing::CANNY) + processFrame(src, dst, t, Processing::CANNY); + + } + 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); + + if (guiState.saveState) + { + imwrite("out.png", display); + guiState.saveState = false; + } + + 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; + elems->filter = Processing::MEDIAN; + return; + } + if (onButtonClicked(elems->grayButtonPlace, x, y)) + { + elems->state = Application::OnFilter; + elems->filter = Processing::CVT_CONVERT_GRAY; + return; + } + if (onButtonClicked(elems->pixButtonPlace, x, y)) + { + elems->state = Application::OnFilter; + elems->filter = Processing::PIXELIZED; + return; + } + if (onButtonClicked(elems->cannyButtonPlace, x, y)) + { + elems->state = Application::OnFilter; + elems->filter = Processing::CANNY; + return; + } + if (onButtonClicked(elems->saveButtonPlace, x, y)) + { + elems->saveState = true; + 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_template/application.hpp b/sample_Renat/application.hpp similarity index 74% rename from sample_template/application.hpp rename to sample_Renat/application.hpp index 862cc3f..7a6e895 100644 --- a/sample_template/application.hpp +++ b/sample_Renat/application.hpp @@ -26,17 +26,25 @@ class Application WindowState state; cv::Rect onButtonPlace; cv::Rect offButtonPlace; + cv::Rect saveButtonPlace; + cv::Rect grayButtonPlace; + cv::Rect pixButtonPlace; + cv::Rect cannyButtonPlace; + bool saveState; + Processing::FilterType filter; }; 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 processFrame(const cv::Mat& src, cv::Mat& dst, int t, Processing::FilterType filter); int showFrame(const std::string &caption, - const cv::Mat& src, cv::Mat& dst); + const cv::Mat& src, cv::Mat& dst, int t); friend void onButtonsOnOffClick(int eventId, int x, int y, int flags, void *userData); Application() { guiState.state = OnFilter; + guiState.saveState = false; + guiState.filter = Processing::MEDIAN; }; private: diff --git a/sample_template/main.cpp b/sample_Renat/main.cpp similarity index 89% rename from sample_template/main.cpp rename to sample_Renat/main.cpp index 43ff041..8ca3bd1 100644 --- a/sample_template/main.cpp +++ b/sample_Renat/main.cpp @@ -35,9 +35,11 @@ int main(int argc, const char **argv) const std::string caption = "OpenCV Sample"; char key = 0; Mat dst(src.rows, src.cols, src.type()); + long long time = 0; while (key != 27) // Esc { - key = app.showFrame(caption, src, dst); + key = app.showFrame(caption, src, dst, time); + time += rand() % 21 - 10; } return OK; diff --git a/sample_Renat/processing.cpp b/sample_Renat/processing.cpp new file mode 100644 index 0000000..3fd7920 --- /dev/null +++ b/sample_Renat/processing.cpp @@ -0,0 +1,89 @@ +#include "processing.hpp" + +#include + +#include + +using namespace cv; + +void Processing::pixelize(const cv::Mat& src, cv::Mat& dst) +{ + int n = 40; + for(int i = 0; i < src.rows - n; i += n) + { + for(int j = 0; j < src.cols - n; j += n) + { + Rect roi(i, j, n, n); + blur(src(roi), dst(roi), Size(n, n)); + } + } + + int deltacol = src.cols % n; + if (deltacol != 0) + { + for(int j = 0; j < src.cols - n; j += n) + { + Rect roi(src.cols - deltacol, j, deltacol - 1, n); + blur(src(roi), dst(roi), Size(deltacol - 1, n)); + } + } + int deltarow = src.rows % n; + if (deltarow != 0) + { + for(int j = 0; j < src.rows - n; j += n) + { + Rect roi(j, src.rows - deltarow, n, deltarow - 1); + blur(src(roi), dst(roi), Size(n, deltarow - 1)); + } + } + Rect roi(src.cols - deltacol, src.rows - deltarow, deltacol - 1, deltarow - 1); + blur(src(roi), dst(roi), Size(deltacol - 1, deltarow - 1)); + + + + + } +void Processing::processFrame(const cv::Mat& src, cv::Mat& dst, int t, FilterType filter) +{ + src.copyTo(dst); + + cv::Rect region(src.rows/4 + t / 5, src.cols/4 + t / 5, src.rows/2, src.cols/2); + Mat roi = dst(region); + + const int kSize = 11; + switch(filter) + { + case MEDIAN: + { + medianBlur(roi, roi, kSize); + + break; + } + case CVT_CONVERT_GRAY: + { + Mat gray_patch; + cvtColor(roi, gray_patch, cv::COLOR_BGR2GRAY); + cvtColor(gray_patch, roi, cv::COLOR_GRAY2BGR); + + break; + } + case PIXELIZED: + { + //GaussianBlur(roi, roi, Size( 19, 19 ), 0, 0 ); + pixelize(roi, roi); + break; + } + case CANNY: + { + Mat gray_patch; + cvtColor(roi, gray_patch, cv::COLOR_BGR2GRAY); + Canny(gray_patch, gray_patch, 0, 59); + cvtColor(gray_patch, roi, cv::COLOR_GRAY2BGR); + + break; + } + default: + break; +} + rectangle(dst, region, Scalar(255, 0, 0)); +} diff --git a/sample_Renat/processing.hpp b/sample_Renat/processing.hpp new file mode 100644 index 0000000..a37792a --- /dev/null +++ b/sample_Renat/processing.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +class Processing +{ + public: + enum FilterType + { + MEDIAN, + CVT_CONVERT_GRAY, + PIXELIZED, + CANNY + }; + void processFrame(const cv::Mat& src, cv::Mat& dst, int t, FilterType filter); + void pixelize(const cv::Mat& src, cv::Mat& dst); + +}; diff --git a/sample_template/application.cpp b/sample_template/application.cpp deleted file mode 100644 index 4cc18d1..0000000 --- a/sample_template/application.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#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_template/processing.cpp b/sample_template/processing.cpp deleted file mode 100644 index bd51a88..0000000 --- a/sample_template/processing.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#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_template/processing.hpp b/sample_template/processing.hpp deleted file mode 100644 index 65f29fc..0000000 --- a/sample_template/processing.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -class Processing -{ - public: - void processFrame(const cv::Mat& src, cv::Mat& dst); -}; diff --git a/testdata/image.png b/testdata_Renat/image.png similarity index 100% rename from testdata/image.png rename to testdata_Renat/image.png