diff --git a/include/ImageProcessorImpl.hpp b/include/ImageProcessorImpl.hpp new file mode 100644 index 0000000..a82b579 --- /dev/null +++ b/include/ImageProcessorImpl.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "image_processing.hpp" + + +class ImageProcessorImpl : public ImageProcessor { +public: + virtual cv::Mat CvtColor(const cv::Mat &src, const cv::Rect &roi); + virtual cv::Mat Filter(const cv::Mat &src, const cv::Rect &roi, + const int size); + virtual cv::Mat DetectEdges(const cv::Mat &src, const cv::Rect &roi, + const int filter_size, const int low_threshold, + const int ratio, const int kernel_size); + virtual cv::Mat Pixelize(const cv::Mat &src, const cv::Rect &roi, + const int divs); +}; \ No newline at end of file diff --git a/include/image_processing.hpp b/include/image_processing.hpp index ca1f116..decb020 100644 --- a/include/image_processing.hpp +++ b/include/image_processing.hpp @@ -4,6 +4,7 @@ #include #include "opencv2/core/core.hpp" +#include class ImageProcessor { public: diff --git a/include/workaround.hpp b/include/workaround.hpp index 18ffbc4..8e41ef6 100644 --- a/include/workaround.hpp +++ b/include/workaround.hpp @@ -1,5 +1,7 @@ #pragma once + + class MatrixProcessor { public: void Threshold(unsigned char* const data, const int width, const int height, diff --git a/samples/devtools_demo.cpp b/samples/devtools_demo.cpp index 8c40769..ef02057 100644 --- a/samples/devtools_demo.cpp +++ b/samples/devtools_demo.cpp @@ -4,6 +4,8 @@ #include "opencv2/core.hpp" #include "opencv2/highgui.hpp" +#include "ImageProcessorImpl.hpp" + #include "workaround.hpp" using namespace std; @@ -12,9 +14,33 @@ using namespace cv; const char* kAbout = "Application for practice #1."; const char* kOptions = - "{ @image | | image to process }" - "{ t | 128 | threshold }" - "{ h ? help usage | | print help message }"; + "{ @image | | image to process }" + "{ gray | | convert ROI to gray scale }" + "{ median | | apply median filter for ROI }" + "{ edges | | detect edges in ROI }" + "{ pix | | pixelize ROI }" + "{ h ? help usage | | print help message }"; + + + +Rect_ roi; +void CallBackFunc(int event, int x, int y, int flags, void* userdata) +{ + + if (event == EVENT_LBUTTONDOWN) + { + static vector points; + points.push_back(Point_(x,y)); + if (points.size() > 1) { + roi = Rect2i(points[0], points[1]); + points.clear(); + } + } + +} + + + int main(int argc, const char** argv) { // Parse command line arguments. @@ -28,7 +54,7 @@ int main(int argc, const char** argv) { } // Read image. - Mat src = imread(parser.get(0), CV_LOAD_IMAGE_GRAYSCALE); + Mat src = imread(parser.get(0)); if (src.empty()) { cout << "Failed to open image file '" + parser.get(0) + "'." << endl; @@ -40,25 +66,27 @@ int main(int argc, const char** argv) { const int kWaitKeyDelay = 1; namedWindow(kSrcWindowName, WINDOW_NORMAL); resizeWindow(kSrcWindowName, 640, 480); + + + setMouseCallback(kSrcWindowName, CallBackFunc, NULL); imshow(kSrcWindowName, src); - waitKey(kWaitKeyDelay); - - // Threshold data. - MatrixProcessor processor; - const int threshold = parser.get("t"); - try { - processor.Threshold(src.data, src.cols, src.rows, threshold); - } catch (const std::exception& ex) { - cout << ex.what() << endl; - return 0; + + + while (true) { + waitKey(1); + if (!roi.empty()) break; } + const string newWindowName = "filter"; + ImageProcessorImpl newFiltr; + //Mat img = newFiltr.CvtColor(src, roi); + //Mat img = newFiltr.Filter(src, roi, 7); + Mat img = newFiltr.DetectEdges(src, roi, 2, 75, 3 , 5); + //Mat img = newFiltr.Pixelize(src, roi, 15); + namedWindow(newWindowName, WINDOW_NORMAL); + resizeWindow(newWindowName, 640, 480); + imshow(newWindowName, img); - // Show destination image. - const string kDstWindowName = "Destination image"; - namedWindow(kDstWindowName, WINDOW_NORMAL); - resizeWindow(kDstWindowName, 640, 480); - imshow(kDstWindowName, src); - waitKey(); - + + waitKey(0); return 0; } diff --git a/src/ImageProcessorImpl.cpp b/src/ImageProcessorImpl.cpp new file mode 100644 index 0000000..55cc108 --- /dev/null +++ b/src/ImageProcessorImpl.cpp @@ -0,0 +1,68 @@ +#include "ImageProcessorImpl.hpp" + +cv::Mat ImageProcessorImpl::CvtColor(const cv::Mat &src, const cv::Rect &roi) { + + cv::Mat src_tmp = src.clone(); + cv::Mat src_tmp_roi = src_tmp(roi); + cv::Mat dst_roi_green = src_tmp_roi.clone(); + std::vector channels; + + cv::cvtColor(src_tmp_roi, dst_roi_green, cv::COLOR_BGR2GRAY); + channels.push_back(dst_roi_green); + channels.push_back(dst_roi_green); + channels.push_back(dst_roi_green); + cv::merge(channels, src_tmp_roi); + + return src_tmp; +} + +cv::Mat ImageProcessorImpl::DetectEdges(const cv::Mat &src, const cv::Rect &roi, + const int filter_size, const int low_threshold, + const int ratio, const int kernel_size) { + + + cv::Mat src_tmp = src.clone(); + cv::Mat src_tmp_roi = src_tmp(roi); + cv::Mat src_roi_green = src_tmp_roi.clone(); + cv::Mat gray_blurred; + cv::Mat detected_edges; + + + cv::cvtColor(src_tmp_roi, src_roi_green, cv::COLOR_BGR2GRAY); + cv::blur(src_roi_green, gray_blurred, cv::Size(kernel_size, kernel_size)); + cv::Canny(gray_blurred, detected_edges, 0, 50); + + cv::Mat dst = src.clone(); + cv::Mat dst_roi = dst(roi); + dst_roi = cv::Scalar::all(0); + src_tmp_roi.copyTo(dst_roi, detected_edges); + + return dst; +} + + +cv::Mat ImageProcessorImpl::Filter(const cv::Mat &src, const cv::Rect &roi, + const int size) { + + cv::Mat src_tmp = src.clone(); + cv::Mat src_tmp_roi = src_tmp(roi); + cv::medianBlur(src_tmp_roi, src_tmp_roi, size); + + return src_tmp; +} + +cv::Mat ImageProcessorImpl::Pixelize(const cv::Mat &src, const cv::Rect &roi, + const int divs) { + cv::Mat src_tmp = src.clone(); + cv::Mat src_tmp_roi = src_tmp(roi); + const int block_size_x = roi.width / divs, block_size_y = roi.height / divs; + + for (int x = 0; x < src_tmp_roi.cols - block_size_x ; x += block_size_x) + for (int y = 0; y < src_tmp_roi.rows - block_size_y; y += block_size_y) { + cv::Mat src_roi_block = src_tmp_roi(cv::Rect(x, y, block_size_x, block_size_y)); + cv::blur(src_roi_block, src_roi_block, cv::Size(block_size_x, block_size_y)); + } + + return src_tmp; + +} \ No newline at end of file