diff --git a/PipelineSample.sln b/PipelineSample.sln new file mode 100644 index 0000000..4104053 --- /dev/null +++ b/PipelineSample.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PipelineSample", "PipelineSample\PipelineSample.vcxproj", "{E8C2BD60-840C-4D97-844A-3AB277C6EB2D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Debug|x64.ActiveCfg = Debug|x64 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Debug|x64.Build.0 = Debug|x64 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Debug|x86.ActiveCfg = Debug|Win32 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Debug|x86.Build.0 = Debug|Win32 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Release|x64.ActiveCfg = Release|x64 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Release|x64.Build.0 = Release|x64 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Release|x86.ActiveCfg = Release|Win32 + {E8C2BD60-840C-4D97-844A-3AB277C6EB2D}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {76D2C8B4-7490-4BE2-87A7-1B071A2FF1F8} + EndGlobalSection +EndGlobal diff --git a/PipelineSample/PipelineSample.vcxproj b/PipelineSample/PipelineSample.vcxproj new file mode 100644 index 0000000..de0a095 --- /dev/null +++ b/PipelineSample/PipelineSample.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + 16.0 + Win32Proj + {e8c2bd60-840c-4d97-844a-3ab277c6eb2d} + PipelineSample + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/PipelineSample/PipelineSample.vcxproj.filters b/PipelineSample/PipelineSample.vcxproj.filters new file mode 100644 index 0000000..6ee2850 --- /dev/null +++ b/PipelineSample/PipelineSample.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + ソース ファイル + + + + + ヘッダー ファイル + + + \ No newline at end of file diff --git a/PipelineSample/main.cpp b/PipelineSample/main.cpp new file mode 100644 index 0000000..d4b3361 --- /dev/null +++ b/PipelineSample/main.cpp @@ -0,0 +1,104 @@ +#include +#include "nkcOpenCV.h" + +// パイブライン処理データ +struct PipelineData { + static const int NUM_BUF = 2; + + bool running; // 実行中フラグ + + cv::Mat camBuf[NUM_BUF]; // カメラフレームバッファ + int camWrite; // カメラ書き込みバッファ番号 + int camRead; // カメラ読み込みバッファ番号 + bool camUpdate; // カメラバッファの更新フラグ + + cv::Mat procBuf[NUM_BUF]; // 画像処理フレームバッファ + int procWrite; // 画像処理結果書き込みバッファ番号 + int procRead; // 画像処理結果読み込みバッファ番号 + bool procUpdate; // 画像処理バッファの更新フラグ + + // コンストラクタ(変数初期化) + PipelineData() { + running = true; + camWrite = procWrite = 0; + camRead = procRead = 0; + camUpdate = procUpdate = false; + } +}; + +// 関数の宣言 +DWORD WINAPI CameraThread(LPVOID param); +DWORD WINAPI ProcThread(LPVOID param); + +// メイン関数 +// 全体の初期化とUI処理 +int main() { + + const cv::String WINDOW = "Pipeline"; + cv::namedWindow(WINDOW, cv::WINDOW_AUTOSIZE); + + PipelineData pd; + + auto threadCamera = ::CreateThread(NULL, 0, CameraThread, &pd, 0, NULL); + auto threadProc = ::CreateThread(NULL, 0, ProcThread, &pd, 0, NULL); + + while (pd.running) { + // 前段スレッド結果受け取り + while (!pd.procUpdate) ::Sleep(1); // 画像処理バッファ更新待ち + pd.procUpdate = false; // 更新フラグをリセット + auto disp = pd.procBuf[pd.procRead].clone(); // データ受け取り + + cv::imshow(WINDOW, disp); // 画面表示(UI関数)mainスレッドのみ + auto key = cv::waitKey(1); // イベント処理(UI関数)mainスレッドのみ + if (key == 27) pd.running = false; + } + + ::WaitForSingleObject(threadCamera, INFINITE); // カメラスレッド終了待機 + ::WaitForSingleObject(threadProc, INFINITE); // 画像処理スレッド終了待機 + + return 0; +} + +// カメラスレッド +DWORD WINAPI CameraThread(LPVOID param) { + auto ppd = (PipelineData*)param; + + cv::VideoCapture cam(0); // カメラ接続 + + while (ppd->running) { + // 処理 + cam >> ppd->camBuf[ppd->camWrite]; // カメラ入力 + + // 後段へ渡すデータをセット + ppd->camRead = ppd->camWrite; // 読み込みバッファの切替 + ppd->camWrite = 1 - ppd->camWrite; // 書き込みバッファの切替 + ppd->camUpdate = true; // 更新フラグ立てる + } + + return 0; +} + +// 画像処理スレッド +DWORD WINAPI ProcThread(LPVOID param) { + auto ppd = (PipelineData*)param; + + while (ppd->running) { + // 前段スレッド結果受け取り + while (!ppd->camUpdate) ::Sleep(1); // カメラバッファ更新待ち + ppd->camUpdate = false; // 更新フラグをリセット + auto imgIn = ppd->camBuf[ppd->camRead].clone(); // データ受け取り + + // 処理 + cv::Mat blurred; + cv::GaussianBlur(imgIn, blurred, cv::Size(15, 15), 5.0); + ::Sleep(10); // ダミー,時間消費 + + // 後段へ渡すデータをセット + ppd->procBuf[ppd->procWrite] = blurred; // 画像処理結果セット + ppd->procRead = ppd->procWrite; // 読み込みバッファの切替 + ppd->procWrite = 1 - ppd->procWrite; // 書き込みバッファの切替 + ppd->procUpdate = true; // 更新フラグ立てる + } + + return 0; +} diff --git a/PipelineSample/nkcOpenCV.h b/PipelineSample/nkcOpenCV.h new file mode 100644 index 0000000..1619766 --- /dev/null +++ b/PipelineSample/nkcOpenCV.h @@ -0,0 +1,130 @@ + +// OpenCV 3�n, 4�n ���ʃw�b�_�[�t�@�C�� +// T.Nakaguchi, CFME, Chiba Univ., 2019 + +#pragma once + +// �w�b�_�[�t�@�C�� +#pragma warning(disable: 4819) +#include +#include +#pragma warning(default: 4819) + +// �o�[�W�����擾 +#define CV_VERSION_STR CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION) + +// �r���h���[�h +#ifdef _DEBUG +#define CV_EXT_STR "d.lib" +#else +#define CV_EXT_STR ".lib" +#endif + +// ���C�u�����̃����N�i�s�v�ȕ��̓R�����g�A�E�g�j +#define PRE_COMPILE 0 // �C���X�g�[���łȂ� 1 �•ʃ��C�u�����g�p���� 0 +#define PREHEAD "opencv_" + +#if PRE_COMPILE +// OpenCV3 �C���X�g�[���� +#pragma comment(lib, PREHEAD "world" CV_VERSION_STR CV_EXT_STR) // �S�� +#pragma comment(lib, PREHEAD "ts" CV_VERSION_STR CV_EXT_STR) // �f���֘A + +#else +// �•ʂ̃��C�u�����w�� �iCmake��Static�Ŏg�p���Ȃǁj +// ��{���W���[�� +#pragma comment(lib, PREHEAD "core" CV_VERSION_STR CV_EXT_STR) // Core functionality +#pragma comment(lib, PREHEAD "imgproc" CV_VERSION_STR CV_EXT_STR) // Image processing +#pragma comment(lib, PREHEAD "imgcodecs" CV_VERSION_STR CV_EXT_STR) // Image file reading and writing +#pragma comment(lib, PREHEAD "videoio" CV_VERSION_STR CV_EXT_STR) // Video I/O +#pragma comment(lib, PREHEAD "highgui" CV_VERSION_STR CV_EXT_STR) // High-level GUI +//#pragma comment(lib, PREHEAD "video" CV_VERSION_STR CV_EXT_STR) // Video Analysis +#pragma comment(lib, PREHEAD "calib3d" CV_VERSION_STR CV_EXT_STR) // Camera Calibration and 3D Reconstruction +//#pragma comment(lib, PREHEAD "features2d" CV_VERSION_STR CV_EXT_STR) // 2D Features Framework +//#pragma comment(lib, PREHEAD "objdetect" CV_VERSION_STR CV_EXT_STR) // Object Detection +//#pragma comment(lib, PREHEAD "dnn" CV_VERSION_STR CV_EXT_STR) // Deep Neural Network module +//#pragma comment(lib, PREHEAD "ml" CV_VERSION_STR CV_EXT_STR) // Machine Learning +//#pragma comment(lib, PREHEAD "flann" CV_VERSION_STR CV_EXT_STR) // Clustering and Search in Multi-Dimensional Spaces +//#pragma comment(lib, PREHEAD "photo" CV_VERSION_STR CV_EXT_STR) // Computational Photography +//#pragma comment(lib, PREHEAD "stitching" CV_VERSION_STR CV_EXT_STR) // Images stitching +//#pragma comment(lib, PREHEAD "cudaarithm" CV_VERSION_STR CV_EXT_STR) // CUDA Operations on Matrices +//#pragma comment(lib, PREHEAD "cudabgsegm" CV_VERSION_STR CV_EXT_STR) // CUDA Background Segmentation +//#pragma comment(lib, PREHEAD "cudacodec" CV_VERSION_STR CV_EXT_STR) // CUDA Video Encoding/Decoding +//#pragma comment(lib, PREHEAD "cudafeatures2d" CV_VERSION_STR CV_EXT_STR) // CUDA Feature Detection and Description +//#pragma comment(lib, PREHEAD "cudafilters" CV_VERSION_STR CV_EXT_STR) // CUDA Image Filtering +//#pragma comment(lib, PREHEAD "cudaimgproc" CV_VERSION_STR CV_EXT_STR) // CUDA Image Processing +//#pragma comment(lib, PREHEAD "cudalegacy" CV_VERSION_STR CV_EXT_STR) // CUDA Legacy support +//#pragma comment(lib, PREHEAD "cudaobjdetect" CV_VERSION_STR CV_EXT_STR) // CUDA Object Detection +//#pragma comment(lib, PREHEAD "cudaoptflow" CV_VERSION_STR CV_EXT_STR) // CUDA Optical Flow +//#pragma comment(lib, PREHEAD "cudastereo" CV_VERSION_STR CV_EXT_STR) // CUDA Stereo Correspondence +//#pragma comment(lib, PREHEAD "cudawarping" CV_VERSION_STR CV_EXT_STR) // CUDA Image Warping +//#pragma comment(lib, PREHEAD "cudev" CV_VERSION_STR CV_EXT_STR) // CUDA Device layer +//#pragma comment(lib, PREHEAD "shape" CV_VERSION_STR CV_EXT_STR) // Shape Distance and Matching +//#pragma comment(lib, PREHEAD "superres" CV_VERSION_STR CV_EXT_STR) // Super Resolution +//#pragma comment(lib, PREHEAD "videostab" CV_VERSION_STR CV_EXT_STR) // Video Stabilization +//#pragma comment(lib, PREHEAD "viz" CV_VERSION_STR CV_EXT_STR) // 3D Visualizer + +// �g�����W���[�� +#pragma comment(lib, PREHEAD "aruco" CV_VERSION_STR CV_EXT_STR) // ArUco Marker Detection +//#pragma comment(lib, PREHEAD "bgsegm" CV_VERSION_STR CV_EXT_STR) // Improved Background-Foreground Segmentation Methods +//#pragma comment(lib, PREHEAD "bioinspired" CV_VERSION_STR CV_EXT_STR) // Biologically inspired vision models and derivated tools +//#pragma comment(lib, PREHEAD "ccalib" CV_VERSION_STR CV_EXT_STR) // Custom Calibration Pattern for 3D reconstruction +//#pragma comment(lib, PREHEAD "cnn_3dobj" CV_VERSION_STR CV_EXT_STR) // 3D object recognition and pose estimation API +//#pragma comment(lib, PREHEAD "cvv" CV_VERSION_STR CV_EXT_STR) // GUI for Interactive Visual Debugging of Computer Vision Programs +//#pragma comment(lib, PREHEAD "datasets" CV_VERSION_STR CV_EXT_STR) // Framework for working with different datasets +//#pragma comment(lib, PREHEAD "dnn_objdetect" CV_VERSION_STR CV_EXT_STR) // DNN used for object detection +//#pragma comment(lib, PREHEAD "dpm" CV_VERSION_STR CV_EXT_STR) // Deformable Part-based Models +//#pragma comment(lib, PREHEAD "face" CV_VERSION_STR CV_EXT_STR) // Face Analysis +//#pragma comment(lib, PREHEAD "freetype" CV_VERSION_STR CV_EXT_STR) // Drawing UTF-8 strings with freetype/harfbuzz +//#pragma comment(lib, PREHEAD "fuzzy" CV_VERSION_STR CV_EXT_STR) // Image processing based on fuzzy mathematics +//#pragma comment(lib, PREHEAD "hdf" CV_VERSION_STR CV_EXT_STR) // Hierarchical Data Format I/O routines +//#pragma comment(lib, PREHEAD "hfs" CV_VERSION_STR CV_EXT_STR) // Hierarchical Feature Selection for Efficient Image Segmentation +//#pragma comment(lib, PREHEAD "img_hash" CV_VERSION_STR CV_EXT_STR) // The module brings implementations of different image hashing algorithms. +//#pragma comment(lib, PREHEAD "line_descriptor" CV_VERSION_STR CV_EXT_STR) // Binary descriptors for lines extracted from an image +//#pragma comment(lib, PREHEAD "matlab" CV_VERSION_STR CV_EXT_STR) // MATLAB Bridge +//#pragma comment(lib, PREHEAD "optflow" CV_VERSION_STR CV_EXT_STR) // Optical Flow Algorithms +//#pragma comment(lib, PREHEAD "ovis" CV_VERSION_STR CV_EXT_STR) // OGRE 3D Visualiser +//#pragma comment(lib, PREHEAD "phase_unwrapping" CV_VERSION_STR CV_EXT_STR) // Phase Unwrapping API +//#pragma comment(lib, PREHEAD "plot" CV_VERSION_STR CV_EXT_STR) // Plot function for Mat data +//#pragma comment(lib, PREHEAD "reg" CV_VERSION_STR CV_EXT_STR) // Image Registration +//#pragma comment(lib, PREHEAD "rgbd" CV_VERSION_STR CV_EXT_STR) // RGB-Depth Processing +//#pragma comment(lib, PREHEAD "saliency" CV_VERSION_STR CV_EXT_STR) // Saliency API +//#pragma comment(lib, PREHEAD "sfm" CV_VERSION_STR CV_EXT_STR) // Structure From Motion +//#pragma comment(lib, PREHEAD "stereo" CV_VERSION_STR CV_EXT_STR) // Stereo Correspondance Algorithms +//#pragma comment(lib, PREHEAD "structured_light" CV_VERSION_STR CV_EXT_STR) // Structured Light API +//#pragma comment(lib, PREHEAD "surface_matching" CV_VERSION_STR CV_EXT_STR) // Surface Matching +//#pragma comment(lib, PREHEAD "text" CV_VERSION_STR CV_EXT_STR) // Scene Text Detection and Recognition +//#pragma comment(lib, PREHEAD "tracking" CV_VERSION_STR CV_EXT_STR) // Tracking API +//#pragma comment(lib, PREHEAD "xfeatures2d" CV_VERSION_STR CV_EXT_STR) // Extra 2D Features Framework +//#pragma comment(lib, PREHEAD "ximgproc" CV_VERSION_STR CV_EXT_STR) // Extended Image Processing +//#pragma comment(lib, PREHEAD "xobjdetect" CV_VERSION_STR CV_EXT_STR) // Extended object detection +//#pragma comment(lib, PREHEAD "xphoto" CV_VERSION_STR CV_EXT_STR) // Additional photo processing algorithms +#endif + +//using namespace cv; + + +#include + +namespace nkc { +namespace ocv { + +// �҂��Ȃ�waitKey() +// �߂�l�F���̓L�[�R�[�h�C�L�[���͂Ȃ� -1�CWM_QUIT��M 0 +int noWaitKey(); + +// �����摜���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); + +// �c�����ۂ������T�C�Y +cv::Mat KeepAspectResize(cv::Mat& img, int width = 0, int height = 0); + +// �E�C���h�E�n���h�����擾 +HANDLE getWindowHandle(cv::String winname); + +}; // namespace ocv +}; // namespace nkc diff --git a/PipelineSample/opencv450.props b/PipelineSample/opencv450.props new file mode 100644 index 0000000..088192c --- /dev/null +++ b/PipelineSample/opencv450.props @@ -0,0 +1,15 @@ + + + + + + D:\SDK\OpenCV4.5.0\include;$(IncludePath) + D:\SDK\OpenCV4.5.0\x64\vc16\lib;$(LibraryPath) + + + D:\SDK\OpenCV4.5.0\include;$(IncludePath) + D:\SDK\OpenCV4.5.0\x86\vc16\lib\lib;$(LibraryPath) + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..aae5dca --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +PipelineSample +=============== +パイプライン処理の実装例 + +## 説明 +- パイプライン処理の流れがわかるように実装していますので,効率は最適化されていません. +- データ更新フラグ(camUpdate, procUpdate)の実装は簡単ですが,本番ではお勧めできません.性能を重視するならばEventシグナルを使ってください.(なぜ変数フラグでは性能が低下するのか理由がわかった人は中口まで) +- 更新チェック機能も含めたダブルバッファクラスを作るとよいでしょう. +- パイプラインスレッドクラスも作るとよいでしょう. + +## 開発環境 +- Windows 10 Pro +- Visual Studio 2019 (C++)