diff --git a/include/image_processing.hpp b/include/image_processing.hpp index ca1f116..09e8f56 100644 --- a/include/image_processing.hpp +++ b/include/image_processing.hpp @@ -5,6 +5,7 @@ #include "opencv2/core/core.hpp" + class ImageProcessor { public: virtual cv::Mat CvtColor(const cv::Mat &src, const cv::Rect &roi) = 0; @@ -15,4 +16,15 @@ class ImageProcessor { const int kernelSize) = 0; virtual cv::Mat Pixelize(const cv::Mat &src, const cv::Rect &roi, const int kDivs) = 0; +}; +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/samples/devtools_demo.cpp b/samples/devtools_demo.cpp deleted file mode 100644 index 8c40769..0000000 --- a/samples/devtools_demo.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include - -#include "opencv2/core.hpp" -#include "opencv2/highgui.hpp" - -#include "workaround.hpp" - -using namespace std; -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 }"; - -int main(int argc, const char** argv) { - // Parse command line arguments. - CommandLineParser parser(argc, argv, kOptions); - parser.about(kAbout); - - // If help option is given, print help message and exit. - if (parser.has("help")) { - parser.printMessage(); - return 0; - } - - // Read image. - Mat src = imread(parser.get(0), CV_LOAD_IMAGE_GRAYSCALE); - if (src.empty()) { - cout << "Failed to open image file '" + parser.get(0) + "'." - << endl; - return 0; - } - - // Show source image. - const string kSrcWindowName = "Source image"; - const int kWaitKeyDelay = 1; - namedWindow(kSrcWindowName, WINDOW_NORMAL); - resizeWindow(kSrcWindowName, 640, 480); - 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; - } - - // Show destination image. - const string kDstWindowName = "Destination image"; - namedWindow(kDstWindowName, WINDOW_NORMAL); - resizeWindow(kDstWindowName, 640, 480); - imshow(kDstWindowName, src); - waitKey(); - - return 0; -} diff --git a/samples/imgproc_demo.cpp b/samples/imgproc_demo.cpp new file mode 100644 index 0000000..59eb25c --- /dev/null +++ b/samples/imgproc_demo.cpp @@ -0,0 +1,137 @@ +#include +#include +#include +#include "opencv2/core.hpp" +#include "opencv2/opencv.hpp" +using namespace std; +using namespace cv; + +const char* kAbout = +"This is an empty application that can be treated as a template for your " +"own doing-something-cool applications."; + +const char* kOptions = +"{ @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 }"; + +struct MouseCallbackState +{ + bool is_selection_started; + bool is_selection_finished; + Point point_first; + Point point_second; +}; + +void OnMouse(int event, int x, int y, int flags, void* param) +{ + MouseCallbackState* mouse = (MouseCallbackState*)param; + + switch (event) + { + case EVENT_LBUTTONDOWN: + + mouse->is_selection_started = true; + mouse->is_selection_finished = false; + mouse->point_first.x = x; + mouse->point_first.y = y; + break; + + case EVENT_LBUTTONUP: + + mouse->is_selection_started = false; + mouse->is_selection_finished = true; + if (mouse->point_first.x != x && mouse->point_first.y != y) + { + mouse->point_second.x = x; + mouse->point_second.y = y; + } + break; + + case EVENT_MOUSEMOVE: + + if (mouse->is_selection_finished == false) + { + mouse->point_second.x = x; + mouse->point_second.y = y; + } + break; + } + +} + +int main(int argc, const char** argv) +{ + // Parse command line arguments. + CommandLineParser parser(argc, argv, kOptions); + parser.about(kAbout); + + // If help option is given, print help message and exit. + if (parser.get("help")) + { + parser.printMessage(); + return 0; + } + + Mat img, src, dst; + MouseCallbackState p; + ImageProcessorImpl obj; + Rect roi; + char c; + + string imageName(parser.get(0)); + img = imread(imageName.c_str(), 1); + if (img.empty()) + { + cout << "Could not open or find the image" << std::endl; + return -1; + } + + imshow("Original", img); + setMouseCallback("Original", OnMouse, &p); + while (1) + { + while (1) + { + c = waitKey(100); + roi = Rect(p.point_first, p.point_second); + if ((p.point_first.x < p.point_second.x) && (p.point_first.y < p.point_second.y) && !roi.empty()) break; + } + + if (!roi.empty() && ((roi & Rect(0, 0, img.cols, img.rows)) == roi)) + { + if (parser.has("gray")) + { + dst = obj.CvtColor(img, roi); + } + else + if (parser.has("median")) + { + int _size = 11;// size must be odd + dst = obj.Filter(img, roi, 11); + } + else + if (parser.has("edges")) + { + int _filter_size = 1, + _low_threshold = 50, + _ratio = 4, + _ksize = 1; + dst = obj.DetectEdges(img, roi, _filter_size, _low_threshold, _ratio, _ksize); + } + else + if (parser.has("pix")) + { + int _divs = 11; + dst = obj.Pixelize(img, roi, _divs); + } + imshow("Result", dst); + } + if (c == 27) break; + } +return 0; +} + diff --git a/samples/template_demo.cpp b/samples/template_demo.cpp deleted file mode 100644 index 3b9eb74..0000000 --- a/samples/template_demo.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "opencv2/core.hpp" - -using namespace std; -using namespace cv; - -const char* kAbout = - "This is an empty application that can be treated as a template for your " - "own doing-something-cool applications."; - -const char* kOptions = - "{ v video | | video to process }" - "{ h ? help usage | | print help message }"; - - -int main(int argc, const char** argv) { - // Parse command line arguments. - CommandLineParser parser(argc, argv, kOptions); - parser.about(kAbout); - - // If help option is given, print help message and exit. - if (parser.get("help")) { - parser.printMessage(); - return 0; - } - - // Do something cool. - cout << "This is empty template sample." << endl; - - return 0; -} diff --git a/src/image_processing.cpp b/src/image_processing.cpp new file mode 100644 index 0000000..f56ff8a --- /dev/null +++ b/src/image_processing.cpp @@ -0,0 +1,70 @@ +#include "image_processing.hpp" +#include "opencv2/opencv.hpp" +#include +using namespace cv; + +Mat ImageProcessorImpl::CvtColor(const Mat &src, const Rect &roi) +{ + Mat src_copy = src.clone(); + Mat src_copy_roi = src_copy(roi); + Mat dst_roi = src_copy_roi.clone(), dst_gray_roi; + std::vector channels; + + cvtColor(src_copy_roi, dst_gray_roi, COLOR_BGR2GRAY); + + channels.push_back(dst_gray_roi); + channels.push_back(dst_gray_roi); + channels.push_back(dst_gray_roi); + + merge(channels, dst_roi); + dst_roi.copyTo(src_copy_roi); + return src_copy; +} + +cv::Mat ImageProcessorImpl::Filter(const Mat &src, const Rect &roi, const int size) +{ + Mat src_copy = src.clone(); + Mat src_copy_roi = src_copy(roi); + + medianBlur(src_copy_roi,src_copy_roi,size); + + return src_copy; + +} + +Mat ImageProcessorImpl::DetectEdges(const Mat &src, const Rect &roi, + const int filterSize, const int lowThreshold, const int ratio, + const int kernelSize) +{ + Mat src_copy = src.clone(); + Mat src_copy_roi = src_copy(roi); + Mat src_gray_roi, gray_blurred, detected_edges, dst, dst_roi; + Size a(kernelSize, kernelSize); + + cvtColor(src_copy_roi, src_gray_roi, COLOR_BGR2GRAY); + blur(src_gray_roi, gray_blurred, a); + Canny(gray_blurred, detected_edges, lowThreshold, lowThreshold*ratio); + + dst = src.clone(); + dst_roi = dst(roi); + dst_roi = Scalar::all(0); + src_copy_roi.copyTo(dst_roi, detected_edges); + return dst; +} + +cv::Mat ImageProcessorImpl::Pixelize(const cv::Mat & src, const cv::Rect & roi, const int divs) +{ + Mat src_copy = src.clone(); + Mat src_copy_roi = src_copy(roi); + int block_size_x = (int)(roi.width / divs), block_size_y = (int)(roi.height / divs); + Size kernSize(block_size_x, block_size_y); + + for(int x = 0; x < src_copy_roi.cols - block_size_x; x += block_size_x) + for (int y = 0; y < src_copy_roi.rows - block_size_y ; y += block_size_y) + { + Mat src_roi_block = src_copy_roi(Rect(x,y,block_size_x,block_size_y)); + blur(src_roi_block, src_roi_block, kernSize); + } + + return src_copy; +} \ No newline at end of file diff --git a/src/workaround.cpp b/src/workaround.cpp index 2eba458..f03e0e7 100644 --- a/src/workaround.cpp +++ b/src/workaround.cpp @@ -1,5 +1,4 @@ #include "workaround.hpp" - #include using namespace std;