You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
5.8 KiB
C
185 lines
5.8 KiB
C
|
5 years ago
|
/*!
|
||
|
|
* \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<Point> path;
|
||
|
|
};
|
||
|
|
typedef std::vector<ScratchPath> 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<uchar>(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<DpScratch>(); // 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<DpScratch>("detect sth");
|
||
|
|
* // get for temporary usage
|
||
|
|
* DpScratch::Ptr localDsPtr = GetModuleInstance<DpScratch>();
|
||
|
|
*
|
||
|
|
* // delete it later
|
||
|
|
* DeleteModuleInstance<DpScratch>("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<DpScratch> 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<Point2f>& roiVertexes, const Point2f& roiDir);
|
||
|
|
|
||
|
|
private:
|
||
|
|
void paraInit(const Mat& greyMat);
|
||
|
|
template<typename T, typename Func> 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<typename T> void erasePath(Mat& oriDisMat, vector<Point>& 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
|