From 61d283af615e4c94d3ccebd1c32cf7ea1b2055c3 Mon Sep 17 00:00:00 2001 From: JuliaKamelina Date: Mon, 16 Oct 2017 00:57:57 +0300 Subject: [PATCH 1/4] almost done --- include/image_processing.hpp | 14 ++++- samples/template_demo.cpp | 105 ++++++++++++++++++++++++++++++++--- 2 files changed, 111 insertions(+), 8 deletions(-) diff --git a/include/image_processing.hpp b/include/image_processing.hpp index ca1f116..39ec22e 100644 --- a/include/image_processing.hpp +++ b/include/image_processing.hpp @@ -15,4 +15,16 @@ class ImageProcessor { const int kernelSize) = 0; virtual cv::Mat Pixelize(const cv::Mat &src, const cv::Rect &roi, const int kDivs) = 0; -}; \ No newline at end of file +}; + +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); +}; diff --git a/samples/template_demo.cpp b/samples/template_demo.cpp index 3b9eb74..8badb19 100644 --- a/samples/template_demo.cpp +++ b/samples/template_demo.cpp @@ -2,18 +2,56 @@ #include #include "opencv2/core.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/imgproc.hpp" +#include "image_processing.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* kAbout = "solution for lab2"; const char* kOptions = - "{ v video | | video to process }" - "{ 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 }"; +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, void *param) { + MouseCallbackState* m = (MouseCallbackState*)param; + + switch (event) { + case EVENT_LBUTTONDOWN: + m->is_selection_started = true; + m->is_selection_finished = false; + m->point_first.x = x; + m->point_first.y = y; + break; + + case EVENT_LBUTTONUP: + m->is_selection_started = false; + m->is_selection_finished = true; + m->point_second.x = x; + m->point_second.y = y; + break; + + case EVENT_MOUSEMOVE: + if (m->is_selection_started == true && m->is_selection_finished == false){ + m->point_second.x = x; + m->point_second.y = y; + } + break; + } +} int main(int argc, const char** argv) { // Parse command line arguments. @@ -26,8 +64,61 @@ int main(int argc, const char** argv) { return 0; } - // Do something cool. - cout << "This is empty template sample." << endl; + // Read image. + Mat src = imread(parser.get(0), IMREAD_COLOR); + if (src.empty()) { + cout << "Failed to open image file '" + parser.get(0) + "'." + << endl; + return 0; + } + + // Show source image. + string kSrcWindowName = "Source image"; + int kWaitKeyDelay = 1; + namedWindow(kSrcWindowName, WINDOW_NORMAL); + MouseCallbackState mouse; + mouse.is_selection_started = false; + mouse.is_selection_finished = false; + + setMouseCallback(kSrcWindowName, OnMouse, &mouse); + imshow(kSrcWindowName, src); + + while (!mouse.is_selection_finished) { + waitKey(100); + } + + Mat cSrc; + Rect selected = Rect(mouse.point_first, mouse.point_second); + src.copyTo(cSrc); + rectangle(cSrc, selected, Scalar(0, 0, 255), 1, LINE_AA); + + imshow(kSrcWindowName, cSrc); + waitKey(10); + + ImageProcessorImpl processor; + + if (parser.get("gray")) { + kSrcWindowName = "gray image"; + namedWindow(kSrcWindowName, WINDOW_NORMAL); + imshow(kSrcWindowName, processor.CvtColor(src, selected)); + } else + if (parser.get("median")) { + kSrcWindowName = "madian image"; + kWaitKeyDelay = 1; + namedWindow(kSrcWindowName, WINDOW_NORMAL); + imshow(kSrcWindowName, processor.Filter(src, selected, 15)); + } else + if (parser.get("edges")) { + kSrcWindowName = "edges image"; + namedWindow(kSrcWindowName, WINDOW_NORMAL); + imshow(kSrcWindowName, processor.DetectEdges(src, selected, 3, 50, 3, 3)); + } else + if (!parser.get("pix")) { + kSrcWindowName = "pix image"; + namedWindow(kSrcWindowName, WINDOW_NORMAL); + imshow(kSrcWindowName, processor.Pixelize(src, selected, 10)); + } + waitKey(); return 0; } From 3a5ddf17445c9758432a8e9ac46e2f1e87bec73d Mon Sep 17 00:00:00 2001 From: JuliaKamelina Date: Mon, 16 Oct 2017 10:23:19 +0300 Subject: [PATCH 2/4] add image_processing --- samples/template_demo.cpp | 2 +- src/image_processing.cpp | 80 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/image_processing.cpp diff --git a/samples/template_demo.cpp b/samples/template_demo.cpp index 8badb19..981a2b0 100644 --- a/samples/template_demo.cpp +++ b/samples/template_demo.cpp @@ -113,7 +113,7 @@ int main(int argc, const char** argv) { namedWindow(kSrcWindowName, WINDOW_NORMAL); imshow(kSrcWindowName, processor.DetectEdges(src, selected, 3, 50, 3, 3)); } else - if (!parser.get("pix")) { + if (parser.get("pix")) { kSrcWindowName = "pix image"; namedWindow(kSrcWindowName, WINDOW_NORMAL); imshow(kSrcWindowName, processor.Pixelize(src, selected, 10)); diff --git a/src/image_processing.cpp b/src/image_processing.cpp new file mode 100644 index 0000000..8e9f77e --- /dev/null +++ b/src/image_processing.cpp @@ -0,0 +1,80 @@ +#include "image_processing.hpp" + +#include + +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" + +using cv::Mat; +using cv::Rect; +using std::vector; + +Mat ImageProcessorImpl::CvtColor(const Mat &src, const Rect &roi) { + Mat src_copy; + src.copyTo(src_copy); + + Mat src_roi = src_copy(roi), dst_gray_roi; + cvtColor(src_roi, dst_gray_roi, CV_BGR2GRAY); + + vector channels; + channels.push_back(dst_gray_roi); + channels.push_back(dst_gray_roi); + channels.push_back(dst_gray_roi); + Mat dst_roi; + merge(channels, dst_roi); + + dst_roi.copyTo(src_roi); + + return src_copy; +} + +Mat ImageProcessorImpl::Filter(const Mat &src, const Rect &roi, + const int size) { + Mat src_copy; + src.copyTo(src_copy); + + Mat src_roi = src_copy(roi); + blur(src_roi, src_roi, cv::Size(size, size)); + + return src_copy; +} + +Mat ImageProcessorImpl::DetectEdges(const Mat &src, const Rect &roi, + const int size, const int low_threshold, + const int ratio, const int kernel_size) { + Mat src_roi = src(roi), src_gray_roi; + cvtColor(src_roi, src_gray_roi, CV_BGR2GRAY); + + Mat gray_blurred; + + blur(src_gray_roi, gray_blurred, cv::Size(size, size)); + + Mat detected_edges; + Canny(gray_blurred, detected_edges, low_threshold, low_threshold * ratio, + kernel_size); + + Mat dst; + src.copyTo(dst); + Mat dst_roi = dst(roi); + dst_roi = cv::Scalar::all(0); + src_roi.copyTo(dst_roi, detected_edges); + + return dst; +} + +Mat ImageProcessorImpl::Pixelize(const Mat &src, const Rect &roi, + const int divs) { + Mat src_copy; + src.copyTo(src_copy); + Mat src_copy_roi = src_copy(roi); + + int block_size_x = roi.width / divs, block_size_y = roi.height / divs; + for (int x = 0; x < roi.width - block_size_x; x += block_size_x) { + for (int y = 0; y < roi.height - 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, cv::Size(block_size_x, block_size_y)); + } + } + + return src_copy; +} From f5407a929bd96975f1f37b0edef6170853472559 Mon Sep 17 00:00:00 2001 From: JuliaKamelina Date: Tue, 17 Oct 2017 00:52:37 +0300 Subject: [PATCH 3/4] video processing --- samples/video_proc.cpp | 143 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 samples/video_proc.cpp diff --git a/samples/video_proc.cpp b/samples/video_proc.cpp new file mode 100644 index 0000000..0fcb7b6 --- /dev/null +++ b/samples/video_proc.cpp @@ -0,0 +1,143 @@ +#include +#include + +#include "opencv2/core.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/imgproc.hpp" +#include "image_processing.hpp" + +using namespace std; +using namespace cv; + +const char* kAbout = "solution for lab2"; + +const char* kOptions = +"{ video | | 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, void *param) { + MouseCallbackState* m = (MouseCallbackState*)param; + + switch (event) { + case EVENT_LBUTTONDOWN: + m->is_selection_started = true; + m->is_selection_finished = false; + m->point_first.x = x; + m->point_first.y = y; + break; + + case EVENT_LBUTTONUP: + m->is_selection_started = false; + m->is_selection_finished = true; + m->point_second.x = x; + m->point_second.y = y; + break; + + case EVENT_MOUSEMOVE: + if (m->is_selection_started == true && m->is_selection_finished == false) { + m->point_second.x = x; + m->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; + } + + VideoCapture cap; + string path = parser.get("video"); + cap.open(path); + + if (!cap.isOpened()) { + cout << "Failed to get video." << endl; + return 0; + } + + // Show source video and get ROI. + const string SrcWinName = "Source video"; + namedWindow(SrcWinName, WINDOW_NORMAL); + MouseCallbackState mouse; + mouse.is_selection_started = false; + mouse.is_selection_finished = false; + setMouseCallback(SrcWinName, OnMouse, &mouse); + + Mat img; + cap >> img; + + imshow(SrcWinName, img); + waitKey(10); + + Rect selected; + while (!mouse.is_selection_finished) { + if (mouse.is_selection_started) { + Mat cSrc; + selected = Rect(mouse.point_first, mouse.point_second); + img.copyTo(cSrc); + rectangle(cSrc, selected, Scalar(0, 0, 255), 1, LINE_AA); + + imshow(SrcWinName, cSrc); + } + waitKey(20); + } + + string DstWinName; + for (;;) { + Mat copy; + img.copyTo(copy); + imshow(SrcWinName, copy); + waitKey(20); + + ImageProcessorImpl processor; + Mat res; + + if (parser.get("gray")) { + DstWinName = "gray image"; + res = processor.CvtColor(img, selected); + } else { + if (parser.get("median")) { + DstWinName = "madian image"; + res = processor.Filter(img, selected, 15); + } else { + if (parser.get("edges")) { + DstWinName = "edges image"; + res = processor.DetectEdges(img, selected, 3, 50, 3, 3); + } else { + if (!parser.get("pix")) { + DstWinName = "pix image"; + res = processor.Pixelize(img, selected, 10); + } + } + } + } + + cap >> img; + namedWindow(DstWinName); + imshow(DstWinName, res); + + + char c = waitKey(20); + if (c == 27 || img.empty()) break; + } + + return 0; +} From 32f536c06a8ebfdafec5ea48e42222c64b53b695 Mon Sep 17 00:00:00 2001 From: JuliaKamelina Date: Sat, 21 Oct 2017 21:08:49 +0300 Subject: [PATCH 4/4] add video_proc --- src/image_processing.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/image_processing.cpp b/src/image_processing.cpp index 8e9f77e..016f4f3 100644 --- a/src/image_processing.cpp +++ b/src/image_processing.cpp @@ -10,19 +10,14 @@ using cv::Rect; using std::vector; Mat ImageProcessorImpl::CvtColor(const Mat &src, const Rect &roi) { - Mat src_copy; + Mat src_copy, dst_roi; src.copyTo(src_copy); Mat src_roi = src_copy(roi), dst_gray_roi; cvtColor(src_roi, dst_gray_roi, CV_BGR2GRAY); - vector channels; - channels.push_back(dst_gray_roi); - channels.push_back(dst_gray_roi); - channels.push_back(dst_gray_roi); - Mat dst_roi; + vector channels(3, dst_gray_roi); merge(channels, dst_roi); - dst_roi.copyTo(src_roi); return src_copy; @@ -46,7 +41,6 @@ Mat ImageProcessorImpl::DetectEdges(const Mat &src, const Rect &roi, cvtColor(src_roi, src_gray_roi, CV_BGR2GRAY); Mat gray_blurred; - blur(src_gray_roi, gray_blurred, cv::Size(size, size)); Mat detected_edges; @@ -69,9 +63,9 @@ Mat ImageProcessorImpl::Pixelize(const Mat &src, const Rect &roi, Mat src_copy_roi = src_copy(roi); int block_size_x = roi.width / divs, block_size_y = roi.height / divs; - for (int x = 0; x < roi.width - block_size_x; x += block_size_x) { - for (int y = 0; y < roi.height - block_size_y; y += block_size_y) { - Mat src_roi_block = src_copy_roi(Rect(x, y, block_size_x, block_size_y)); + for (int i = 0; i < roi.width - block_size_x; i += block_size_x) { + for (int j = 0; j < roi.height - block_size_y; j += block_size_y) { + Mat src_roi_block = src_copy_roi(Rect(i, j, block_size_x, block_size_y)); blur(src_roi_block, src_roi_block, cv::Size(block_size_x, block_size_y)); } }