|
|
|
@ -15,8 +15,6 @@
|
|
|
|
#include <fstream>
|
|
|
|
#include <fstream>
|
|
|
|
#include "MultiScaleObj.h"
|
|
|
|
#include "MultiScaleObj.h"
|
|
|
|
#include "ICompareModel.h"
|
|
|
|
#include "ICompareModel.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define COLS_SCALE (float)(1200.0/ 416.0)
|
|
|
|
|
|
|
|
using std::set;
|
|
|
|
using std::set;
|
|
|
|
using std::map;
|
|
|
|
using std::map;
|
|
|
|
using std::fstream;
|
|
|
|
using std::fstream;
|
|
|
|
@ -96,14 +94,9 @@ public:
|
|
|
|
float outterR = -1);
|
|
|
|
float outterR = -1);
|
|
|
|
static void selfRotationSimilarityFeature(const Mat& img,
|
|
|
|
static void selfRotationSimilarityFeature(const Mat& img,
|
|
|
|
vector<float>& vec, Point2f cen = Point2f(-1, -1));
|
|
|
|
vector<float>& vec, Point2f cen = Point2f(-1, -1));
|
|
|
|
Mat genMask(const Mat& img, Point2f center, float innerR = -1,
|
|
|
|
static Mat genMask(const Mat& img, Point2f center, float innerR = -1,
|
|
|
|
float outterR = -1,
|
|
|
|
float outterR = -1,
|
|
|
|
int type = CV_32FC1);
|
|
|
|
int type = CV_32FC1);
|
|
|
|
|
|
|
|
|
|
|
|
Mat genInsideMask (const Mat& img, Point2f center, float innerR = -1,
|
|
|
|
|
|
|
|
float outterR = -1,
|
|
|
|
|
|
|
|
int type = CV_32FC1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void genCandidateRepeatNums(set<unsigned int>& canNums);
|
|
|
|
static void genCandidateRepeatNums(set<unsigned int>& canNums);
|
|
|
|
int computeRepeatNum(const Mat& img);
|
|
|
|
int computeRepeatNum(const Mat& img);
|
|
|
|
static int recognizeLowerExtremes(const Mat& vec, set<unsigned int> canNums, int extremeRefineRange = 5, vector<int> *pExtemeIdxVec = 0);
|
|
|
|
static int recognizeLowerExtremes(const Mat& vec, set<unsigned int> canNums, int extremeRefineRange = 5, vector<int> *pExtemeIdxVec = 0);
|
|
|
|
@ -115,42 +108,38 @@ public:
|
|
|
|
static void genCandidateAngleRanges(const Mat& disMat, float angleStep,
|
|
|
|
static void genCandidateAngleRanges(const Mat& disMat, float angleStep,
|
|
|
|
vector<Range>& rangeVec, float rangeScale = 1);
|
|
|
|
vector<Range>& rangeVec, float rangeScale = 1);
|
|
|
|
static void selfRotateMin(const Mat& img, Mat& weightMat, int repeatNum);
|
|
|
|
static void selfRotateMin(const Mat& img, Mat& weightMat, int repeatNum);
|
|
|
|
float allocateInnerRadius(cv::Mat subImage);
|
|
|
|
|
|
|
|
float allocateRadius(cv::Mat subImage);
|
|
|
|
|
|
|
|
void resizeVecMat(vector<Mat> srcVec, vector<Mat> &dstVec);
|
|
|
|
|
|
|
|
void resizeMat(Mat src, Mat &dst);
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
ImageCompareModel() :
|
|
|
|
ImageCompareModel() :
|
|
|
|
mMatchValScale(1.0),
|
|
|
|
mMatchValScale(1.0),
|
|
|
|
mTargetMeanVal(127),
|
|
|
|
mTargetMeanVal(127),
|
|
|
|
mTargetStddevVal(50),
|
|
|
|
mTargetStddevVal(50),
|
|
|
|
mHighlightsThreshold(256),
|
|
|
|
mHighlightsThreshold(256),
|
|
|
|
mRepeatNum(0),
|
|
|
|
mRepeatNum(0),
|
|
|
|
mName("unnamed"),
|
|
|
|
mName("unnamed"),
|
|
|
|
mDisThre(DBL_MAX),
|
|
|
|
mDisThre(DBL_MAX),
|
|
|
|
mTrueSampleDisMin(DBL_MAX),
|
|
|
|
mTrueSampleDisMin(DBL_MAX),
|
|
|
|
mTrueSampleDisMax(DBL_MIN),
|
|
|
|
mTrueSampleDisMax(DBL_MIN),
|
|
|
|
mTrueSampleDisMean(-1),
|
|
|
|
mTrueSampleDisMean(-1),
|
|
|
|
mTrueSampleDisStddev(-1),
|
|
|
|
mTrueSampleDisStddev(-1),
|
|
|
|
mIsEnableCache(false),
|
|
|
|
mIsEnableCache(false),
|
|
|
|
mpMultiScaleModel(NULL),
|
|
|
|
mpMultiScaleModel(NULL),
|
|
|
|
meanDiameter(0),
|
|
|
|
meanDiameter(0),
|
|
|
|
realWidth(0),
|
|
|
|
realWidth(0),
|
|
|
|
realHeight(0),
|
|
|
|
realHeight(0)
|
|
|
|
rInner(DBL_MAX)
|
|
|
|
|
|
|
|
{};
|
|
|
|
{};
|
|
|
|
ImageCompareModel(const ImageCompareModel& model)
|
|
|
|
ImageCompareModel(const ImageCompareModel& model)
|
|
|
|
: mAlignBaseImg(model.getBaseImg().clone())
|
|
|
|
: mAlignBaseImg(model.getBaseImg().clone())
|
|
|
|
, mWeightMat(model.getWeightMat().clone())
|
|
|
|
, mWeightMat(model.getWeightMat().clone())
|
|
|
|
, mMatchValScale(model.getMatchValScale())
|
|
|
|
, mMatchValScale(model.getMatchValScale())
|
|
|
|
, mInSideBaseImg(model.getInsideBaseImg().clone())
|
|
|
|
|
|
|
|
, mInsideWeightMat(model.getInsideWeightImg().clone())
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
genMask();
|
|
|
|
genMask();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
~ImageCompareModel() {};
|
|
|
|
~ImageCompareModel() {};
|
|
|
|
|
|
|
|
|
|
|
|
void printInfo();
|
|
|
|
void printInfo();
|
|
|
|
|
|
|
|
|
|
|
|
void saveImages(string dirPath);
|
|
|
|
void saveImages(string dirPath);
|
|
|
|
bool save2file(string filePath);
|
|
|
|
bool save2file(string filePath);
|
|
|
|
bool readFromFile(string filePath);
|
|
|
|
bool readFromFile(string filePath);
|
|
|
|
@ -159,8 +148,6 @@ public:
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mAlignBaseImg = model.getBaseImg().clone();
|
|
|
|
mAlignBaseImg = model.getBaseImg().clone();
|
|
|
|
mWeightMat = model.getWeightMat().clone();
|
|
|
|
mWeightMat = model.getWeightMat().clone();
|
|
|
|
mInSideBaseImg = model.getInsideBaseImg().clone();
|
|
|
|
|
|
|
|
mInsideWeightMat = model.getInsideWeightImg().clone();
|
|
|
|
|
|
|
|
mMatchValScale = model.getMatchValScale();
|
|
|
|
mMatchValScale = model.getMatchValScale();
|
|
|
|
mTargetMeanVal = model.getTargetMeanVal();
|
|
|
|
mTargetMeanVal = model.getTargetMeanVal();
|
|
|
|
mTargetStddevVal = model.getTargetStddevVal();
|
|
|
|
mTargetStddevVal = model.getTargetStddevVal();
|
|
|
|
@ -170,68 +157,61 @@ public:
|
|
|
|
mTrueSampleDisMax = model.getDisMax();
|
|
|
|
mTrueSampleDisMax = model.getDisMax();
|
|
|
|
mTrueSampleDisMin = model.getDisMin();
|
|
|
|
mTrueSampleDisMin = model.getDisMin();
|
|
|
|
meanDiameter = model.getMeanDiamter();
|
|
|
|
meanDiameter = model.getMeanDiamter();
|
|
|
|
rInner = model.getInnerR();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void genMask();
|
|
|
|
void genMask();
|
|
|
|
void genOutterMask();
|
|
|
|
|
|
|
|
void preProcessImage(Mat& img, Mat &insideImg) const;
|
|
|
|
void preProcessImage(Mat& img) const;
|
|
|
|
void preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold) const;
|
|
|
|
void preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold) const;
|
|
|
|
void preProcessImage(Mat& img, const Mat& mask, const Mat& weightMat, double dstMean,
|
|
|
|
void preProcessImage(Mat& img, const Mat& mask, const Mat& weightMat, double dstMean,
|
|
|
|
double dstStddev, int highlightsThreshold) const;
|
|
|
|
double dstStddev, int highlightsThreshold) const;
|
|
|
|
void preProcessImage0(Mat& img) const;
|
|
|
|
void preProcessImage0(Mat& img) const;
|
|
|
|
void weightOptimization(const vector<Mat>& falseSamples);
|
|
|
|
void weightOptimization(const vector<Mat>& falseSamples);
|
|
|
|
//! 将一个图像和标准图mBaseImg进行旋转匹配,再相减求得差异值
|
|
|
|
//! 将一个图像和标准图mBaseImg进行旋转匹配,再相减求得差异值
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\param Mat img 输入图像
|
|
|
|
\param Mat img 输入图像
|
|
|
|
\param Mat * pRImg 输入图像的旋转匹配结果
|
|
|
|
\param Mat * pRImg 输入图像的旋转匹配结果
|
|
|
|
\param bool isFilterSize 是否根据图像尺寸过滤
|
|
|
|
\param bool isFilterSize 是否根据图像尺寸过滤
|
|
|
|
\return double 差异值
|
|
|
|
\return double 差异值
|
|
|
|
\see compare(Mat, Mat, Mat*, Mat*)
|
|
|
|
\see compare(Mat, Mat, Mat*, Mat*)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
double compare(Mat srcImage, Mat* pRImg = NULL, int levelNum = 1, bool isFilterSize = true, int flag = 0,
|
|
|
|
double compare(Mat img, Mat* pRImg = NULL, int levelNum = 1, bool isFilterSize = true, int flag = 0,
|
|
|
|
double md_diameter = 0, double md_height = 0);
|
|
|
|
double md_diameter = 0, double md_height = 0);
|
|
|
|
|
|
|
|
|
|
|
|
//! 训练得到标准图像mBaseImg
|
|
|
|
//! 训练得到标准图像mBaseImg
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\param const vector<Mat> & imgVec 属于同类的训练样本图
|
|
|
|
\param const vector<Mat> & imgVec 属于同类的训练样本图
|
|
|
|
\return void
|
|
|
|
\return void
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void train(const vector<Mat>& vec);
|
|
|
|
void train(const vector<Mat>& imgVec);
|
|
|
|
void calculateAllParams(const vector<Mat>& imgVec);
|
|
|
|
void calculateAllParams(const vector<Mat>& imgVec);
|
|
|
|
void trueSampleWeightRecon(const vector<Mat>& resizedVec, const vector<Mat>& resizedCenterVec, vector<RotateMatchResult> rmrVec,
|
|
|
|
void trueSampleWeightRecon(const vector<Mat>& resizedVec, vector<RotateMatchResult> rmrVec);
|
|
|
|
vector<RotateMatchResult> rmrVecInside);
|
|
|
|
void trueWeightRecon(const Mat& rImg, const Mat& baseImg);
|
|
|
|
void trueWeightRecon(const Mat& rImg, const Mat& baseImg, const Mat& insideRimg, const Mat& insideBaseImg);
|
|
|
|
void weightMapping(const Mat& weight, double maxVal);
|
|
|
|
void weightMapping(const Mat& weight, double maxVal, const Mat& i_mData, double i_maxVal);
|
|
|
|
|
|
|
|
//void falseWeightmapping(Mat &img);
|
|
|
|
//void falseWeightmapping(Mat &img);
|
|
|
|
double descendFunction(double pixVal, double maxVal);
|
|
|
|
double descendFunction(double pixVal, double maxVal);
|
|
|
|
double penltyCoeff(double matchedVal, int diameterMean, int targetDiameterm, double modelDiamter, double modelHeight) const;
|
|
|
|
double penltyCoeff(double matchedVal, int diameterMean, int targetDiameterm, double modelDiamter, double modelHeight) const;
|
|
|
|
//! 根据负样本计算差异阈值,用于判断任意一个新的图像是否属于该类别。
|
|
|
|
//! 根据负样本计算差异阈值,用于判断任意一个新的图像是否属于该类别。
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\param const vector<Mat> & imgVec 不属于该类的训练样本图
|
|
|
|
\param const vector<Mat> & imgVec 不属于该类的训练样本图
|
|
|
|
\return void
|
|
|
|
\return void
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void computeDisThre(const vector<Mat>& imgVec, double* pMinDis = NULL, double md_diameter = 0, double md_height = 0);
|
|
|
|
void computeDisThre(const vector<Mat>& imgVec, double* pMinDis = NULL, double md_diameter = 0, double md_height = 0);
|
|
|
|
|
|
|
|
|
|
|
|
double filterTrainImage(const Mat &img);
|
|
|
|
double filterTrainImage(const Mat &img);
|
|
|
|
|
|
|
|
|
|
|
|
//! 并行计算rotate
|
|
|
|
//! 并行计算rotate
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\param int index 当前并行index
|
|
|
|
\param int index 当前并行index
|
|
|
|
\param void *p 数据指针
|
|
|
|
\param void *p 数据指针
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void parallelDetect(int index, void *p) const;
|
|
|
|
void parallelDetect(int index, void *p) const;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//! 获取标准图像
|
|
|
|
//! 获取标准图像
|
|
|
|
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\return cv::Mat 标准图像
|
|
|
|
\return cv::Mat 标准图像
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
Mat getInsideBaseImg() const{ return mInSideBaseImg; }
|
|
|
|
Mat getBaseImg() const { return mAlignBaseImg; }
|
|
|
|
Mat getInsideWeightImg() const{ return mInsideWeightMat; }
|
|
|
|
|
|
|
|
float getInnerR() const { return rInner; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual Mat getBaseImg() const { return mAlignBaseImg; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setBaseImg(const Mat& img) { mAlignBaseImg = img; }
|
|
|
|
void setBaseImg(const Mat& img) { mAlignBaseImg = img; }
|
|
|
|
|
|
|
|
|
|
|
|
@ -259,17 +239,17 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
double getFalseSampleMinDis() const { return mFalseSampleMinDis; }
|
|
|
|
double getFalseSampleMinDis() const { return mFalseSampleMinDis; }
|
|
|
|
double getMeanDiamter() const { return meanDiameter; }
|
|
|
|
double getMeanDiamter() const { return meanDiameter; }
|
|
|
|
//! 获取最近一次执行readFromFile时输入的文件路径
|
|
|
|
//! 获取最近一次执行readFromFile时输入的文件路径
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\return string 文件路径
|
|
|
|
\return string 文件路径
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
string getFilePath() const { return mFilePath; }
|
|
|
|
string getFilePath() const { return mFilePath; }
|
|
|
|
|
|
|
|
|
|
|
|
double getDisThre() const { return mDisThre; }
|
|
|
|
double getDisThre() const { return mDisThre; }
|
|
|
|
void setDisThre(double val) { mDisThre = val; }
|
|
|
|
void setDisThre(double val) { mDisThre = val; }
|
|
|
|
|
|
|
|
|
|
|
|
//! 启用缓存。缓存会将每次调用compare接口输入的img参数的data指针作为key存储
|
|
|
|
//! 启用缓存。缓存会将每次调用compare接口输入的img参数的data指针作为key存储
|
|
|
|
// 差异值。
|
|
|
|
// 差异值。
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\return void
|
|
|
|
\return void
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
@ -300,16 +280,16 @@ public:
|
|
|
|
void setRealHeight(int val){ realHeight = val; }
|
|
|
|
void setRealHeight(int val){ realHeight = val; }
|
|
|
|
int getRealWidth(){ return realWidth; }
|
|
|
|
int getRealWidth(){ return realWidth; }
|
|
|
|
int getRealHeight(){ return realHeight; }
|
|
|
|
int getRealHeight(){ return realHeight; }
|
|
|
|
void printLog(string root, string log, double n = 0) const;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
protected:
|
|
|
|
//! (尚未完成)将两个图像分别和标准图mBaseImg进行旋转匹配,再相减求得差异值
|
|
|
|
//! (尚未完成)将两个图像分别和标准图mBaseImg进行旋转匹配,再相减求得差异值
|
|
|
|
/*!
|
|
|
|
/*!
|
|
|
|
\param Mat img0 待比较的图像img0
|
|
|
|
\param Mat img0 待比较的图像img0
|
|
|
|
\param Mat img1 带比较的图像img1
|
|
|
|
\param Mat img1 带比较的图像img1
|
|
|
|
\param Mat * pRImg0 将img0和标准图mBaseImg旋转匹配的结果rimg0
|
|
|
|
\param Mat * pRImg0 将img0和标准图mBaseImg旋转匹配的结果rimg0
|
|
|
|
\param Mat * pRImg1 将img1和标准图mBaseImg旋转匹配的结果rimg1
|
|
|
|
\param Mat * pRImg1 将img1和标准图mBaseImg旋转匹配的结果rimg1
|
|
|
|
\return double 差异值,取值大小为mMatchValScale*norm(rimg0 - rimg1)/(cols*rows)
|
|
|
|
\return double 差异值,取值大小为mMatchValScale*norm(rimg0 - rimg1)/(cols*rows)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
double compare(Mat img0, Mat img1, Mat* pRImg0 = NULL, Mat* pRImg1 = NULL);
|
|
|
|
double compare(Mat img0, Mat img1, Mat* pRImg0 = NULL, Mat* pRImg1 = NULL);
|
|
|
|
|
|
|
|
|
|
|
|
@ -333,24 +313,16 @@ protected:
|
|
|
|
Mat mDisMat;
|
|
|
|
Mat mDisMat;
|
|
|
|
Mat reConMat;
|
|
|
|
Mat reConMat;
|
|
|
|
Mat falseReConMat;
|
|
|
|
Mat falseReConMat;
|
|
|
|
Mat insideWeightRecon;
|
|
|
|
double mDisThre;
|
|
|
|
Mat innerTempl;
|
|
|
|
|
|
|
|
double mDisThre{ DBL_MAX };
|
|
|
|
|
|
|
|
string mName;
|
|
|
|
string mName;
|
|
|
|
double falseMinDis;
|
|
|
|
double falseMinDis;
|
|
|
|
int meanDiameter;
|
|
|
|
int meanDiameter;
|
|
|
|
int realWidth;
|
|
|
|
int realWidth;
|
|
|
|
int realHeight;
|
|
|
|
int realHeight;
|
|
|
|
// INSIDE PART
|
|
|
|
|
|
|
|
Mat mInSideBaseImg, mInsideCompareBaseImg;
|
|
|
|
|
|
|
|
Mat mInsideWeightMat;
|
|
|
|
|
|
|
|
Mat m32fInsideMaskImg, m8uInsideMaskImg;
|
|
|
|
|
|
|
|
float rInner;
|
|
|
|
|
|
|
|
float x_aix;
|
|
|
|
|
|
|
|
float y_aix;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// some training data
|
|
|
|
// some training data
|
|
|
|
double mTrueSampleDisStddev, mTrueSampleDisMean, mTrueSampleDisMax{DBL_MAX}, mTrueSampleDisMin;
|
|
|
|
double mTrueSampleDisStddev, mTrueSampleDisMean, mTrueSampleDisMax, mTrueSampleDisMin;
|
|
|
|
double mFalseSampleMinDis;
|
|
|
|
double mFalseSampleMinDis;
|
|
|
|
|
|
|
|
|
|
|
|
// temp data
|
|
|
|
// temp data
|
|
|
|
@ -361,8 +333,6 @@ protected:
|
|
|
|
// cache
|
|
|
|
// cache
|
|
|
|
bool mIsEnableCache;
|
|
|
|
bool mIsEnableCache;
|
|
|
|
map<uchar*, double> mDisCache;
|
|
|
|
map<uchar*, double> mDisCache;
|
|
|
|
public:
|
|
|
|
|
|
|
|
static int m_parallelFlag;
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|