Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion include/image_processing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
};

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);
};
105 changes: 98 additions & 7 deletions samples/template_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,56 @@
#include <string>

#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.
Expand All @@ -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<string>(0), IMREAD_COLOR);
if (src.empty()) {
cout << "Failed to open image file '" + parser.get<string>(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<bool>("gray")) {
kSrcWindowName = "gray image";
namedWindow(kSrcWindowName, WINDOW_NORMAL);
imshow(kSrcWindowName, processor.CvtColor(src, selected));
} else
if (parser.get<bool>("median")) {
kSrcWindowName = "madian image";
kWaitKeyDelay = 1;
namedWindow(kSrcWindowName, WINDOW_NORMAL);
imshow(kSrcWindowName, processor.Filter(src, selected, 15));
} else
if (parser.get<bool>("edges")) {
kSrcWindowName = "edges image";
namedWindow(kSrcWindowName, WINDOW_NORMAL);
imshow(kSrcWindowName, processor.DetectEdges(src, selected, 3, 50, 3, 3));
} else
if (parser.get<bool>("pix")) {
kSrcWindowName = "pix image";
namedWindow(kSrcWindowName, WINDOW_NORMAL);
imshow(kSrcWindowName, processor.Pixelize(src, selected, 10));
}

waitKey();
return 0;
}
143 changes: 143 additions & 0 deletions samples/video_proc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <iostream>
#include <string>

#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<bool>("help")) {
parser.printMessage();
return 0;
}

VideoCapture cap;
string path = parser.get<string>("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<bool>("gray")) {
DstWinName = "gray image";
res = processor.CvtColor(img, selected);
} else {
if (parser.get<bool>("median")) {
DstWinName = "madian image";
res = processor.Filter(img, selected, 15);
} else {
if (parser.get<bool>("edges")) {
DstWinName = "edges image";
res = processor.DetectEdges(img, selected, 3, 50, 3, 3);
} else {
if (!parser.get<bool>("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;
}
74 changes: 74 additions & 0 deletions src/image_processing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "image_processing.hpp"

#include <vector>

#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, dst_roi;
src.copyTo(src_copy);

Mat src_roi = src_copy(roi), dst_gray_roi;
cvtColor(src_roi, dst_gray_roi, CV_BGR2GRAY);

vector<Mat> channels(3, dst_gray_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 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));
}
}

return src_copy;
}