Skip to content
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(LIBRARY_DEPS ${OpenCV_LIBS})

# BUILD
add_subdirectory(sample_template)
add_subdirectory(sample_zhiltsov)
# Add you directory here
# add_subdirectory(sample_YOUR_NAME)

Expand Down
7 changes: 7 additions & 0 deletions sample_zhiltsov/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set(target "sample_zhiltsov")

file(GLOB hdrs "*.hpp")
file(GLOB srcs "*.cpp")

add_executable(${target} ${srcs} ${hdrs})
target_link_libraries(${target} ${LIBRARY_DEPS})
169 changes: 169 additions & 0 deletions sample_zhiltsov/application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#include "application.hpp"
#include "processing.hpp"

#include <opencv2/highgui/highgui.hpp>
#include <time.h>
#include <string>
#include <iostream>

using namespace cv;

Application::Application()
{
guiState.state = WindowState::OnFilter;
}

int Application::parseArguments(int argc, const char** argv, Application::Parameters& params)
{
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;
}

void create_button(const std::string& text, const Rect& rect, Mat& display)
{
rectangle(display, rect, Scalar(128, 128, 128), CV_FILLED);
putText(display, text,
Point(rect.x + rect.width / 2 - 15,
rect.y + rect.height / 2 + 10),
FONT_HERSHEY_SIMPLEX, 1.0, CV_RGB(0, 0, 0), 2);
}

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.filterBlurButtonPlace = Rect(20, display.rows - 120, 120, 40);
guiState.filterCannyButtonPlace = Rect(160, display.rows - 120, 120, 40);
guiState.filterPixelizeButtonPlace = Rect(300, display.rows - 120, 120, 40);
guiState.filterGrayscaleButtonPlace = Rect(440, display.rows - 120, 120, 40);

create_button("on", guiState.onButtonPlace, display);
create_button("off", guiState.offButtonPlace, display);
create_button("save", guiState.saveButtonPlace, display);
create_button("Canny", guiState.filterCannyButtonPlace, display);
create_button("Blur", guiState.filterBlurButtonPlace, display);
create_button("Pixelize", guiState.filterPixelizeButtonPlace, display);
create_button("Grayscale", guiState.filterGrayscaleButtonPlace, display);

return 0;
}

int Application::showFrame(const std::string &caption, const Mat& src, Mat& dst)
{
switch (guiState.state)
{
case WindowState::OffFilter:
src.copyTo(dst);
break;

case WindowState::OnFilter:
processFrame(src, dst);
break;

default: { throw "Unexpected window state."; }
}

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);

buttonClickHandleArgs.dstBuf = &dst;
setMouseCallback(caption, onButtonClick, this);

char key = waitKey(1);

return key;
}

void Application::onButtonClick(int eventId, int x, int y, int flsgs, void* userData)
{
if (eventId != EVENT_LBUTTONDOWN)
{
return;
}
Application* app = static_cast<Application*>(userData);

if (isButtonClicked(app->guiState.onButtonPlace, x, y))
{
app->guiState.state = WindowState::OnFilter;
return;
}
if (isButtonClicked(app->guiState.offButtonPlace, x, y))
{
app->guiState.state = WindowState::OffFilter;
return;
}
if (isButtonClicked(app->guiState.saveButtonPlace, x, y))
{
std::stringstream ss;
ss << clock() << ".png";
imwrite(ss.str(), *app->buttonClickHandleArgs.dstBuf);
return;
}
if (isButtonClicked(app->guiState.filterBlurButtonPlace, x, y))
{
app->processor.setFilterType(Processing::FilterType::Blur);
return;
}
if (isButtonClicked(app->guiState.filterCannyButtonPlace, x, y))
{
app->processor.setFilterType(Processing::FilterType::Canny);
return;
}
if (isButtonClicked(app->guiState.filterGrayscaleButtonPlace, x, y))
{
app->processor.setFilterType(Processing::FilterType::Grayscale);
return;
}
if (isButtonClicked(app->guiState.filterPixelizeButtonPlace, x, y))
{
app->processor.setFilterType(Processing::FilterType::Pixelize);
return;
}
}

bool Application::isButtonClicked(const 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;
}

59 changes: 59 additions & 0 deletions sample_zhiltsov/application.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <string>
#include <iostream>
#include <opencv2/core/core.hpp>

#include "processing.hpp"


class Application
{
public:
struct WindowState
{
enum
{
OnFilter,
OffFilter
};
};
typedef int WindowState_t;

struct Parameters
{
std::string imgFileName;
};
struct GUIElementsState
{
WindowState_t state;
cv::Rect onButtonPlace;
cv::Rect offButtonPlace;
cv::Rect saveButtonPlace;
cv::Rect filterGrayscaleButtonPlace;
cv::Rect filterPixelizeButtonPlace;
cv::Rect filterCannyButtonPlace;
cv::Rect filterBlurButtonPlace;
};
int parseArguments(int argc, const char** argv, Parameters& params);
int getFrame(const std::string& fileName, cv::Mat& src);
int processFrame(const cv::Mat& src, cv::Mat& dst);
int showFrame(const std::string& caption,
const cv::Mat& src, cv::Mat& dst);

Application();
private:
Processing processor;
GUIElementsState guiState;
struct ButtonClickHandleArgs
{
cv::Mat* dstBuf;
};
ButtonClickHandleArgs buttonClickHandleArgs;


int drawButtons(cv::Mat &display);

static void onButtonClick(int eventId, int x, int y, int flags, void* userData);
static bool isButtonClicked(const cv::Rect& buttonPlace, int x, int y);
};
44 changes: 44 additions & 0 deletions sample_zhiltsov/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <opencv2/core/core.hpp>
#include <iostream>

#include "application.hpp"

using namespace std;
using namespace cv;

enum ErrorCode {
OK,
WRONG_ARGUMENTS,
WRONG_INPUT,
CANT_PROCESS
};

int main(int argc, const char **argv)
{
Application app;
Application::Parameters params;

if (app.parseArguments(argc, argv, params) != 0)
{
cout << "sample_template <image_name>" << endl;
cout << "<image_name> - image name for filtering" << endl;
return WRONG_ARGUMENTS;
}

Mat src;
if (app.getFrame(params.imgFileName, src) != 0)
{
cout << "Error: \'src\' image is null or empty!" << endl;
return WRONG_INPUT;
}

const std::string caption = "OpenCV Sample";
char key = 0;
Mat dst(src.rows, src.cols, src.type());
while (key != 27) // Esc
{
key = app.showFrame(caption, src, dst);
}

return OK;
}
Loading