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.
whellvalue/3part/Cyclops/include/FlatFieldCalibrator.h

206 lines
7.1 KiB
C

5 years ago
/*!
* \file lightCompensate.h
* \date 2019/08/13
*
* \author Lou.Lixuan
* Contact: Lou.Lixuan@hzleaper.com
*
*
* \note
*/
#ifndef FlatFieldCalibrator_h_
#define FlatFieldCalibrator_h_
#include "StdUtils.h"
#include "CVUtils.h"
#include "CyclopsModules.h"
/*! \brief calibrate non-uniformity between same background pixles.
*
* Note: Both gray and color source is supported.
*
* Example:
* \code{.cpp}
* Mat src = imread("yourfilePath/picName.png", 1);
* FlatFieldCalibrator calib;
* calib.setInitBGR(Scalar(70,87,60));
* calib.setExpectedBGR(Scalar(105, 120, 112));
* calib.setBGRWidth(10, 10, 10);
* calib.setKernelSize(81, 81);
* calib.setRefreshSpeed(0.5);
* calib.init(src, FlatFieldCalibrator::COLOR);
*
* string filePath = "yourfilePath";
* float changeRate = 0.0;
* for (int i = 0; i < 100; ++i) {
* string fileName = to_string(i) + ".png";
* Mat trainMat = imread(path + fileName, 0);
* calib.train(trainMat, changeRate, FlatFieldCalibrator::COLOR);
* }
* Mat intensity
* calib.foregroundToIntensity(intensity, FlatFieldCalibrator::COLOR);
* Mat testMat = imread("yourfilePath/testPicName.png", 1), dst;
* calib.apply(testMat, dst, FlatFieldCalibrator::COLOR);
* \endcode
*
*/
class FlatFieldCalibrator : public ICyclopsModuleInstance
{
public:
enum ColorType {
GRAY, COLOR
};
enum FieldCalcType
{
/*! get light intensity directly in every iteration */
DIRECT = 0,
/*! extract foreground in every iteration, get light intensity finally*/
INDIRECT = 1,
// add more type before this line...
};
/*! \fn setFieldCalcType
* Define which algorithm we should use in light field construction, default to INDIRECT
* \fn getInitRange
* Get which algorithm we are using in light field construction
*/
DECLARE_PARAMETER_GET(FieldCalcType, FieldCalcType)
/*! \fn setInitBGR
* Define initial value of pixels belong to background, 3 to 255, default to (70, 70, 70)
* \fn getInitBGR
* Get initial value of pixels belong to foreground
*/
DECLARE_PARAMETER_GET(Scalar, InitBGR)
/*! \fn setExpectedBGR
* Define expected BGR value of pixels belong to background, 3 to 255, default to <120, 120, 120>
* \fn getExpectedBGR
* Get expected BGR value of pixels belong to foreground
*/
DECLARE_PARAMETER_GET(Scalar, ExpectedBGR)
/*! \fn setBGRWidth
* Define distribution width of BGR value belong to background, 3 to 25, default to <10, 10, 10>
* \fn getBGRWidth
* Get distribution width of BGR value belong to foreground
*/
DECLARE_PARAMETER_GET(Scalar, BGRWidth)
// define kernel size, odd numbers(1, 3, 5, ...), 1 to INT_MAX, default to (121, 121)
DECLARE_PARAMETER_GET(Size, KSize)
/*! \fn setRefreshSpeed
* Define refresh speed of light field, 0 to 1.0, default to 0.5
* \fn getBGRWidth
* Get refresh speed of light field
*/
DECLARE_PARAMETER2(float, RefreshSpeed, 0, 1.0)
/*! \fn setGroundDensity
* Define minimum density of foregroundMask which is used to dilate foreground, 0 to 1.0, default to 0.2
* \fn getGroundDensity
* Get minimum density of foregroundMask which is used to dilate foreground
*/
DECLARE_PARAMETER2(float, GroundDensity, 0, 1.0)
/*! \fn setIterationNum
* Define maximum number of iterations, 50 to 200, default to 50
* \fn getIterationNum
* Get maximum number of iterations
*/
DECLARE_PARAMETER2(int, IterationNum, 10, 200)
/*! \fn setPrecision
* Define precision during training, default to 0.01
* \fn getPrecision
* Get value of precision
*/
DECLARE_PARAMETER(float, Precision)
public:
FlatFieldCalibrator();
virtual ~FlatFieldCalibrator() {}
typedef std::shared_ptr<FlatFieldCalibrator> Ptr;
DECL_GET_INSTANCE(FlatFieldCalibrator::Ptr)
/*! \fn serializeToMemory
* Serialize FlatFieldCalibrator (including its calibration matrix) into a in-memory string, see also deserializeFromMemory()
* @param str used to take the output serialization result
* @return true for succeed, false for fail
* \fn serializeToFile
* Serialize FlatFieldCalibrator (including its calibration matrix) into a text file, see also deserializeFromFile()
* @param filename file name (full path) where we will write the data
* @return true for succeed, false for fail
* \fn deserializeFromMemory
* Deserialize FlatFieldCalibrator from in-memory string, see also serializeToMemory()
* @param str in-memory string
* @return true for succeed, false for fail
* \fn deserializeFromFile
* Deserialize FlatFieldCalibrator from a text file, see also serializeToFile()
* @param filename file name (full path) where we will read the data
* @return true for succeed, false for fail
*/
DECL_SERIALIZE_FUNCS
virtual bool setInitBGR(Scalar color);
virtual bool setExpectedBGR(Scalar color);
virtual bool setBGRWidth(Scalar colorWidth);
virtual bool setKernelSize(int w, int h);
Mat getGrayIntensity() { return mGrayIntensity.clone(); }
Mat getColorIntensity() { return mColorIntensity.clone(); }
/*! initialize intensity mat
* @param src input the source image, whose light intensity will be extracted
* @param type input type of calibrate, ColorType::<GRAY, COLOR>
*/
virtual bool init(const Mat&src, int colorType);
/*! extracted information from image, refresh intensity mat
* @param src input the source image, whose light intensity will be extracted
* @param maskChangedRate output the change rate of intensity
* @param type input type of calibrate, ColorType::<GRAY, COLOR>
*/
virtual bool train(const Mat&src, float& changeRate, int type);
/*! apply light compensation to the image
* @param src input the source image
* @param dst output light compensated image
* @param type input type of calibrate, ColorType::<GRAY, COLOR>
*/
virtual bool apply(const Mat& src, Mat& dst, int type);
/*! transform foreground to intensity field
* @param intensity output the intensity mat
* @param type input type of calibrate, ColorType::<GRAY, COLOR>
*/
virtual bool foregroundToIntensity(Mat& intensity, int colorType);
private:
void initLightField(const Mat& src, int colorType);
/*! refresh intensity according to src image and background mask
* @param src input the source image
* @param curIntensity input the current intensity
* @param nextIntensity input the nextIntensity, avoid space allocation
* @param tempI input temp space, avoid space allocation
* @param backgroundMask input mask of background
* @param type input type of calibrate
* @return change rate of intensity
*/
float refreshIntensity(const Mat& src, Mat& curIntensity, Mat&nextIntensity, Mat& tempI, const Mat& backgroundMask, int type);
float _train(const Mat& src, int type);
float _trainColor(const Mat& src);
void extractForeground(const Mat& src, int colorType);
void dilateCurForeground(const Mat& src, Mat& curForeground, Mat& foregroundMask, int colorType);
/*! there is only one connected domain
* @param srcMask input the source mask
* @param domainMask output main domain mask
*/
void getMainDomainMask(const Mat& srcMask, Mat& domainMask);
bool patchUp(const Mat&src, const Rect& rect, int type);
virtual bool serialize(FileStorage& fs);
virtual bool deserialize(const FileNode& fs);
private:
Mat mGrayIntensity;
Mat mColorIntensity;
Mat mMaskLUT;
Mat mMask;
Mat mForeground;
bool mNewForeground;
};
#endif