/*! * \file DynamicScratch.h * \date 2019/09/12 * * \author Deng Zouchao * Contact: deng.zouchao@hzleaper.com * * * \note */ #ifndef _DYNAMICSCRATCH_H_ #define _DYNAMICSCRATCH_H_ #include "StdUtils.h" #include "CVUtils.h" #include "CyclopsModules.h" struct ScratchPath { int x; int y;/**< hold grid position (x,y) for double judge */ float energy; vector path; }; typedef std::vector ScratchPaths; /*! \brief * * * 1) If you are using Cyclops as static library, * 1.1) and you want global factory to manage the detector for you, initialize the detector * via DpScratch::getInstance(). * Example: * \code{.cpp} * DpScratch::Ptr dsPtr = DpScratch::getInstance("detect sth"); * dsPtr->setGridWidthPara(100); * dsPtr->setMaxSearchNum(2); * dsPtr->setRatioThreshold(1.3); * dsPtr->setEraseWidthPara(10); * dsPtr->setPathMode(DpScratch::MaxPath); * dsPtr->setDirectionMode(DpScratch::BothDirection); * ScratchPaths resultPath; * resultPath = dsPtr->dynamicScratch(inputMat, gridW, maxSearchNum, ratioThreshold, eraseWitdh, pathMode); * // draw path on source image * for (int pathNos = 0; pathNos < resultPath.size(); ++pathNos) { * for (int i = 0; i < gridW; i++) * srcMat.at(resultPath[pathNos].path[i].y, resultPath[pathNos].path[i].x) = 128; * } * * // delete it later * DpScratch::deleteInstance("detect sth"); * \endcode * * 1.2) or, if you wish to manage the detector yourself: * DpScratch::Ptr dsPtr = std::make_shared(); // remember to hold the smart pointer * // balabala, same as above * // ... * \endcode * * 2) If you are using Cyclops as dynamic library, * initialize and manipulate the detector via CyclopsModules APIs. * Example: * \code{.cpp} * // get a long-term detector, and give it an unique name * DpScratch::Ptr dsPtr = GetModuleInstance("detect sth"); * // get for temporary usage * DpScratch::Ptr localDsPtr = GetModuleInstance(); * * // delete it later * DeleteModuleInstance("detect sth"); * \endcode * */ class DpScratch : public ICyclopsModuleInstance { public: enum SearchMode { /*! Find the minimum neighbour and minimum path */ MinPath = 0, /*! Find the maximum neighbour and maximum path */ MaxPath = 1, /*! Only this two modes */ }; enum SearchDirection { /*! Only search X direction */ XDirection = 0, /*! Only search Y direction */ YDirection = 1, /*! Search both X and Y directions */ BothDirection = 2, }; /*! \fn setGridWidth * Define the width of small square grid, split the ROI area into grids according to the width. * \fn getGridWidth * Get value of grid witdh */ DECLARE_PARAMETER(int, GridWidthPara) /*! \fn setMaxSearchNum * Define the number of paths should be search in a grid,which is the maximum number of defects that can exist in a grid. * note: linear defect which shorter than GridWidth may not be detected, and smaller GridWidth will lead to increased time consuming * \fn getMaxSearchNum * Get number of paths in a grid. */ DECLARE_PARAMETER(int, MaxSearchNum) /*! \fn setRatioThreshold * Define the sensitivity of detection should be search in a grid. * The closer to 1, the more sensitive, when the contrast between the defect and the background is weak, this parameter should be reduced. * \fn getRatioThreshold * Get value of detection sensitivity */ DECLARE_PARAMETER(float, RatioThreshold) /*! \fn setEraseWidth * Define the width to be erase after dp calculation, in oder to find the other path, usually be maximum defect width * \fn getEraseWidth * Get value of width */ DECLARE_PARAMETER(int, EraseWidthPara) /*! \fn setPathMode * Define the path mode: * 0 for find the minimum neighbour and minimum path * 1 for find the maximum neighbour and maximum path * \fn getPathMode * Get path mode */ DECLARE_PARAMETER(SearchMode, PathMode) /*! \fn setDirectionMode * Define the search direction: * 0 for only search X direction * 1 for only search Y direction * 2 for search both X and Y directions * \fn getDirectionMode * Get direction mode */ DECLARE_PARAMETER(SearchDirection, DirectionMode) //! Smart pointer to hold an instance of DpScratch typedef std::shared_ptr Ptr; DECL_GET_INSTANCE(DpScratch::Ptr) public: DpScratch(): mGridWidthPara(100), mMaxSearchNum(2), mRatioThreshold(1.2), mEraseWidthPara(10), mPathMode(MaxPath), mDirectionMode(BothDirection) {} virtual ~DpScratch() {} /*! Find the linear defect in the image * @param inputMat input image for detection * @return the search result */ virtual ScratchPaths dynamicScratch(const Mat& inputMat); /*! Find the linear defect in the image support rotate ROI * @param inputMat input image for detection * @param roiVertexes roi for detection * @param roiDir scan direction of roi * @return the search result */ virtual ScratchPaths dynamicScratch(const Mat& inputMat, const vector& roiVertexes, const Point2f& roiDir); private: void paraInit(const Mat& greyMat); template void dynamicProgram(Mat& oriDisMat, Mat& backTrackROIMat, Mat& disMat, Func func); void findPath(Mat& disMat, Mat& backTrackROIMat, int pathNos); void pathJudgeInGrid(ScratchPaths& selectedPaths, int x, int y); template void erasePath(Mat& oriDisMat, vector& path, int rowOffset); void pathSearchinGrid(Mat& oriDisMat, Mat& backTrackROIMat, float *pMidEnergyMat, int y, int x); void getPathandEnergy(void); void pathDoubleJudge(Mat& midEnergyMat, ScratchPaths& selectedPaths, bool isTrans); void genResult(void); bool mIsCloned = false; int mGridWidth, mEraseWidth; int mGridXNum, mGridYNum; double mEraseColor; ScratchPaths mResultPaths, mPaths, mSelectedPaths, mSelectedTransPaths; Mat mMidEnergyXMat, mMidEnergyYMat; Mat mGreyMat, mGreyTransMat; Mat mXBackTrackMat, mYBackTrackMat; }; #endif