diff --git a/ECTrainer2/BitalMonitor.cpp b/ECTrainer2/BitalMonitor.cpp index 03a4b51..8eaf4df 100644 --- a/ECTrainer2/BitalMonitor.cpp +++ b/ECTrainer2/BitalMonitor.cpp @@ -1,7 +1,4 @@ -#include "ECTrainer.h" -#include "BitalMonitor.h" -#include -#include +#include "common.h" // �R���X�g���N�^ BitalMonitor::BitalMonitor(ECTrainer* pEct) @@ -14,18 +11,24 @@ // ������ bool BitalMonitor::Init() { - bool rv = _Com.Open(COM_PORT, _T("baud=19200 parity=N data=8 stop=1")); - - // �|�[�g�`�F�b�N char comBuf[256] = { '\0' }; - DWORD readBytes = _Com.Receive((BYTE*)comBuf, 256); - if (readBytes < 1) return true; - comBuf[readBytes] = '\0'; - char* pt = strchr(comBuf, LF); - if (!pt) return true; - if (atoi(pt + 1) < 1) return true; - _useDevice = true; + for (int com = 1; com <= GComPort::COM_SEARCH_MAX; com++) { + + if (!_Com.Open(com, _T("baud=19200 parity=N data=8 stop=1"))) continue; + + // �|�[�g�`�F�b�N + DWORD readBytes = _Com.Receive((BYTE*)comBuf, 256); + if (readBytes < 1) continue; + if ((*comBuf >= '0' && *comBuf <= '9') || *comBuf == '#' || *comBuf == LF) { + mwut::DebugPrintf(_T("Bital device found on com%d\n"), com); + _useDevice = true; + return true; + } + } + + mwut::DebugPrintf(_T("Bital device not found\n")); + _useDevice = false; return true; } diff --git a/ECTrainer2/ECTrainer.cpp b/ECTrainer2/ECTrainer.cpp index 6189b5c..8201712 100644 --- a/ECTrainer2/ECTrainer.cpp +++ b/ECTrainer2/ECTrainer.cpp @@ -68,34 +68,34 @@ return true; } -// �L�����u���[�V�����J�n -void ECTrainer::CalibStart() { - ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::CALIB); - ((TobiiREST*)_pProcs[REST])->Start(); -} +//// �L�����u���[�V�����J�n +//void ECTrainer::CalibStart() { +// ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::STIM_PAGE::CALIB); +// ((TobiiREST*)_pProcs[REST])->StartCalibration(); +//} -// �L�����u���[�V�������ʕ\�� -int ECTrainer::CheckCalibResult() { - int res = _CalibResult; - if (res > 0) ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::CALIB_COMPLETE); - if (res < 0) ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::CALIB_FAILED); - _CalibResult = 0; - return res; -} +//// �L�����u���[�V�������ʕ\�� +//int ECTrainer::CheckCalibResult() { +// int res = _CalibResult; +// if (res > 0) ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::STIM_PAGE::CALIB_COMPLETE); +// if (res < 0) ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::STIM_PAGE::CALIB_FAILED); +// _CalibResult = 0; +// return res; +//} // �J�n void ECTrainer::StartStim() { - ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::START); + ((Stimulus*)_pProcs[STIM])->SetPage(STIM_PAGE::START); } // �J�n void ECTrainer::StopStim() { - ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::STOP); + ((Stimulus*)_pProcs[STIM])->SetPage(STIM_PAGE::STOP); } // ���� void ECTrainer::NextStim() { - ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::NEXT); + ((Stimulus*)_pProcs[STIM])->SetPage(STIM_PAGE::NEXT); } //// ����摜�o�b�t�@�ɉ摜��ݒ� @@ -149,5 +149,5 @@ // �o�b�e���[�c�ʎ擾 int ECTrainer::BatteryLevel() { - return ((TobiiREST*)_pProcs[REST])->BatteryLevel(); + return ((TobiiREST*)_pProcs[REST])->GetBatteryLevel(); } \ No newline at end of file diff --git a/ECTrainer2/ECTrainer.h b/ECTrainer2/ECTrainer.h index f8d0bfd..487f28b 100644 --- a/ECTrainer2/ECTrainer.h +++ b/ECTrainer2/ECTrainer.h @@ -4,8 +4,8 @@ #include "myOpenCV.h" #define ADDR "192.168.71.50" -//#define EYEDEVICE_GLASS2 -#define EYEDEVICE_NONE +#define EYEDEVICE_GLASS2 +//#define EYEDEVICE_NONE class BaseProcess; class ECTrainerGUI; @@ -23,7 +23,7 @@ { private: // �v���Z�X�ꗗ KeepAlive -> EyeTrack �̏��K�{ - enum PROC { IMGPROC, SCNCAM, STIM, ALIVE, EYETR, REST, BITAL, WORKER, GUI, NUM }; + enum PROC { REST, IMGPROC, SCNCAM, STIM, ALIVE, EYETR, BITAL, WORKER, GUI, NUM }; BaseProcess* _pProcs[PROC::NUM]; HINSTANCE _hInstance; Marker* _pMarker; @@ -33,7 +33,6 @@ // �X���b�h�J�n�_ static DWORD WINAPI ThreadEntry(LPVOID lpParameter); - //static DWORD WINAPI KeepAliveThreadEntry(LPVOID lpParameter); public: static const int RINGBUFSIZE = 4; @@ -50,8 +49,8 @@ Worker* PWorker() { return (Worker*)_pProcs[WORKER]; } Marker* PMarker() { return _pMarker; } bool Process(); - void CalibStart(); - int CheckCalibResult(); + //void CalibStart(); + //int CheckCalibResult(); void StartStim(); void StopStim(); void NextStim(); @@ -67,10 +66,6 @@ // �C�����C���֐� bool IsAppRun() { return _AppRunning; } // �A�v���P�[�V�������s�����ǂ��� void StopApp() { _AppRunning = false; } // �A�v���P�[�V�������~ - //void SetHomographyStatus(bool ok) { _HomographyOK = ok; } - //bool GetHomographyStatus() { return _HomographyOK; } - //void SetSceneSize(cv::Size s) { _SceneSize = s; } - //cv::Size GetSceneSize() { return _SceneSize; } void SetCalibResult(int result) { _CalibResult = result; } void SetMovieToShow(std::wstring file) { _MovieToShow = file; } std::wstring GetMovieToShow() { return _MovieToShow; } diff --git a/ECTrainer2/ECTrainer2.vcxproj b/ECTrainer2/ECTrainer2.vcxproj index fafaa24..324cb13 100644 --- a/ECTrainer2/ECTrainer2.vcxproj +++ b/ECTrainer2/ECTrainer2.vcxproj @@ -91,6 +91,7 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + $(SolutionDir)packages\cpprestsdk.v141.2.10.12.1\build\native\include;%(AdditionalIncludeDirectories) Console @@ -152,6 +153,9 @@ + + + @@ -161,6 +165,7 @@ + @@ -169,9 +174,10 @@ + - + diff --git a/ECTrainer2/ECTrainer2.vcxproj.filters b/ECTrainer2/ECTrainer2.vcxproj.filters index 314b9f3..1d84d96 100644 --- a/ECTrainer2/ECTrainer2.vcxproj.filters +++ b/ECTrainer2/ECTrainer2.vcxproj.filters @@ -60,6 +60,15 @@ ソース ファイル + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + @@ -104,9 +113,6 @@ ヘッダー ファイル - - ヘッダー ファイル - ヘッダー ファイル @@ -122,6 +128,15 @@ ヘッダー ファイル + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + diff --git a/ECTrainer2/ECTrainerGUI.cpp b/ECTrainer2/ECTrainerGUI.cpp index 09850d7..2a7e384 100644 --- a/ECTrainer2/ECTrainerGUI.cpp +++ b/ECTrainer2/ECTrainerGUI.cpp @@ -1,11 +1,5 @@ -#include "ECTrainerGUI.h" -#include "ECTrainer.h" -#include "BitalMonitor.h" -#include "ImageProc.h" -#include "Marker.h" -//#include "MyWinUtils.h" -#include "myOpenCVutil.h" +#include "common.h" #include #pragma comment(lib,"winmm.lib") #include @@ -14,8 +8,6 @@ #pragma comment(lib, "Strmiids.lib") #define _WIN32_DCOM // CoInitializeEx�֐��̌Ăяo���ɕK�v - - #define CVUI_IMPLEMENTATION #include "cvui.h" @@ -38,16 +30,8 @@ , _SceneBufferHeight(0) , _DispImageHeight(0) , _SceneBufferScale(1.F) - //, _PlayIndex(0) + , _hWndMain(NULL) { - //_MovieFiles.push_back(_T("../movies/instruction.avi")); - //_MovieFiles.push_back(_T("../movies/test4.avi")); - //_MovieFiles.push_back(_T("../movies/instruction.avi")); - //_MovieFiles.push_back(_T("../movies/test1.avi")); - //_MovieFiles.push_back(_T("../movies/instruction.avi")); - //_MovieFiles.push_back(_T("../movies/test3.avi")); - //_MovieFiles.push_back(_T("../movies/instruction.avi")); - //_MovieFiles.push_back(_T("../movies/test2.avi")); } // �f�X�g���N�^ @@ -67,29 +51,29 @@ // ������ bool ECTrainerGUI::Init(HINSTANCE hInstance) { // ���s�‹��̏��擾 - GetDisplayInfo(); + std::vector _Displays = mwut::GetDisplayInfo(); // GUI�E�C���h�E cvui::init(WIN_MAIN); _MainFrame.create(MAIN_FRAME_SIZE, CV_8UC3); // �h���񎦃E�C���h�E - cv::namedWindow(WIN_DISP, cv::WINDOW_NORMAL | cv::WINDOW_OPENGL); if (_Displays.size() > 1) { - // ���C�����j�^�̌��� - int mainMonitor = 0, subMonitor = 1; - for (int i = 0; i < _Displays.size(); i++) { - if (_Displays[i].left == 0 && _Displays[i].top == 0) mainMonitor = i; - else subMonitor = i; - } - // �}���`���j�^�̏ꍇ �T�u��ʂŃt���X�N���[���� - cv::moveWindow(WIN_DISP, _Displays[mainMonitor].left, _Displays[mainMonitor].top); + // �}���`���j�^�̏ꍇ + // �T�u��ʂɑ���p�l���\�� + cv::moveWindow(WIN_MAIN, _Displays[1].left, _Displays[1].top); + _hWndMain = ::FindWindowA(NULL, WIN_MAIN.c_str()); + + // ���C����ʂɔ팱�҉f���񎦁iDirectShow���悪�T�u��ʂɏo�͂ł��Ȃ����߁j + cv::namedWindow(WIN_DISP, cv::WINDOW_NORMAL | cv::WINDOW_OPENGL); + cv::moveWindow(WIN_DISP, _Displays[0].left, _Displays[0].top); + cv::resizeWindow(WIN_DISP, cv::Size(640, 400)); cv::setWindowProperty(WIN_DISP, cv::WND_PROP_FULLSCREEN, cv::WINDOW_FULLSCREEN); - _DispBuffer.create(cv::Size(_Displays[mainMonitor].right - _Displays[mainMonitor].left, - _Displays[mainMonitor].bottom - _Displays[mainMonitor].top), CV_8UC3); - cv::moveWindow(WIN_MAIN, _Displays[subMonitor].left + 100, _Displays[mainMonitor].top + 100); - _DispRect = _Displays[mainMonitor]; + _DispBuffer.create(cv::Size(_Displays[0].right - _Displays[0].left, + _Displays[0].bottom - _Displays[0].top), CV_8UC3); + _DispRect = _Displays[0]; } else { // �V���O�����j�^�̏ꍇ + cv::namedWindow(WIN_DISP, cv::WINDOW_AUTOSIZE); cv::moveWindow(WIN_DISP, _Displays[0].left, _Displays[0].top); _DispBuffer.create(cv::Size(640, 480), CV_8UC3); cv::moveWindow(WIN_MAIN, _Displays[0].left + 100, _Displays[0].top + 100); @@ -251,32 +235,15 @@ } // �L�����u���[�V�������� - if (_pEct->CheckCalibResult() > 0) fCaliblated = true; + //if (_pEct->CheckCalibResult() > 0) fCaliblated = true; // UI�`�� cvui::image(_MainFrame, 0, 0, _Logo); cvui::beginColumn(_MainFrame, 10, 100, 140, -1, 10); - if (fStimulus) { - if (cvui::button(140, 30, "STOP")) { - if (!StopMovie()) _pEct->StopApp(); - //fKeepContact = false; - _pEct->StopStim(); - fStimulus = false; - } - //if (cvui::button(140, 30, "NEXT")) { - // //fKeepContact = false; - // //if (!StopMovie()) _pEct->Stop(); - // //_PlayIndex = (_PlayIndex + 1) % _MovieFiles.size(); - // //if (!PlayMovie()) _pEct->Stop(); - // //_pEct->Next(); - //} - cvui::trackbar(140, &targetSize, (float)0, (float)3.0); - cvui::checkbox("Show Eyes", &fShowEyesPos); - cvui::text(fContact ? "Eyes Contact!" : "No contact"); - } else { + switch (_pEct->PWorker()->GetAppStatus()) { + case APP_STATUS::IDLE: if (cvui::button(140, 30, "CALIBRATION")) { - _pEct->CalibStart(); - //fCalib = true; + _pEct->PWorker()->StartCalibration(); } if (fCaliblated) { if (cvui::button(140, 30, "START")) { @@ -286,6 +253,18 @@ _pEct->StartStim(); } } + break; + case APP_STATUS::EXEC: + if (cvui::button(140, 30, "STOP")) { + if (!StopMovie()) _pEct->StopApp(); + //fKeepContact = false; + _pEct->StopStim(); + fStimulus = false; + } + cvui::trackbar(140, &targetSize, (float)0, (float)3.0); + cvui::checkbox("Show Eyes", &fShowEyesPos); + cvui::text(fContact ? "Eyes Contact!" : "No contact"); + break; } cvui::printf("Mouse W %d, %d", mp.x, mp.y); cvui::printf("Mouse L %.2f, %.2f", imagePos.x, imagePos.y); @@ -320,7 +299,10 @@ if (movieToShow == L"STOP") { if (!StopMovie()) _pEct->StopApp(); } else { - if (!PlayMovie(movieToShow)) _pEct->StopApp(); + if (!PlayMovie(movieToShow)) { + mwut::DebugPrintf(_T("Can't play movie: %s\n"), movieToShow.c_str()); + _pEct->StopApp(); + } } } @@ -484,27 +466,6 @@ buf.copyTo(_DispBuffer); } -// �S�f�B�X�v���C�̏����擾 -void ECTrainerGUI::GetDisplayInfo() { - EnumDisplayMonitors(NULL, NULL, - (MONITORENUMPROC)MonitorEnumProc, (LPARAM)&_Displays); -#ifdef _DEBUG - for (int i = 0; i < _Displays.size(); i++) { - std::cout << "Monitor" << i << " : " - << _Displays[i].left << "," << _Displays[i].top << "," - << _Displays[i].right << "," << _Displays[i].bottom << std::endl; - } -#endif // _DEBUG -} - -// �e�f�B�X�v���C�̏����擾 -BOOL CALLBACK ECTrainerGUI::MonitorEnumProc( - HMONITOR hMon, HDC hdcMon, LPRECT lpMon, LPARAM dwData) { - std::vector* displays = (std::vector*)dwData; - displays->push_back(*lpMon); - return TRUE; -} - // �E�B���h�E�v���V�[�W�� LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_DESTROY) { PostQuitMessage(0); return 0; } diff --git a/ECTrainer2/ECTrainerGUI.h b/ECTrainer2/ECTrainerGUI.h index f38dceb..dcfc64c 100644 --- a/ECTrainer2/ECTrainerGUI.h +++ b/ECTrainer2/ECTrainerGUI.h @@ -26,8 +26,6 @@ const cv::Point DISP_IMAGE_POS = cv::Point(820, 120); const int KEY_ESC = 27; - //std::vector _MovieFiles; - std::vector _Displays; cv::Mat _MainFrame; // ���C���E�C���h�E�t���[�� cv::Mat _DispImage; // �h���摜�i����җp�j cv::Mat _DispBuffer; // �h����ʁi�팱�җp�j @@ -37,9 +35,9 @@ int _SceneBufferHeight; float _SceneBufferScale; int _DispImageHeight; - //int _PlayIndex; + HWND _hWndMain; - RECT _DispRect; + RECT _DispRect; // DirectShow����\���ʒu HWND _hWnd; LPDIRECT3D9 _pD3D; LPDIRECT3DDEVICE9 _pD3DDev; @@ -55,14 +53,12 @@ bool PlayMovie(std::wstring movie); bool StopMovie(); bool IsPlaying(); - void GetDisplayInfo(); - static BOOL CALLBACK MonitorEnumProc(HMONITOR hMon, HDC hdcMon, LPRECT lpMon, LPARAM dwDate); public: ECTrainerGUI(ECTrainer* pEct); ~ECTrainerGUI(); bool Init(HINSTANCE hInstance); bool MainLoop(); - //void SetSceneBuffer(cv::Mat &img); + HWND GetMainHWnd() { return _hWndMain; } void SetDispBuffer(cv::Mat& img); }; diff --git a/ECTrainer2/EyeTrack.cpp b/ECTrainer2/EyeTrack.cpp index aba6369..eac6c48 100644 --- a/ECTrainer2/EyeTrack.cpp +++ b/ECTrainer2/EyeTrack.cpp @@ -1,10 +1,6 @@ #include #include -#include -#include "EyeTrack.h" -#include "ECTrainer.h" -#include "KeepAlive.h" -#include "SceneCamera.h" +#include "common.h" #include "MeanBuffer.h" #pragma comment(lib, "ws2_32.lib") diff --git a/ECTrainer2/GComPort.cpp b/ECTrainer2/GComPort.cpp index c3f64f5..dd3c463 100644 --- a/ECTrainer2/GComPort.cpp +++ b/ECTrainer2/GComPort.cpp @@ -15,7 +15,7 @@ // �|�[�g��T���ĊJ�� int GComPort::Open(TCHAR* config) { - for (int findPort = 1; findPort < 20; findPort++) { + for (int findPort = 1; findPort < COM_SEARCH_MAX; findPort++) { if (this->Open(findPort, config)) { this->Send((BYTE*)"s", 1); Sleep(100); @@ -31,6 +31,8 @@ // �|�[�g���J�� bool GComPort::Open(int port, const TCHAR* config) { + if (mComHandle != INVALID_HANDLE_VALUE) this->Close(); + // �|�[�g�ԍ������񐶐� if (port < 1) return false; TCHAR portStr[256]; diff --git a/ECTrainer2/GComPort.h b/ECTrainer2/GComPort.h index ea06251..61c88ee 100644 --- a/ECTrainer2/GComPort.h +++ b/ECTrainer2/GComPort.h @@ -8,6 +8,7 @@ HANDLE mComHandle; public: + static const int COM_SEARCH_MAX = 20; GComPort(void); ~GComPort(void); diff --git a/ECTrainer2/KeepAlive.cpp b/ECTrainer2/KeepAlive.cpp index c732032..0956983 100644 --- a/ECTrainer2/KeepAlive.cpp +++ b/ECTrainer2/KeepAlive.cpp @@ -33,6 +33,7 @@ _socketAddr.sin_family = AF_INET; _socketAddr.sin_port = htons(PORT); InetPton(_socketAddr.sin_family, _T(ADDR), &_socketAddr.sin_addr.S_un.S_addr); + #endif return true; diff --git a/ECTrainer2/MovieObject.cpp b/ECTrainer2/MovieObject.cpp new file mode 100644 index 0000000..180be12 --- /dev/null +++ b/ECTrainer2/MovieObject.cpp @@ -0,0 +1,63 @@ +#include "MovieObject.h" + + +// �R���X�g���N�^ +MovieObject::MovieObject() + :_lastAccess(0) +{ + +} + +// �e�[�u������f�[�^���Z�b�g +int MovieObject::SetData(mwut::STR_TABLE table) { + + int addLines = 0; + for (int r = 0; r < table.size(); r++) { + // �s�`�F�b�N + int cols = (int)table[r].size(); + if (cols < 4 || (cols - 1) % 3 != 0) continue; + + bool check = true; + for (int c = 0; c < cols; c++) { + if (atof(table[r][c].c_str()) == 0 && table[r][c] != "0") check = false; + } + if (!check) continue; + + // �f�[�^�ǂݍ��� + FrameInfo fi; + fi.eTime = (float)atof(table[r][0].c_str()); + int nElements = (cols - 1) / 3; + for (int e = 0; e < nElements; e++) { + fi.elements.push_back(Element( + (float)atof(table[r][(size_t)e * 3 + 1].c_str()), + (float)atof(table[r][(size_t)e * 3 + 2].c_str()), + (float)atof(table[r][(size_t)e * 3 + 3].c_str()))); + } + _frame.push_back(fi); + addLines++; + } + return addLines; +} + +// �t�@�C��������f�[�^���Z�b�g +int MovieObject::SetData(const std::string& filename) { + mwut::STR_TABLE table; + if (!mwut::ReadTable(filename, table)) return 0; + return SetData(table); +} + +// �w�莞�ԈȑO�̗v�f�Q��Ԃ� +std::vector MovieObject::GetElements(float sTime) { + // �O�񌋉ʂ̎��Ԃ����łɑO���̏ꍇ�͍ŏ��ɖ߂� + if (_frame[_lastAccess].eTime > sTime) _lastAccess = 0; + + // �O�񌋉ʂ���O���ɒT�� + int index = _lastAccess; + for (; index < _frame.size(); index++) { + if (_frame[index].eTime > sTime) break; + } + + if (index > 0) index--; + _lastAccess = index; + return _frame[index].elements; +} diff --git a/ECTrainer2/MovieObject.h b/ECTrainer2/MovieObject.h new file mode 100644 index 0000000..2f9ebb8 --- /dev/null +++ b/ECTrainer2/MovieObject.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +#include "myWinUtils.h" + + +// �\���v�f +struct Element { + float x; // X���W + float y; // Y���W + float d; // �T�C�Y + + Element(float X, float Y, float D) { + x = X; + y = Y; + d = D; + } +}; + +// �t���[����� +struct FrameInfo { + float eTime; // ���� + std::vector elements; // �v�f�Q +}; + +// �f���I�u�W�F�N�g�N���X +class MovieObject { + std::vector _frame; + int _lastAccess; + +public: + // �R���X�g���N�^ + MovieObject(); + // �e�[�u������f�[�^���Z�b�g + int SetData(mwut::STR_TABLE table); + // �t�@�C��������f�[�^���Z�b�g + int SetData(const std::string& filename); + // �w�莞�Ԃ̃I�u�W�F�N�g����Ԃ� + std::vector GetElements(float sTime); + // �t���[������Ԃ� + int GetNumFrames() { return _frame.size(); } +}; diff --git a/ECTrainer2/MyWinUtils.h b/ECTrainer2/MyWinUtils.h index a577d5d..d0c8b27 100644 --- a/ECTrainer2/MyWinUtils.h +++ b/ECTrainer2/MyWinUtils.h @@ -4,62 +4,36 @@ #include #include #include -#include -#include -// �}���`�o�C�g����������C�h������iUNICODE�j�ɕϊ� -std::wstring Multi2Wide(std::string const& src) -{ - auto const dest_size = ::MultiByteToWideChar(CP_ACP, 0U, src.data(), -1, nullptr, 0U); - std::vector dest(dest_size, L'\0'); - if (::MultiByteToWideChar(CP_ACP, 0U, src.data(), -1, dest.data(), (int)dest.size()) == 0) { - throw std::system_error{ static_cast(::GetLastError()), std::system_category() }; - } - dest.resize(std::char_traits::length(dest.data())); - dest.shrink_to_fit(); - return std::wstring(dest.begin(), dest.end()); -} +namespace mwut { -// �����t���f�o�b�O�o�� -int DebugPrintf(LPCTSTR format, ...) -{ - va_list args; - va_start(args, format); + typedef std::vector> STR_TABLE; - int len = _vsctprintf(format, args) + 1; - TCHAR* buf = (TCHAR*)malloc(len * sizeof(TCHAR)); - len = _vstprintf_s(buf, len, format, args); - - OutputDebugString(buf); - free(buf); - - return len; -} - -bool ReadTable(const std::string& filename, std::vector>& table, const char delimiter = ',') -{ - // �t�@�C�����J�� - std::fstream filestream(filename); - if (!filestream.is_open()) return false; // �t�@�C�����J���Ȃ������ꍇ�͏I�� - - // �t�@�C����ǂݍ��� - while (!filestream.eof()) { - // �P�s�ǂݍ��� - std::string buffer; - filestream >> buffer; - - // �t�@�C������ǂݍ��񂾂P�s�̕��������؂蕶���ŕ����ă��X�g�ɒlj����� - std::vector record; // �P�s���̕�����̃��X�g - std::istringstream streambuffer(buffer); // ������X�g���[�� - std::string token; // �P�Z�����̕����� - while (std::getline(streambuffer, token, delimiter)) { - // �P�Z�����̕���������X�g�ɒlj����� - record.push_back(token); + // �X���b�v�N���X + template + class SWAP { + public: + static void DO(T& a, T& b) { + T tmp = a; + a = b; + b = a; } + }; - // �P�s���̕�������o�͈����̃��X�g�ɒlj����� - table.push_back(record); - } + // �}���`�o�C�g����������C�h������iUNICODE�j�ɕϊ� + std::wstring Multi2Wide(std::string const& src); - return true; -} \ No newline at end of file + // �����t���f�o�b�O�o�� + int DebugPrintf(LPCTSTR format, ...); + + // �e�[�u����ǂݍ��� + bool ReadTable(const std::string& filename, STR_TABLE& table, const char delimiter = ','); + + // �}���`�f�B�X�v���C�̏����擾 + // �v�f0�F���C���E�C���h�E + std::vector GetDisplayInfo(); + + // �f�B�X�v���C���擾�R�[���o�b�N + BOOL CALLBACK MonitorEnumProc( + HMONITOR hMon, HDC hdcMon, LPRECT lpMon, LPARAM dwData); +} diff --git a/ECTrainer2/REST_Handler.cpp b/ECTrainer2/REST_Handler.cpp index a1c1030..b2a69b2 100644 --- a/ECTrainer2/REST_Handler.cpp +++ b/ECTrainer2/REST_Handler.cpp @@ -3,7 +3,9 @@ http_response REST_Handler::POST_Request(const TCHAR* baseURL, json::value data) { - http_client httpClient(baseURL); + http_client_config cfg; + cfg.set_timeout(std::chrono::milliseconds(100)); + http_client httpClient(baseURL, cfg); http_response httpResponse = httpClient.request(methods::POST, L"", data == json::value::Null ? _T("") : data.serialize(), L"application/json").get(); return httpResponse; diff --git a/ECTrainer2/REST_Handler.h b/ECTrainer2/REST_Handler.h index 4b809b4..4186cd6 100644 --- a/ECTrainer2/REST_Handler.h +++ b/ECTrainer2/REST_Handler.h @@ -2,6 +2,7 @@ #include #include +#include #include using namespace web; diff --git a/ECTrainer2/StimDataS.txt b/ECTrainer2/StimDataS.txt index 8a627dd..0792ff8 100644 --- a/ECTrainer2/StimDataS.txt +++ b/ECTrainer2/StimDataS.txt @@ -1 +1 @@ -2 ../movies/visit01_004re.avi 30 ../movies/visit01_004.csv 2 +2 ../movies/visit01_004.avi 30 ../movies/visit01_004.csv 2 diff --git a/ECTrainer2/Stimulus.cpp b/ECTrainer2/Stimulus.cpp index 3394576..a254c75 100644 --- a/ECTrainer2/Stimulus.cpp +++ b/ECTrainer2/Stimulus.cpp @@ -1,8 +1,4 @@ - -#include "Stimulus.h" -#include "ECTrainer.h" -#include "Marker.h" -#include "MyWinUtils.h" +#include "common.h" #include #include @@ -17,7 +13,7 @@ // ������ bool Stimulus::Init() { - SetPage(PAGES::OPENING); + SetPage(STIM_PAGE::OPENING); std::ifstream ifs(DATA_FILE); if (!ifs) @@ -44,13 +40,13 @@ DWORD current = GetTickCount(); if ((float)(current - _StartTime) / 1000.F > _StimInfoSet[_StimNo].dulation) { if (_StimInfoSet[_StimNo].type == 2) { - SetPage(PAGES::WHITE); + SetPage(STIM_PAGE::WHITE); _pEct->SetMovieToShow(L"STOP"); } if (++_StimNo < _StimInfoSet.size()) { SetStimulus(); } else { - SetPage(PAGES::STOP); + SetPage(STIM_PAGE::STOP); } } } @@ -73,7 +69,7 @@ } _pEct->SetDispBuffer(_DispBuffer); } else { - std::wstring mov = Multi2Wide(_StimInfoSet[_StimNo].filename); + std::wstring mov = mwut::Multi2Wide(_StimInfoSet[_StimNo].filename); _pEct->SetMovieToShow(mov); } if (_StimInfoSet[_StimNo].csvfile[0] != '_') { @@ -83,38 +79,38 @@ } // �Œ�y�[�W�\�� -void Stimulus::SetPage(PAGES st) { +void Stimulus::SetPage(STIM_PAGE st) { switch (st) { - case PAGES::OPENING: + case STIM_PAGE::OPENING: _DispBuffer = cv::imread(OPENING_FILE); _pEct->SetDispBuffer(_DispBuffer); break; - case PAGES::CALIB: + case STIM_PAGE::CALIB: _DispBuffer = cv::imread(CALIB_FILE); _pEct->SetDispBuffer(_DispBuffer); break; - case PAGES::CALIB_COMPLETE: + case STIM_PAGE::CALIB_COMPLETE: _DispBuffer = cv::imread(CALIB_COMPLETE_FILE); _pEct->SetDispBuffer(_DispBuffer); break; - case PAGES::CALIB_FAILED: + case STIM_PAGE::CALIB_FAILED: _DispBuffer = cv::imread(CALIB_FAILED_FILE); _pEct->SetDispBuffer(_DispBuffer); break; - case PAGES::WHITE: + case STIM_PAGE::WHITE: _DispBuffer = cv::imread(WHITE_FILE); _pEct->SetDispBuffer(_DispBuffer); break; - case PAGES::START: + case STIM_PAGE::START: _StimNo = 0; SetStimulus(); break; - case PAGES::STOP: + case STIM_PAGE::STOP: _StimNo = -1; _DispBuffer = cv::imread(OPENING_FILE); _pEct->SetDispBuffer(_DispBuffer); break; - case PAGES::NEXT: + case STIM_PAGE::NEXT: if (++_StimNo >= _StimInfoSet.size()) _StimNo = -1; SetStimulus(); break; @@ -131,25 +127,9 @@ // CSV�ǂݍ��� void Stimulus::ReadCsv() { - if (_StimInfoSet[_StimNo].frame.size() > 0) return; // �ǂݍ��ݍς� - std::vector> table; - if (!ReadTable(_StimInfoSet[_StimNo].csvfile, table)) return; - if (table.size() < 2) return; + if (_MovieObject.GetNumFrames() > 0) return; // �ǂݍ��ݍς� + int nFrames = _MovieObject.SetData(_StimInfoSet[_StimNo].csvfile); - for (int r = 1; r < table.size(); r++) { - if (table[r].size() < 5) continue; - FrameInfo fi; - fi.time = (float)atof(table[r][0].c_str()); - fi.target.push_back(TargetInfo( - (float)atof(table[r][1].c_str()), - (float)atof(table[r][2].c_str()), 10.F)); - fi.target.push_back(TargetInfo( - (float)atof(table[r][3].c_str()), - (float)atof(table[r][4].c_str()), 10.F)); - _StimInfoSet[_StimNo].frame.push_back(fi); - } - - DebugPrintf(_T("CSV file '%s' - %d frames read.\n"), - Multi2Wide(_StimInfoSet[_StimNo].csvfile).c_str(), - _StimInfoSet[_StimNo].frame.size()); + mwut::DebugPrintf(_T("CSV file '%s' - %d frames read.\n"), + mwut::Multi2Wide(_StimInfoSet[_StimNo].csvfile).c_str(), nFrames); } diff --git a/ECTrainer2/Stimulus.h b/ECTrainer2/Stimulus.h index 2934760..d60c95a 100644 --- a/ECTrainer2/Stimulus.h +++ b/ECTrainer2/Stimulus.h @@ -1,6 +1,7 @@ #pragma once #include "myOpenCV.h" +#include "MovieObject.h" #include "BaseProcess.h" #include #include @@ -10,19 +11,7 @@ class Marker; -struct TargetInfo { - cv::Point2f pos; - float size; - TargetInfo(float x, float y, float s) { - pos = cv::Point2f(x, y); - size = s; - } -}; - -struct FrameInfo { - float time; - std::vector target; -}; +enum class STIM_PAGE { OPENING, CALIB, CALIB_COMPLETE, CALIB_FAILED, START, STOP, NEXT, BACK, WHITE }; struct StimInfo { int type; // 1:�摜 2:���� @@ -30,13 +19,11 @@ float dulation; // ����(sec) std::string csvfile; // �^�[�Q�b�g���W�t�@�C���i�����ꍇ��_�A���_�[�o�[�j int target; // �^�[�Q�b�g�i�����ꍇ��0�j - std::vector frame; }; class Stimulus : public BaseProcess { public: - enum PAGES {OPENING, CALIB, CALIB_COMPLETE, CALIB_FAILED, START, STOP, NEXT, BACK, WHITE}; private: const cv::String OPENING_FILE = "../images/ECT_toppage.png"; const cv::String CALIB_FILE = "../images/calib.png"; @@ -47,18 +34,19 @@ Marker* _pMarker; cv::Mat _DispBuffer; std::vector _StimInfoSet; - //std::vector _StimImages; + MovieObject _MovieObject; int _StimNo; // �h���f�[�^�ԍ��@-1:��~ DWORD _StartTime; // �h���񎦊J�n���� //void StimWithMarker(); bool SetStimulus(); void ReadCsv(); + public: Stimulus(ECTrainer* pEct, Marker* pMarker); bool Init(); bool MainLoop(); - void SetPage(PAGES st); + void SetPage(STIM_PAGE st); //cv::Point2f GetEyeR() { return _StimImages[_StimNo].eyes[0]; } //cv::Point2f GetEyeL() { return _StimImages[_StimNo].eyes[1]; } }; diff --git a/ECTrainer2/TobiiREST.cpp b/ECTrainer2/TobiiREST.cpp index c88a635..d70683b 100644 --- a/ECTrainer2/TobiiREST.cpp +++ b/ECTrainer2/TobiiREST.cpp @@ -1,9 +1,14 @@ #include "ECTrainer.h" #include "TobiiREST.h" +#include "ECTrainerGUI.h" +#include "myWinUtils.h" // �R���X�g���N�^ TobiiREST::TobiiREST(ECTrainer* pEct) - :BaseProcess(pEct), _Start(false) { + :BaseProcess(pEct) + , _CalibTrigger(false) + , _CalibStatus(CALIB_STATUS::NONE) + , _BatteryLevel(999) { } @@ -12,70 +17,90 @@ try { #if defined(EYEDEVICE_GLASS2) + // Project ID�擾 json::value json = REST_Handler::POST_Request(SERVER _T("/api/projects")).extract_json().get(); _ProjectID = json[_T("pr_id")].as_string(); - std::wcout << "prId=" << _ProjectID << std::endl; - + mwut::DebugPrintf(_T("Tobii Project ID : %s\n"), _ProjectID.c_str()); + + // Participant ID�擾 json::value postData; postData[L"pa_project"] = json::value::string(_ProjectID); json = REST_Handler::POST_Request(SERVER _T("/api/participants"), postData).extract_json().get(); _ParticipantID = json[_T("pa_id")].as_string(); - std::wcout << "paId=" << _ParticipantID << std::endl; + mwut::DebugPrintf(_T("Tobii Prarticipant ID : %s\n"), _ParticipantID.c_str()); #endif return true; } catch (const std::exception & e) { - std::cout << "Error " << e.what() << std::endl; + UNREFERENCED_PARAMETER(e); // e.what() ���}���`�o�C�g������Ȃ̂Ŏg���Ȃ� +#ifdef NDEBUG + ::MessageBox(_pEct->PECTrainerGUI()->GetMainHWnd(), _T("Can't connect Tobii Device."), _T("Error"), 0); +#else + mwut::DebugPrintf(_T("Error in TobiiREST::Init()\n")); +#endif return false; } } // ���[�v bool TobiiREST::MainLoop() { + DWORD lastBatteryQuery = timeGetTime(); while (_pEct->IsAppRun()) { - if (_Start) { - _Start = false; - if (StartCalibration()) { - int res = GetCalibResult(); - if (res != 0) _pEct->SetCalibResult(res); + + // �L�����u���[�V���� + if (_CalibTrigger) { + _CalibTrigger = false; + if (StartCalib()) { + QueryCalibResult(); } } + + // �o�b�e���[���擾 + DWORD cTime = timeGetTime(); + if (cTime - lastBatteryQuery > BATTERY_QUERY_INTERVAL) { + lastBatteryQuery = cTime; + QueryBatteryLevel(); + } + Sleep(1); } return true; } // �L�����u���[�V�����J�n -bool TobiiREST::StartCalibration() { +bool TobiiREST::StartCalib() { try { #if defined(EYEDEVICE_GLASS2) + // Calibration ID�擾 json::value postData; postData[L"ca_project"] = json::value::string(_ProjectID); postData[L"ca_type"] = json::value::string(L"default"); postData[L"ca_participant"] = json::value::string(_ParticipantID); json::value json = REST_Handler::POST_Request(SERVER _T("/api/calibrations"), postData).extract_json().get(); _CalibrationID = json[_T("ca_id")].as_string(); - std::wcout << "caId=" << _CalibrationID << std::endl; + mwut::DebugPrintf(_T("Tobii Calibration ID : %s\n"), _CalibrationID.c_str()); + // Calibration�J�n std::wstring url = SERVER _T("/api/calibrations/") + _CalibrationID + _T("/start"); json = REST_Handler::POST_Request(url.c_str()).extract_json().get(); - std::wcout << "Calibration start" << std::endl; + mwut::DebugPrintf(_T("Calibration start\n")); #endif return true; } catch (const std::exception& e) { - std::cout << "Error " << e.what() << std::endl; + UNREFERENCED_PARAMETER(e); // e.what() ���}���`�o�C�g������Ȃ̂Ŏg���Ȃ� + mwut::DebugPrintf(_T("Error in TobiiREST::StartCalib()\n")); return false; } } // GetCalibResult // �߂�l -1:�G���[ 0:���s 1:���� -int TobiiREST::GetCalibResult() { +bool TobiiREST::QueryCalibResult() { try { #if defined(EYEDEVICE_GLASS2) @@ -85,34 +110,39 @@ values.push_back(_T("calibrated")); std::wstring status = REST_Handler::WaitForStatus(url.c_str(), _T("ca_state"), values); if (status == _T("failed")) { - std::wcout << _T("Calibration failed.") << std::endl; - return -1; + _CalibStatus = CALIB_STATUS::FAIL; + mwut::DebugPrintf(_T("Calibration failed\n")); + } else { + _CalibStatus = CALIB_STATUS::DONE; + mwut::DebugPrintf(_T("Calibration successful\n")); } - std::wcout << _T("Calibration successful.") << std::endl; #endif - return 1; + return true; } catch (const std::exception & e) { - std::cout << "Error " << e.what() << std::endl; - - return 0; + UNREFERENCED_PARAMETER(e); // e.what() ���}���`�o�C�g������Ȃ̂Ŏg���Ȃ� + _CalibStatus = CALIB_STATUS::ERR; + mwut::DebugPrintf(_T("Error in TobiiREST::QueryCalibResult()\n")); + return false; } } // �o�b�e���[�c�ʎ擾 -int TobiiREST::BatteryLevel() { +bool TobiiREST::QueryBatteryLevel() { try { #if defined(EYEDEVICE_GLASS2) std::wstring url = SERVER _T("/api/system/status"); auto response = REST_Handler::GET_Request(url.c_str()); json::value json = response.extract_json().get(); - return json[L"sys_battery"][L"level"].as_integer(); + _BatteryLevel = json[L"sys_battery"][L"level"].as_integer(); #elif defined(EYEDEVICE_NONE) - return 999; + _BatteryLevel = 999; #endif + return true; } catch (const std::exception & e) { - std::cout << "Error " << e.what() << std::endl; - return 0; + UNREFERENCED_PARAMETER(e); // e.what() ���}���`�o�C�g������Ȃ̂Ŏg���Ȃ� + mwut::DebugPrintf(_T("Error in TobiiREST::QueryBatteryLevel()\n")); + return false; } } diff --git a/ECTrainer2/TobiiREST.h b/ECTrainer2/TobiiREST.h index c092c00..5ce53d1 100644 --- a/ECTrainer2/TobiiREST.h +++ b/ECTrainer2/TobiiREST.h @@ -2,24 +2,32 @@ #include "REST_Handler.h" #include "BaseProcess.h" -#include #define SERVER _T("http://192.168.71.50") +enum class CALIB_STATUS { NONE, DONE, FAIL, ERR }; + class TobiiREST : public BaseProcess { + const DWORD BATTERY_QUERY_INTERVAL = 60000; // ms + utility::string_t _ProjectID; utility::string_t _ParticipantID; utility::string_t _CalibrationID; - bool _Start; + bool _CalibTrigger; + CALIB_STATUS _CalibStatus; + int _BatteryLevel; // ���ڑ��� 999 - bool StartCalibration(); - int GetCalibResult(); + bool StartCalib(); + bool QueryCalibResult(); + bool QueryBatteryLevel(); public: + TobiiREST(ECTrainer* pEct); bool Init(); bool MainLoop(); - void Start() { if (!_Start) _Start = true; }; - int BatteryLevel(); + void StartCalibration() { _CalibStatus = CALIB_STATUS::NONE; _CalibTrigger = true; }; + int GetBatteryLevel() { return _BatteryLevel; }; + CALIB_STATUS GetCalibStatus() { return _CalibStatus; } }; diff --git a/ECTrainer2/Worker.cpp b/ECTrainer2/Worker.cpp index c31e7aa..241af53 100644 --- a/ECTrainer2/Worker.cpp +++ b/ECTrainer2/Worker.cpp @@ -1,37 +1,64 @@ -#include "Worker.h" -#include "ECTrainer.h" -#include "EyeTrack.h" -#include "BitalMonitor.h" -#include "myOpenCV.h" -#include -#include +#include "common.h" -Worker::Worker(ECTrainer* pEct) : BaseProcess(pEct) { +Worker::Worker(ECTrainer* pEct) + : BaseProcess(pEct) + , LOG_FILENAME(_T("log.txt")) + , _AppStatus(APP_STATUS::BOOT) + , _fpLog(NULL) { } bool Worker::Init() { + if (_tfopen_s(&_fpLog, LOG_FILENAME, _T("w")) != 0) { + ::MessageBox(_pEct->PECTrainerGUI()->GetMainHWnd(), _T("Can't open log file."), _T("Error"), 0); + return false; + } + _ftprintf(_fpLog, _T("time,gazeVx,gazeVy,RR\n")); + return true; } bool Worker::MainLoop() { int64 start = cv::getTickCount(); - FILE* fp; - fopen_s(&fp, "log.txt", "w"); - fprintf(fp, "time,gazeVx,gazeVy,RR\n"); + _AppStatus = APP_STATUS::IDLE; while (_pEct->IsAppRun()) { + // �������X�V��҂� Sleep(0); if (!_pEct->PEyeTrack()->IsNewGazeV()) continue; + // ��ԍX�V + if (_AppStatus == APP_STATUS::CALIB) { + switch (_pEct->PTobiiREST()->GetCalibStatus()) { + case CALIB_STATUS::DONE: + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_COMPLETE); + _AppStatus = APP_STATUS::IDLE; + break; + case CALIB_STATUS::FAIL: + case CALIB_STATUS::ERR: + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_FAILED); + _AppStatus = APP_STATUS::IDLE; + break; + } + } + + // ���O�o�� auto elapse = (cv::getTickCount() - start) * 1000. / cv::getTickFrequency(); - fprintf(fp, "%.1f", elapse); + _ftprintf(_fpLog, _T("%.1f"), elapse); cv::Point2f gazeV = (_pEct->GetGazeV()); - fprintf(fp, ",%.1f,%.1f", gazeV.x, gazeV.y); - fprintf(fp, ",%d", _pEct->PBitalMonitor()->GetRR()); - fprintf(fp, "\n"); + _ftprintf(_fpLog, _T(",%.1f,%.1f"), gazeV.x, gazeV.y); + _ftprintf(_fpLog, _T(",%d"), _pEct->PBitalMonitor()->GetRR()); + _ftprintf(_fpLog, _T("\n")); } - fclose(fp); + fclose(_fpLog); + return true; +} + +bool Worker::StartCalibration() { + if (_AppStatus != APP_STATUS::IDLE) return false; + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB); + _pEct->PTobiiREST()->StartCalibration(); + _AppStatus = APP_STATUS::CALIB; return true; } diff --git a/ECTrainer2/Worker.h b/ECTrainer2/Worker.h index da6b035..65a8611 100644 --- a/ECTrainer2/Worker.h +++ b/ECTrainer2/Worker.h @@ -1,12 +1,21 @@ #pragma once #include "BaseProcess.h" +#include + + +enum class APP_STATUS { BOOT, IDLE, CALIB, EXEC }; class Worker : public BaseProcess { + const TCHAR* LOG_FILENAME; + APP_STATUS _AppStatus; + FILE* _fpLog; public: Worker(ECTrainer* pEct); bool Init(); bool MainLoop(); + bool StartCalibration(); + APP_STATUS GetAppStatus() { return _AppStatus; } }; diff --git a/ECTrainer2/common.h b/ECTrainer2/common.h new file mode 100644 index 0000000..11dec7c --- /dev/null +++ b/ECTrainer2/common.h @@ -0,0 +1,20 @@ +#pragma once + +#include "ECTrainer.h" +#include "ECTrainerGUI.h" +#include "BitalMonitor.h" +#include "EyeTrack.h" +#include "ImageProc.h" +#include "KeepAlive.h" +#include "Marker.h" +#include "SceneCamera.h" +#include "Stimulus.h" +#include "TobiiREST.h" +#include "Worker.h" +#include "myOpenCV.h" +#include "myOpenCVutil.h" +#include "myWinUtils.h" +#include +#include +#include +#include diff --git a/ECTrainer2/myOpenCVutil.cpp b/ECTrainer2/myOpenCVutil.cpp new file mode 100644 index 0000000..fac54b7 --- /dev/null +++ b/ECTrainer2/myOpenCVutil.cpp @@ -0,0 +1,61 @@ +#include "myOpenCVutil.h" + +// �����摜���c���ɘA���\�� +void imShowMulti( + cv::String winname, std::vector& imgs, // �S�Ă̕\���摜�i8bit 3ch or 8bit 1ch�̂�) + unsigned int cols, // ���̘A���� + unsigned int rows, // �c�̘A���� + cv::Size imgsize, // �\������摜�T�C�Y + unsigned int border) { + if (imgs.size() < 1 || cols < 1 || rows < 1) return; + + unsigned int w = imgsize.width + border, h = imgsize.height + border; + cv::Mat board(h * rows + border, w * cols + border, CV_8UC3, CV_RGB(128, 128, 128)); + for (unsigned int r = 0, i = 0; r < rows; r++) { + for (unsigned int c = 0; c < cols; c++, i++) { + cv::Rect roi_rect = cv::Rect(c * w + border, r * h + border, imgsize.width, imgsize.height); + cv::Mat roi(board, roi_rect); + if (i < imgs.size()) { + if (imgs[i].type() == CV_8UC3) { + resize(imgs[i], roi, imgsize); + } else if (imgs[i].type() == CV_8UC1) { + cv::Mat c3; + cvtColor(imgs[i], c3, cv::COLOR_GRAY2BGR); + resize(c3, roi, imgsize); + } else { + putText(roi, "Color mode not matched", cv::Point(20, 20), cv::FONT_HERSHEY_COMPLEX, 0.5, CV_RGB(0, 0, 0)); + } + } else { + putText(roi, "No image", cv::Point(20, 20), cv::FONT_HERSHEY_COMPLEX, 0.5, CV_RGB(0, 0, 0)); + } + } + } + imshow(winname, board); +} + +// �c�����ۂ������T�C�Y +cv::Mat KeepAspectResize(cv::Mat& img, int width, int height) { + cv::Size outputSize; + if (width > 0) { + if (height > 0) { + // �c���w��i���T�C�Y�Ɏ��܂�悤�ɂ���j + outputSize = cv::Size(height * img.cols / img.rows, width * img.rows / img.cols); + if (outputSize.width > width) outputSize.width = width; + else outputSize.height = height; + } else { + // �����w�� + outputSize = cv::Size(width, width * img.rows / img.cols); + } + } else { + if (height > 0) { + // �c���w�� + outputSize = cv::Size(height * img.cols / img.rows, height); + } else { + // �c���ǂ�����w�薳���ꍇ�͓��͂̃R�s�[��Ԃ� + return img.clone(); + } + } + cv::Mat resized; + cv::resize(img, resized, outputSize); + return resized; +} diff --git a/ECTrainer2/myOpenCVutil.h b/ECTrainer2/myOpenCVutil.h index d36185b..f4db07c 100644 --- a/ECTrainer2/myOpenCVutil.h +++ b/ECTrainer2/myOpenCVutil.h @@ -13,57 +13,7 @@ unsigned int cols, // ���̘A���� unsigned int rows, // �c�̘A���� cv::Size imgsize, // �\������摜�T�C�Y - unsigned int border) -{ - if (imgs.size() < 1 || cols < 1 || rows < 1) return; - - unsigned int w = imgsize.width + border, h = imgsize.height + border; - cv::Mat board(h * rows + border, w * cols + border, CV_8UC3, CV_RGB(128, 128, 128)); - for (unsigned int r = 0, i = 0; r < rows; r ++) { - for(unsigned int c = 0; c < cols; c ++, i ++) { - cv::Rect roi_rect = cv::Rect(c * w + border, r * h + border, imgsize.width, imgsize.height); - cv::Mat roi(board, roi_rect); - if (i < imgs.size()) { - if (imgs[i].type() == CV_8UC3) { - resize(imgs[i], roi, imgsize); - } else if (imgs[i].type() == CV_8UC1) { - cv::Mat c3; - cvtColor(imgs[i], c3, cv::COLOR_GRAY2BGR); - resize(c3, roi, imgsize); - } else { - putText(roi, "Color mode not matched", cv::Point(20,20), cv::FONT_HERSHEY_COMPLEX, 0.5, CV_RGB(0,0,0)); - } - } else { - putText(roi, "No image", cv::Point(20,20), cv::FONT_HERSHEY_COMPLEX, 0.5, CV_RGB(0,0,0)); - } - } - } - imshow(winname, board); -} + unsigned int border); // �c�����ۂ������T�C�Y -cv::Mat KeepAspectResize(cv::Mat& img, int width = 0, int height = 0) { - cv::Size outputSize; - if (width > 0) { - if (height > 0) { - // �c���w��i���T�C�Y�Ɏ��܂�悤�ɂ���j - outputSize = cv::Size(height * img.cols / img.rows, width * img.rows / img.cols); - if (outputSize.width > width) outputSize.width = width; - else outputSize.height = height; - } else { - // �����w�� - outputSize = cv::Size(width, width * img.rows / img.cols); - } - } else { - if (height > 0) { - // �c���w�� - outputSize = cv::Size(height * img.cols / img.rows, height); - } else { - // �c���ǂ�����w�薳���ꍇ�͓��͂̃R�s�[��Ԃ� - return img.clone(); - } - } - cv::Mat resized; - cv::resize(img, resized, outputSize); - return resized; -} +cv::Mat KeepAspectResize(cv::Mat& img, int width = 0, int height = 0); diff --git a/ECTrainer2/myWinUtils.cpp b/ECTrainer2/myWinUtils.cpp new file mode 100644 index 0000000..95b2dac --- /dev/null +++ b/ECTrainer2/myWinUtils.cpp @@ -0,0 +1,104 @@ +#include "MyWinUtils.h" + +#include +#include +#include + +namespace mwut { + + // �}���`�o�C�g����������C�h������iUNICODE�j�ɕϊ� + std::wstring Multi2Wide(std::string const& src) { + auto const dest_size = ::MultiByteToWideChar(CP_ACP, 0U, src.data(), -1, nullptr, 0U); + std::vector dest(dest_size, L'\0'); + if (::MultiByteToWideChar(CP_ACP, 0U, src.data(), -1, dest.data(), (int)dest.size()) == 0) { + throw std::system_error{ static_cast(::GetLastError()), std::system_category() }; + } + dest.resize(std::char_traits::length(dest.data())); + dest.shrink_to_fit(); + return std::wstring(dest.begin(), dest.end()); + } + + // �����t���f�o�b�O�o�� + int DebugPrintf(LPCTSTR format, ...) { + va_list args; + va_start(args, format); + + int len = _vsctprintf(format, args) + 1; + TCHAR* buf = (TCHAR*)malloc(len * sizeof(TCHAR)); + len = _vstprintf_s(buf, len, format, args); + + OutputDebugString(buf); + free(buf); + + return len; + } + + // �e�[�u����ǂݍ��� + bool ReadTable(const std::string& filename, STR_TABLE& table, const char delimiter) { + // �t�@�C�����J�� + std::fstream filestream(filename); + if (!filestream.is_open()) return false; // �t�@�C�����J���Ȃ������ꍇ�͏I�� + + // �t�@�C����ǂݍ��� + while (!filestream.eof()) { + // �P�s�ǂݍ��� + std::string buffer; + filestream >> buffer; + + // �t�@�C������ǂݍ��񂾂P�s�̕��������؂蕶���ŕ����ă��X�g�ɒlj����� + std::vector record; // �P�s���̕�����̃��X�g + std::istringstream streambuffer(buffer); // ������X�g���[�� + std::string token; // �P�Z�����̕����� + while (std::getline(streambuffer, token, delimiter)) { + // �P�Z�����̕���������X�g�ɒlj����� + record.push_back(token); + } + + // �P�s���̕�������o�͈����̃��X�g�ɒlj����� + table.push_back(record); + } + + return true; + } + + // �}���`�f�B�X�v���C�̏����擾 + // �v�f0�F���C���E�C���h�E + std::vector GetDisplayInfo() { + // �f�B�X�v���C���擾 + std::vector displays; + EnumDisplayMonitors(NULL, NULL, + (MONITORENUMPROC)MonitorEnumProc, (LPARAM)&displays); + + // ���C�����j�^��擪�v�f�Ɉړ� + int mainMonitor = 0; + for (int i = 0; i < displays.size(); i++) { + if (displays[i].left == 0 && displays[i].top == 0) mainMonitor = i; + } + if (mainMonitor != 0) { + SWAP::DO(displays[0], displays[mainMonitor]); + } + +#ifdef _DEBUG + for (int i = 0; i < displays.size(); i++) { + DebugPrintf(_T("Display %d%s L %d T %d R %d B %d\n"), + i, i ? _T("") : _T("(main)"), displays[i].left, displays[i].top, + displays[i].right, displays[i].bottom); + //std::cout << "Monitor" << i << " : " + // << displays[i].left << "," << displays[i].top << "," + // << displays[i].right << "," << displays[i].bottom << std::endl; + } +#endif // _DEBUG + + return displays; + } + + // �f�B�X�v���C���擾�R�[���o�b�N + BOOL CALLBACK MonitorEnumProc( + HMONITOR hMon, HDC hdcMon, LPRECT lpMon, LPARAM dwData) { + + std::vector* displays = (std::vector*)dwData; + displays->push_back(*lpMon); + return TRUE; + } +} + diff --git "a/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" "b/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" index 1685a44..542969e 100644 --- "a/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" +++ "b/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" Binary files differ