/**
 * 新来车检测算法
 * */

#ifndef TRAINANAENGINE_H
#define TRAINANAENGINE_H

#include <algorithm>
#include "AppCommon.h"
#include "MyYaml.h"
#include "myutils.h"
#include "EngineBase.h"
#include "EngineFactory.h"
#include "math.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

using namespace cv;
using namespace std;

typedef void* LPVOID;

class TrainAnaEngine : public ai_matrix::EngineBase
{
public:
    TrainAnaEngine();
    ~TrainAnaEngine();

    APP_ERROR Init() override;
    APP_ERROR DeInit() override;
    APP_ERROR Process() override;

private:

    //////////////////////////////变量部分//////////////////////////////////////////
    //engine变量
    std::string strPort0_;
    std::string strPort1_;
    ai_matrix::DataSourceConfig dataSourceConfig_;
    std::string strResultPath_;
    std::string strResultPath_for_test;
    std::string strTrainData_;
    std::string strTrainName_;

    //划分算法参数和算法计算的实况数值
    std::vector<AnalyseInfo> lstAction;             //行车检测算法基准参数集
    std::vector<AnalyseInfo> lstPartion;            //车厢划分算法基准参数集
    std::vector<PartionInfo> lstPartInfo;           //当前车次车厢划分结果
    
    int nRightComeFlagR1;                           //最右侧检测区域状态变化的数值
    int nRightComeFlagR2;                           //次右侧检测区域状态变化的数值
    int nRightComeFlagR3;                           //第三右侧检测区域状态变化的数值
    
    //动态数据
    int nStatus;                                    //车辆状态
    int nPreStatus;                                 //上一帧车辆状态
    int nPicAreaChangeing;                          //图片区域变化状态(从左往右)
    int nPrePicAreaChangeing;                       //上一帧图片区域变化状态(从左往右)
    int nSamePartionIgnoreCount;                    //检测到车钩跳帧数
    int nPartionPassFrameCount;                     //检测到车钩后通过了多少帧
    int nTailPixOffset;                             //尾部车钩偏移位置
    float fdefaultspeed;                            //缺省行车速度
    cv::Mat cvFirstImg;                             //比对基准图
    uint64_t ncurtime;

    //图像相关
    long nLatestFrame;                              //目前为止最大帧数
    int nFrameRate;                                 //相机帧率
    unsigned int nRecIndex;                         //测试用记录索引

    //////////////////////////////函数部分//////////////////////////////////////////
    //基础函数
    void InitParam();                                                                           //参数初始化
    void checkAction(cv::Mat baseimg, uint64_t i64TimeStamp);                                   //行车检测
    bool checkPartion(cv::Mat baseimg, uint64_t i64TimeStamp);                                  //车厢划分检测

    //功能函数
    void vformatStructAnalyseInfo(std::vector<std::string> elems, AnalyseInfo &info);           //读取的csv文件内容格式化到结构体变量中
    void getsetting(string strFilePath);                                                        //读取的算法参数的csv文件
    double anapicbyHist(cv::Mat baseimg, cv::Mat tarpic, int method);                           //根据检测物形状进行比对
    double anapicbyTemple(cv::Mat baseimg, cv::Mat tarpic, int method, cv::Point &pPos);        //根据直方图进行比对   
    double anapicbySpec(cv::Mat baseimg);                                                
    void vResetPartion();                                                                       //重置车厢划分信息
    int getOffsetFrame(float fspeed, int nFrameRate, int width);                                //根据车钩位置计算帧数
    int getCouplerOffsetPosition(float fspeed, int nframeindex);                                //计算车钩在图片的x坐标(预测的计算值非实际值)
    int getTailPixOffset();									                                    //计算尾部车钩在图片的x坐标(预测的计算值非实际值)
    float GetPointMaxReduceMin(float dComparePoint,int index);                                             //获取最近100帧的dComparePoint的最大值与最小值之差
    //图像处理函数
    cv::Mat mtdecodeImageDatabyFile(string path);                                               //读取图像文件并转化为Mat格式               
    cv::Mat mtdecodeImageDatabyBin(LPVOID lpimgdata, int imglen);                               //将图像二进制数据转化为Mat格式
    cv::Mat mtImproveImage(cv::Mat inImage, AnalyseInfo info, bool bcvread);                    //图像优化 根据配置进行灰度/直方图均衡/gamma变化/自定义优化
    cv::Mat mtresizeImage(cv::Mat inImage, int width, int height);                              //调整车厢图像尺寸为固定尺寸
    cv::Mat mtareaImage(cv::Mat inImage, int x1, int y1, int x2, int y2);                       //从图像获取敏感位置图像数据
    cv::Mat mtgrayImage(cv::Mat inImage, int mode);                                             //图像灰度化
    cv::Mat mtequalizeImage(cv::Mat inImage);                                                   //图像直方图均衡化
    cv::Mat mtGammaImage(cv::Mat inImage, float fgamma);                                        //图像gamma变换
    cv::Mat mtspecImage(cv::Mat inImage);                                                       //图像自定义优化
    std::vector<double >getCompPoint(AnalyseInfo info, cv::Mat baseimg, cv::Mat tarpic);        //获取图像比对值


};

ENGINE_REGIST(TrainAnaEngine)

#endif
