diff --git a/src/EdgeDetector.cpp b/src/EdgeDetector.cpp new file mode 100644 index 0000000..b142a6d --- /dev/null +++ b/src/EdgeDetector.cpp @@ -0,0 +1,82 @@ +#include "EdgeDetector.h" + +EdgeDetector::EdgeDetector() {} + +/** + * Деструктор. + * Закрытие окон созданных при помощи OpenCV и освобождение ресурсов. + */ +EdgeDetector::~EdgeDetector() { + cvReleaseCapture(&camera); + cvDestroyAllWindows(); +} + +/** + * Инициализация камеры, окон и первоначальных параметров. + */ +void EdgeDetector::init(int deviceNumber) { + camera = initCamera(deviceNumber); + imageSize = getCameraImageSize(camera); + cvNamedWindow(getWindowName(), CV_WINDOW_AUTOSIZE); +} + +/** + * Обновление выводимой информации. + */ +void EdgeDetector::update() { + if (camera == NULL) return; + IplImage *tempFrame; + cameraFrame = cvQueryFrame(camera); + resultFrame = cvCloneImage(cameraFrame); + if (isGrayScaleEffect) { + resultFrame = cvCreateImage(imageSize, cameraFrame->depth, CV_LOAD_IMAGE_GRAYSCALE); + cvCvtColor(cameraFrame, resultFrame, CV_BGR2GRAY); + } + if (isInverseEffect) { + tempFrame = cvCloneImage(resultFrame); + cvNot(tempFrame, resultFrame); + } + + cvShowImage(getWindowName(), resultFrame); +} + +/** + * Сохранить скриншот результирующего фрейма. + */ +void EdgeDetector::snapshot() { + if (resultFrame == NULL) return; + cvSaveImage("Capture.jpg", resultFrame); +} + +/** + * Выставить состояние эффекта. + */ +void EdgeDetector::setEffects(UINT effect, bool enabled) { + switch(LOWORD(effect)) { + case ID_EF_ORIGINAL: + isOriginalEffect = enabled; + break; + case ID_EF_GRAYSCALE: + isGrayScaleEffect = enabled; + break; + case ID_EF_INVERSE: + isInverseEffect = enabled; + break; + } +} + + +CvCapture* EdgeDetector::initCamera(int deviceNumber) { + //return cvCreateCameraCapture(deviceNumber); + return cvCaptureFromCAM(deviceNumber); +} + +CvSize EdgeDetector::getCameraImageSize(CvCapture* camera) { + double width = cvGetCaptureProperty(camera, CV_CAP_PROP_FRAME_WIDTH); + double height = cvGetCaptureProperty(camera, CV_CAP_PROP_FRAME_HEIGHT); + return cvSize(width, height); +} + +const char* EdgeDetector::getWindowName() { + return "Окно просмотра"; +} diff --git a/src/EdgeDetector.h b/src/EdgeDetector.h new file mode 100644 index 0000000..6028fdc --- /dev/null +++ b/src/EdgeDetector.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include "resource.h" + +/** + * Класс выделения границ. + * @author aNNiMON + */ +class EdgeDetector { +public: + EdgeDetector(); + ~EdgeDetector(); + + void init(int deviceNumber); + void update(); + void snapshot(); + + void setEffects(UINT effect, bool enabled); + +private: + // инициализация + CvCapture* initCamera(int deviceNumber); + CvSize getCameraImageSize(CvCapture* camera); + + const char* getWindowName(); + + bool isOriginalEffect, isGrayScaleEffect, isInverseEffect; + CvCapture* camera; + CvSize imageSize; + IplImage *cameraFrame, *resultFrame; +}; diff --git a/src/Main.cpp b/src/Main.cpp index 7994daa..9fab139 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "EdgeDetector.h" #include "WindowClass.h" #include "Window.h" #include "resource.h" @@ -15,7 +16,8 @@ void setEffectTypes(HWND hWnd); /** Состояния эффектов (включен / выключен) */ bool effectsEnabled[EFFECTS_END - EFFECTS_START + 1]; - +/** Детектор границ */ +EdgeDetector detector; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { // Регистрация класса окна @@ -31,6 +33,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmd Window wnd = Window(); wnd.setClassName(wClass.getClassName()); wnd.setInstance(hInstance); + wnd.setBounds(CW_USEDEFAULT, CW_USEDEFAULT, 400, 300); wnd.setTitle(wClass.getClassName()); if (!wnd.createWindow()) return 0; @@ -42,8 +45,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmd UpdateWindow(wnd.getWindow()); DrawMenuBar(wnd.getWindow()); + detector.init(CV_CAP_ANY); + MSG msg; while(GetMessage(&msg, NULL, 0, 0)) { + detector.update(); if(!TranslateAccelerator(wnd.getWindow(), hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); @@ -62,10 +68,7 @@ LRESULT CALLBACK mainWindowProcedure(HWND hWnd, UINT message, UINT wParam, LONG setOperatorType(hWnd, ID_OP_ROBERTS); setEffectTypes(hWnd); break; - - //case WM_PAINT: - // break; - + case WM_COMMAND: menuCommandSelected(hWnd, wParam); break; @@ -87,15 +90,19 @@ void menuCommandSelected(HWND hWnd, UINT wParam) { UINT command = LOWORD(wParam); switch(command) { + case ID_SNAPSHOT: + detector.snapshot(); + break; + + case ID_DEVICE: + break; + case ID_OP_ROBERTS: case ID_OP_PREWITT: case ID_OP_SOBEL: setOperatorType(hWnd, command); break; - case ID_SNAPSHOT: - break; - case ID_EF_ORIGINAL: case ID_EF_GRAYSCALE: case ID_EF_INVERSE: @@ -103,6 +110,9 @@ void menuCommandSelected(HWND hWnd, UINT wParam) { setEffectTypes(hWnd); break; + case ID_ABOUT: + break; + case ID_EXIT: SendMessage(hWnd, WM_CLOSE, NULL, NULL); break; @@ -125,7 +135,9 @@ void setOperatorType(HWND hWnd, UINT type) { void setEffectTypes(HWND hWnd) { HMENU viewMenu = GetSubMenu(GetMenu(hWnd), 1); for(int i = EFFECTS_START; i <= EFFECTS_END; i++) { - ULONG check = effectsEnabled[EFFECTS_END - i] ? MF_CHECKED : MF_UNCHECKED; + int id = EFFECTS_END - i; + ULONG check = effectsEnabled[id] ? MF_CHECKED : MF_UNCHECKED; CheckMenuItem( viewMenu, i, check); + detector.setEffects(i, effectsEnabled[id]); } } \ No newline at end of file