Compare commits
10 Commits
b57ad52a0d
...
04dd7d3816
| Author | SHA1 | Date |
|---|---|---|
|
|
04dd7d3816 | 3 months ago |
|
|
af8d1a1b43 | 3 months ago |
|
|
ee96b4191c | 3 months ago |
|
|
3bfe9ffb6f | 4 months ago |
|
|
cfcdaca5c0 | 4 months ago |
|
|
b34cb5c246 | 4 months ago |
|
|
8309131e41 | 4 months ago |
|
|
cfb3caad1a | 4 months ago |
|
|
65a2e8b7f6 | 4 months ago |
|
|
f6a3bede36 | 4 months ago |
@ -0,0 +1,128 @@
|
||||
// NV12 对地跟踪性能测试
|
||||
#include "NeoArithStandardDll.h"
|
||||
#include "utils.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "TestAPI_Profile.h"
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
#define Test_Len 1000
|
||||
|
||||
int TestAPI_SOT_Ground_NV12()
|
||||
{
|
||||
// 产生一个仿真Y16数据
|
||||
int nWidth = 1920;
|
||||
int nHeight = 1080;
|
||||
SimTargetImage factory(nWidth, nHeight);
|
||||
|
||||
factory.setBackGround(128, 10);
|
||||
// 叠加一个初始目标
|
||||
Target t;
|
||||
t.x = 100;
|
||||
t.y = 100;
|
||||
t.width = 30;
|
||||
t.height = 30;
|
||||
t.vw = 0;
|
||||
t.vh = 0;
|
||||
t.vx = 1;
|
||||
t.vy = 1;
|
||||
t.addTexture(cow_png,cow_png_len);
|
||||
factory.addTarget(t);
|
||||
//
|
||||
|
||||
t.x = 300;
|
||||
t.y = 250;
|
||||
t.width = 100;
|
||||
t.height = 100;
|
||||
t.vw = 0;
|
||||
t.vh = 0;
|
||||
t.vx = 0;
|
||||
t.vy = 0;
|
||||
t.color = cv::Scalar(20,20,20);
|
||||
factory.addOcc(t);
|
||||
|
||||
|
||||
// 创建算法句柄
|
||||
ArithHandle pTracker = STD_CreatEOArithHandle();
|
||||
|
||||
// 初始化为凝视-对地模式
|
||||
ARIDLL_EOArithInitWithMode(pTracker,nWidth,nHeight,GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_NV12,
|
||||
GLB_SYS_MODE::GLB_SYS_STARE,GLB_SCEN_MODE::GLB_SCEN_GROUND);
|
||||
|
||||
// 算法输入部分
|
||||
ARIDLL_INPUTPARA stInputPara = { 0 };
|
||||
stInputPara.unFrmId++;
|
||||
stInputPara.stCameraInfo.fPixelSize = 15;
|
||||
stInputPara.stCameraInfo.nFocus = 300;
|
||||
|
||||
// 算法输出部分
|
||||
ARIDLL_OUTPUT stOutput = { 0 };
|
||||
|
||||
|
||||
// 模拟算法执行流程
|
||||
int nTrackSuc = 0;
|
||||
cv::Mat frame;
|
||||
for(int i = 0; i < Test_Len; i++)
|
||||
{
|
||||
stInputPara.unFrmId++;
|
||||
|
||||
factory.update();
|
||||
cv::Mat src = factory.getImageNV12();
|
||||
Target* gt = factory.getTarget(0);
|
||||
|
||||
// 构建图像类型
|
||||
GD_VIDEO_FRAME_S img = { 0 };
|
||||
img.enPixelFormat = GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_NV12;
|
||||
img.u32Width = nWidth;
|
||||
img.u32Height = nHeight;
|
||||
img.u32Stride[0] = img.u32Width * 1;
|
||||
img.u64VirAddr[0] = (unsigned char*)src.data;
|
||||
|
||||
// 下发面锁定指令
|
||||
if (stInputPara.unFrmId == 3)
|
||||
{
|
||||
//ARIDLL_LockCommand(pTracker, gt->x,gt->y,gt->width,gt->height);
|
||||
ARIDLL_LockCommand(pTracker, gt->x, gt->y, gt->width, gt->height);
|
||||
}
|
||||
|
||||
|
||||
cv::TickMeter tm;
|
||||
tm.start();
|
||||
|
||||
// 运行算法主控逻辑API
|
||||
ARIDLL_RunController(pTracker, img, stInputPara, &stOutput);
|
||||
|
||||
tm.stop();
|
||||
|
||||
printf("time:%.2f\n",tm.getTimeMilli());
|
||||
|
||||
#ifdef SHOW
|
||||
// 绘制跟踪结果
|
||||
cv::Mat rgb = factory.getImageRGB();
|
||||
showArithInfo(rgb,&stOutput);
|
||||
imshow("res",rgb);
|
||||
cv::waitKey(1);
|
||||
#endif
|
||||
|
||||
if (stOutput.nStatus == GLB_STATUS_TRACK && stOutput.nTrackObjCnts == 1)
|
||||
{
|
||||
if (abs(stOutput.stTrackers[0].nX - gt->x) < 5 &&
|
||||
abs(stOutput.stTrackers[0].nY - gt->y) < 5)
|
||||
{
|
||||
nTrackSuc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("Suc:%d/A:%d\n",nTrackSuc,Test_Len);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
// 暴力锁定解锁鲁棒性测试
|
||||
#include "NeoArithStandardDll.h"
|
||||
#include "utils.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "TestAPI_Profile.h"
|
||||
#include <random>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int TestAPI_SOT_LockUnlock_Stress()
|
||||
{
|
||||
// 产生一个仿真数据
|
||||
int nWidth = 1920;
|
||||
int nHeight = 1080;
|
||||
|
||||
const int Test_Len = 100000;
|
||||
|
||||
// 初始化随机数生成器
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> offsetDist(-2000, 2000); // 在目标周围±5像素范围内随机
|
||||
|
||||
SimTargetImage factory(nWidth, nHeight);
|
||||
factory.setCheckerboardBackGround(120, 0, 80);
|
||||
|
||||
// 创建算法句柄
|
||||
ArithHandle pTracker = STD_CreatEOArithHandle();
|
||||
|
||||
// 初始化为凝视-对空模式
|
||||
ARIDLL_EOArithInitWithMode(pTracker, nWidth, nHeight, GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_NV12,
|
||||
GLB_SYS_MODE::GLB_SYS_STARE, GLB_SCEN_MODE::GLB_SCEN_GROUND);
|
||||
|
||||
ARIDLL_INPUTPARA stInputPara = { 0 };
|
||||
stInputPara.unFrmId++;
|
||||
stInputPara.unFreq = 50;
|
||||
stInputPara.stCameraInfo.fPixelSize = 15;
|
||||
stInputPara.stCameraInfo.nFocus = 300;
|
||||
stInputPara.stCameraInfo.unVideoType = GLB_VIDEO_IR_MW;
|
||||
ARIDLL_OUTPUT stOutput = { 0 };
|
||||
|
||||
// 生成随机锁定解锁序列
|
||||
std::vector<int> lockUnlockSequence = generateRandomLockUnlockSequence(Test_Len);
|
||||
|
||||
int nTrackSuc = 0;
|
||||
int nLock = 0, nUnlock = 0, nLost = 0;
|
||||
bool locked = false;
|
||||
|
||||
for (int i = 0; i < Test_Len; i++)
|
||||
{
|
||||
stInputPara.unFrmId++;
|
||||
factory.update();
|
||||
cv::Mat src = factory.getImageNV12();
|
||||
|
||||
GD_VIDEO_FRAME_S img = { 0 };
|
||||
img.enPixelFormat = GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_NV12;
|
||||
img.u32Width = nWidth;
|
||||
img.u32Height = nHeight;
|
||||
img.u32Stride[0] = img.u32Width;
|
||||
img.u64VirAddr[0] = (UBYTE8*)src.data;
|
||||
|
||||
int targetNum = 0;
|
||||
cv::TickMeter tm1;
|
||||
tm1.start();
|
||||
{
|
||||
//targetNum = ARIDLL_SearchFrameTargets(pTracker, img);
|
||||
}
|
||||
tm1.stop();
|
||||
printf("det time:%.2f", tm1.getTimeMilli());
|
||||
|
||||
// 根据序列执行锁定/解锁操作
|
||||
switch (lockUnlockSequence[i])
|
||||
{
|
||||
case 1: // 锁定
|
||||
{
|
||||
// 在目标周围随机选择锁定位置
|
||||
int offsetX = offsetDist(gen);
|
||||
int offsetY = offsetDist(gen);
|
||||
//ARIDLL_LockCommand_DefaultSize(pTracker, (int)nWidth / 2 + offsetX, (int)nHeight / 2 + offsetY, 30, 30);
|
||||
//ARIDLL_LockTarget_DefaultSize(pTracker, img,(int)nWidth / 2 + offsetX, (int)nHeight / 2 + offsetY, 30, 30);
|
||||
locked = true;
|
||||
nLock++;
|
||||
}
|
||||
break;
|
||||
case 2: // 解锁
|
||||
ARIDLL_unLockCommand(pTracker);
|
||||
locked = false;
|
||||
nUnlock++;
|
||||
break;
|
||||
default: // 普通帧
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
cv::TickMeter tm2;
|
||||
tm2.start();
|
||||
ARIDLL_RunController(pTracker, img, stInputPara, &stOutput);
|
||||
tm2.stop();
|
||||
printf(" trk time:%.2f\n", tm2.getTimeMilli());
|
||||
|
||||
#ifdef SHOW
|
||||
cv::Mat rgb = factory.getImageRGB();
|
||||
showArithInfo(rgb, &stOutput);
|
||||
imshow("res", rgb);
|
||||
cv::waitKey(1);
|
||||
#endif
|
||||
printf("nStatus:%d,Proc:%d", stOutput.nStatus,stInputPara.unFrmId);
|
||||
}
|
||||
|
||||
// 输出测试统计结果
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
#include "cmdline.h"//命令行解析
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <iostream>
|
||||
#include "image_data.h"
|
||||
#include "TestAPI_Profile.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
TestAPI_SOT_Sky_Y16();
|
||||
return 0;
|
||||
// 映射表
|
||||
std::unordered_map<std::string, std::function<void()>> handlerMap = {
|
||||
{"sky:Y16", TestAPI_SOT_Sky_Y16},
|
||||
{"ground:Y8", TestAPI_SOT_Ground_Y8},
|
||||
{"ground:RGB", TestAPI_SOT_Ground_RGB},
|
||||
{"ground:Y16", TestAPI_SOT_Ground_Y16},
|
||||
{"ground:NV12", TestAPI_SOT_Ground_NV12},
|
||||
{"ground:NV12:LOCK_STRESS", TestAPI_SOT_LockUnlock_Stress},
|
||||
};
|
||||
|
||||
cmdline::parser a;
|
||||
a.add<string>("scen",'s',"sky or ground",true,"");
|
||||
a.add<string>("dataType",'d',"Y8/Y16/RGB/NV12",true,"");
|
||||
a.add<string>("testItem",'t',"other item",false,"");
|
||||
a.parse_check(argc, argv);
|
||||
|
||||
cout << "scen:" << a.get<string>("scen")
|
||||
<< "datatype:" << a.get<string>("dataType") << endl;
|
||||
cout << "------------------ " << endl;
|
||||
|
||||
|
||||
std::string scen = a.get<std::string>("scen");
|
||||
std::string dataType = a.get<std::string>("dataType");
|
||||
std::string testItem = a.get<std::string>("testItem");
|
||||
|
||||
std::string key;
|
||||
if (!testItem.empty()) {
|
||||
key = scen + ":" + dataType + ":" + testItem;
|
||||
} else {
|
||||
key = scen + ":" + dataType;
|
||||
}
|
||||
|
||||
// 查找并执行逻辑
|
||||
if (handlerMap.find(key) != handlerMap.end()) {
|
||||
handlerMap[key]();
|
||||
} else {
|
||||
std::cout << "Invalid combination of scen and dataType: " << key << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
#include "utils.h"
|
||||
|
||||
#define SHOW
|
||||
|
||||
extern unsigned char cow_png[];
|
||||
extern unsigned int cow_png_len;
|
||||
|
||||
int TestAPI_SOT_Ground_NV12();
|
||||
int TestAPI_SOT_Ground_RGB();
|
||||
int TestAPI_SOT_Ground_Y8();
|
||||
int TestAPI_SOT_Ground_Y16();
|
||||
int TestAPI_SOT_Sky_Y16();
|
||||
int TestAPI_SOT_LockUnlock_Stress();
|
||||
@ -0,0 +1,821 @@
|
||||
/*
|
||||
Copyright (c) 2009, Hideyuki Tanaka
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#ifdef __GNUC__
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
#include <cstdlib>
|
||||
|
||||
namespace cmdline{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <typename Target, typename Source, bool Same>
|
||||
class lexical_cast_t{
|
||||
public:
|
||||
static Target cast(const Source &arg){
|
||||
Target ret;
|
||||
std::stringstream ss;
|
||||
if (!(ss<<arg && ss>>ret && ss.eof()))
|
||||
throw std::bad_cast();
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Target, typename Source>
|
||||
class lexical_cast_t<Target, Source, true>{
|
||||
public:
|
||||
static Target cast(const Source &arg){
|
||||
return arg;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Source>
|
||||
class lexical_cast_t<std::string, Source, false>{
|
||||
public:
|
||||
static std::string cast(const Source &arg){
|
||||
std::ostringstream ss;
|
||||
ss<<arg;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Target>
|
||||
class lexical_cast_t<Target, std::string, false>{
|
||||
public:
|
||||
static Target cast(const std::string &arg){
|
||||
Target ret;
|
||||
std::istringstream ss(arg);
|
||||
if (!(ss>>ret && ss.eof()))
|
||||
throw std::bad_cast();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct is_same {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_same<T, T>{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<typename Target, typename Source>
|
||||
Target lexical_cast(const Source &arg)
|
||||
{
|
||||
return lexical_cast_t<Target, Source, detail::is_same<Target, Source>::value>::cast(arg);
|
||||
}
|
||||
|
||||
static inline std::string demangle(const std::string &name)
|
||||
{
|
||||
|
||||
#ifdef _MSC_VER
|
||||
return name; // 为MSVC编译器时直接返回name
|
||||
#elif defined(__GNUC__)
|
||||
// 为gcc编译器时还调用原来的代码
|
||||
int status = 0;
|
||||
char* p = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
|
||||
std::string ret(p);
|
||||
free(p);
|
||||
return ret;
|
||||
#else
|
||||
// 其他不支持的编译器需要自己实现这个方法
|
||||
#error unexpected c complier (msc/gcc), Need to implement this method for demangle
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string readable_typename()
|
||||
{
|
||||
return demangle(typeid(T).name());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string default_value(T def)
|
||||
{
|
||||
return detail::lexical_cast<std::string>(def);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string readable_typename<std::string>()
|
||||
{
|
||||
return "string";
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
//-----
|
||||
|
||||
class cmdline_error : public std::exception {
|
||||
public:
|
||||
cmdline_error(const std::string &msg): msg(msg){}
|
||||
~cmdline_error() throw() {}
|
||||
const char *what() const throw() { return msg.c_str(); }
|
||||
private:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct default_reader{
|
||||
T operator()(const std::string &str){
|
||||
return detail::lexical_cast<T>(str);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_reader{
|
||||
range_reader(const T &low, const T &high): low(low), high(high) {}
|
||||
T operator()(const std::string &s) const {
|
||||
T ret=default_reader<T>()(s);
|
||||
if (!(ret>=low && ret<=high)) throw cmdline::cmdline_error("range_error");
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
T low, high;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
range_reader<T> range(const T &low, const T &high)
|
||||
{
|
||||
return range_reader<T>(low, high);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct oneof_reader{
|
||||
T operator()(const std::string &s){
|
||||
T ret=default_reader<T>()(s);
|
||||
if (std::find(alt.begin(), alt.end(), ret)==alt.end())
|
||||
throw cmdline_error("");
|
||||
return ret;
|
||||
}
|
||||
void add(const T &v){ alt.push_back(v); }
|
||||
private:
|
||||
std::vector<T> alt;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
ret.add(a5);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
ret.add(a5);
|
||||
ret.add(a6);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
ret.add(a5);
|
||||
ret.add(a6);
|
||||
ret.add(a7);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
ret.add(a5);
|
||||
ret.add(a6);
|
||||
ret.add(a7);
|
||||
ret.add(a8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
ret.add(a5);
|
||||
ret.add(a6);
|
||||
ret.add(a7);
|
||||
ret.add(a8);
|
||||
ret.add(a9);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10)
|
||||
{
|
||||
oneof_reader<T> ret;
|
||||
ret.add(a1);
|
||||
ret.add(a2);
|
||||
ret.add(a3);
|
||||
ret.add(a4);
|
||||
ret.add(a5);
|
||||
ret.add(a6);
|
||||
ret.add(a7);
|
||||
ret.add(a8);
|
||||
ret.add(a9);
|
||||
ret.add(a10);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----
|
||||
|
||||
class parser{
|
||||
public:
|
||||
parser(){
|
||||
}
|
||||
~parser(){
|
||||
for (std::map<std::string, option_base*>::iterator p=options.begin();
|
||||
p!=options.end(); p++)
|
||||
delete p->second;
|
||||
}
|
||||
|
||||
void add(const std::string &name,
|
||||
char short_name=0,
|
||||
const std::string &desc=""){
|
||||
if (options.count(name)) throw cmdline_error("multiple definition: "+name);
|
||||
options[name]=new option_without_value(name, short_name, desc);
|
||||
ordered.push_back(options[name]);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void add(const std::string &name,
|
||||
char short_name=0,
|
||||
const std::string &desc="",
|
||||
bool need=true,
|
||||
const T def=T()){
|
||||
add(name, short_name, desc, need, def, default_reader<T>());
|
||||
}
|
||||
|
||||
template <class T, class F>
|
||||
void add(const std::string &name,
|
||||
char short_name=0,
|
||||
const std::string &desc="",
|
||||
bool need=true,
|
||||
const T def=T(),
|
||||
F reader=F()){
|
||||
if (options.count(name)) throw cmdline_error("multiple definition: "+name);
|
||||
options[name]=new option_with_value_with_reader<T, F>(name, short_name, need, def, desc, reader);
|
||||
ordered.push_back(options[name]);
|
||||
}
|
||||
|
||||
void footer(const std::string &f){
|
||||
ftr=f;
|
||||
}
|
||||
|
||||
void set_program_name(const std::string &name){
|
||||
prog_name=name;
|
||||
}
|
||||
|
||||
bool exist(const std::string &name) const {
|
||||
if (options.count(name)==0) throw cmdline_error("there is no flag: --"+name);
|
||||
return options.find(name)->second->has_set();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T &get(const std::string &name) const {
|
||||
if (options.count(name)==0) throw cmdline_error("there is no flag: --"+name);
|
||||
const option_with_value<T> *p=dynamic_cast<const option_with_value<T>*>(options.find(name)->second);
|
||||
if (p==NULL) throw cmdline_error("type mismatch flag '"+name+"'");
|
||||
return p->get();
|
||||
}
|
||||
|
||||
const std::vector<std::string> &rest() const {
|
||||
return others;
|
||||
}
|
||||
|
||||
bool parse(const std::string &arg){
|
||||
std::vector<std::string> args;
|
||||
|
||||
std::string buf;
|
||||
bool in_quote=false;
|
||||
for (std::string::size_type i=0; i<arg.length(); i++){
|
||||
if (arg[i]=='\"'){
|
||||
in_quote=!in_quote;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg[i]==' ' && !in_quote){
|
||||
args.push_back(buf);
|
||||
buf="";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg[i]=='\\'){
|
||||
i++;
|
||||
if (i>=arg.length()){
|
||||
errors.push_back("unexpected occurrence of '\\' at end of string");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
buf+=arg[i];
|
||||
}
|
||||
|
||||
if (in_quote){
|
||||
errors.push_back("quote is not closed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf.length()>0)
|
||||
args.push_back(buf);
|
||||
|
||||
for (size_t i=0; i<args.size(); i++)
|
||||
std::cout<<"\""<<args[i]<<"\""<<std::endl;
|
||||
|
||||
return parse(args);
|
||||
}
|
||||
|
||||
bool parse(const std::vector<std::string> &args){
|
||||
int argc=static_cast<int>(args.size());
|
||||
std::vector<const char*> argv(argc);
|
||||
|
||||
for (int i=0; i<argc; i++)
|
||||
argv[i]=args[i].c_str();
|
||||
|
||||
return parse(argc, &argv[0]);
|
||||
}
|
||||
|
||||
bool parse(int argc, const char * const argv[]){
|
||||
errors.clear();
|
||||
others.clear();
|
||||
|
||||
if (argc<1){
|
||||
errors.push_back("argument number must be longer than 0");
|
||||
return false;
|
||||
}
|
||||
if (prog_name=="")
|
||||
prog_name=argv[0];
|
||||
|
||||
std::map<char, std::string> lookup;
|
||||
for (std::map<std::string, option_base*>::iterator p=options.begin();
|
||||
p!=options.end(); p++){
|
||||
if (p->first.length()==0) continue;
|
||||
char initial=p->second->short_name();
|
||||
if (initial){
|
||||
if (lookup.count(initial)>0){
|
||||
lookup[initial]="";
|
||||
errors.push_back(std::string("short option '")+initial+"' is ambiguous");
|
||||
return false;
|
||||
}
|
||||
else lookup[initial]=p->first;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=1; i<argc; i++){
|
||||
if (strncmp(argv[i], "--", 2)==0){
|
||||
const char *p=strchr(argv[i]+2, '=');
|
||||
if (p){
|
||||
std::string name(argv[i]+2, p);
|
||||
std::string val(p+1);
|
||||
set_option(name, val);
|
||||
}
|
||||
else{
|
||||
std::string name(argv[i]+2);
|
||||
if (options.count(name)==0){
|
||||
errors.push_back("undefined option: --"+name);
|
||||
continue;
|
||||
}
|
||||
if (options[name]->has_value()){
|
||||
if (i+1>=argc){
|
||||
errors.push_back("option needs value: --"+name);
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
i++;
|
||||
set_option(name, argv[i]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
set_option(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[i], "-", 1)==0){
|
||||
if (!argv[i][1]) continue;
|
||||
char last=argv[i][1];
|
||||
for (int j=2; argv[i][j]; j++){
|
||||
last=argv[i][j];
|
||||
if (lookup.count(argv[i][j-1])==0){
|
||||
errors.push_back(std::string("undefined short option: -")+argv[i][j-1]);
|
||||
continue;
|
||||
}
|
||||
if (lookup[argv[i][j-1]]==""){
|
||||
errors.push_back(std::string("ambiguous short option: -")+argv[i][j-1]);
|
||||
continue;
|
||||
}
|
||||
set_option(lookup[argv[i][j-1]]);
|
||||
}
|
||||
|
||||
if (lookup.count(last)==0){
|
||||
errors.push_back(std::string("undefined short option: -")+last);
|
||||
continue;
|
||||
}
|
||||
if (lookup[last]==""){
|
||||
errors.push_back(std::string("ambiguous short option: -")+last);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i+1<argc && options[lookup[last]]->has_value()){
|
||||
set_option(lookup[last], argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
else{
|
||||
set_option(lookup[last]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
others.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<std::string, option_base*>::iterator p=options.begin();
|
||||
p!=options.end(); p++)
|
||||
if (!p->second->valid())
|
||||
errors.push_back("need option: --"+std::string(p->first));
|
||||
|
||||
return errors.size()==0;
|
||||
}
|
||||
|
||||
void parse_check(const std::string &arg){
|
||||
if (!options.count("help"))
|
||||
add("help", '?', "print this message");
|
||||
check(0, parse(arg));
|
||||
}
|
||||
|
||||
void parse_check(const std::vector<std::string> &args){
|
||||
if (!options.count("help"))
|
||||
add("help", '?', "print this message");
|
||||
check(args.size(), parse(args));
|
||||
}
|
||||
|
||||
void parse_check(int argc, char *argv[]){
|
||||
if (!options.count("help"))
|
||||
add("help", '?', "print this message");
|
||||
check(argc, parse(argc, argv));
|
||||
}
|
||||
|
||||
std::string error() const{
|
||||
return errors.size()>0?errors[0]:"";
|
||||
}
|
||||
|
||||
std::string error_full() const{
|
||||
std::ostringstream oss;
|
||||
for (size_t i=0; i<errors.size(); i++)
|
||||
oss<<errors[i]<<std::endl;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string usage() const {
|
||||
std::ostringstream oss;
|
||||
oss<<"usage: "<<prog_name<<" ";
|
||||
for (size_t i=0; i<ordered.size(); i++){
|
||||
if (ordered[i]->must())
|
||||
oss<<ordered[i]->short_description()<<" ";
|
||||
}
|
||||
|
||||
oss<<"[options] ... "<<ftr<<std::endl;
|
||||
oss<<"options:"<<std::endl;
|
||||
|
||||
size_t max_width=0;
|
||||
for (size_t i=0; i<ordered.size(); i++){
|
||||
max_width=std::max(max_width, ordered[i]->name().length());
|
||||
}
|
||||
for (size_t i=0; i<ordered.size(); i++){
|
||||
if (ordered[i]->short_name()){
|
||||
oss<<" -"<<ordered[i]->short_name()<<", ";
|
||||
}
|
||||
else{
|
||||
oss<<" ";
|
||||
}
|
||||
|
||||
oss<<"--"<<ordered[i]->name();
|
||||
for (size_t j=ordered[i]->name().length(); j<max_width+4; j++)
|
||||
oss<<' ';
|
||||
oss<<ordered[i]->description()<<std::endl;
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void check(int argc, bool ok){
|
||||
if ((argc==1 && !ok) || exist("help")){
|
||||
std::cerr<<usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!ok){
|
||||
std::cerr<<error()<<std::endl<<usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void set_option(const std::string &name){
|
||||
if (options.count(name)==0){
|
||||
errors.push_back("undefined option: --"+name);
|
||||
return;
|
||||
}
|
||||
if (!options[name]->set()){
|
||||
errors.push_back("option needs value: --"+name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void set_option(const std::string &name, const std::string &value){
|
||||
if (options.count(name)==0){
|
||||
errors.push_back("undefined option: --"+name);
|
||||
return;
|
||||
}
|
||||
if (!options[name]->set(value)){
|
||||
errors.push_back("option value is invalid: --"+name+"="+value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
class option_base{
|
||||
public:
|
||||
virtual ~option_base(){}
|
||||
|
||||
virtual bool has_value() const=0;
|
||||
virtual bool set()=0;
|
||||
virtual bool set(const std::string &value)=0;
|
||||
virtual bool has_set() const=0;
|
||||
virtual bool valid() const=0;
|
||||
virtual bool must() const=0;
|
||||
|
||||
virtual const std::string &name() const=0;
|
||||
virtual char short_name() const=0;
|
||||
virtual const std::string &description() const=0;
|
||||
virtual std::string short_description() const=0;
|
||||
};
|
||||
|
||||
class option_without_value : public option_base {
|
||||
public:
|
||||
option_without_value(const std::string &name,
|
||||
char short_name,
|
||||
const std::string &desc)
|
||||
:nam(name), snam(short_name), desc(desc), has(false){
|
||||
}
|
||||
~option_without_value(){}
|
||||
|
||||
bool has_value() const { return false; }
|
||||
|
||||
bool set(){
|
||||
has=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set(const std::string &){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool has_set() const {
|
||||
return has;
|
||||
}
|
||||
|
||||
bool valid() const{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool must() const{
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string &name() const{
|
||||
return nam;
|
||||
}
|
||||
|
||||
char short_name() const{
|
||||
return snam;
|
||||
}
|
||||
|
||||
const std::string &description() const {
|
||||
return desc;
|
||||
}
|
||||
|
||||
std::string short_description() const{
|
||||
return "--"+nam;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string nam;
|
||||
char snam;
|
||||
std::string desc;
|
||||
bool has;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class option_with_value : public option_base {
|
||||
public:
|
||||
option_with_value(const std::string &name,
|
||||
char short_name,
|
||||
bool need,
|
||||
const T &def,
|
||||
const std::string &desc)
|
||||
: nam(name), snam(short_name), need(need), has(false)
|
||||
, def(def), actual(def) {
|
||||
this->desc=full_description(desc);
|
||||
}
|
||||
~option_with_value(){}
|
||||
|
||||
const T &get() const {
|
||||
return actual;
|
||||
}
|
||||
|
||||
bool has_value() const { return true; }
|
||||
|
||||
bool set(){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set(const std::string &value){
|
||||
try{
|
||||
actual=read(value);
|
||||
has=true;
|
||||
}
|
||||
catch(const std::exception &e){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_set() const{
|
||||
return has;
|
||||
}
|
||||
|
||||
bool valid() const{
|
||||
if (need && !has) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool must() const{
|
||||
return need;
|
||||
}
|
||||
|
||||
const std::string &name() const{
|
||||
return nam;
|
||||
}
|
||||
|
||||
char short_name() const{
|
||||
return snam;
|
||||
}
|
||||
|
||||
const std::string &description() const {
|
||||
return desc;
|
||||
}
|
||||
|
||||
std::string short_description() const{
|
||||
return "--"+nam+"="+detail::readable_typename<T>();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string full_description(const std::string &desc){
|
||||
return
|
||||
desc+" ("+detail::readable_typename<T>()+
|
||||
(need?"":" [="+detail::default_value<T>(def)+"]")
|
||||
+")";
|
||||
}
|
||||
|
||||
virtual T read(const std::string &s)=0;
|
||||
|
||||
std::string nam;
|
||||
char snam;
|
||||
bool need;
|
||||
std::string desc;
|
||||
|
||||
bool has;
|
||||
T def;
|
||||
T actual;
|
||||
};
|
||||
|
||||
template <class T, class F>
|
||||
class option_with_value_with_reader : public option_with_value<T> {
|
||||
public:
|
||||
option_with_value_with_reader(const std::string &name,
|
||||
char short_name,
|
||||
bool need,
|
||||
const T def,
|
||||
const std::string &desc,
|
||||
F reader)
|
||||
: option_with_value<T>(name, short_name, need, def, desc), reader(reader){
|
||||
}
|
||||
|
||||
private:
|
||||
T read(const std::string &s){
|
||||
return reader(s);
|
||||
}
|
||||
|
||||
F reader;
|
||||
};
|
||||
|
||||
std::map<std::string, option_base*> options;
|
||||
std::vector<option_base*> ordered;
|
||||
std::string ftr;
|
||||
|
||||
std::string prog_name;
|
||||
std::vector<std::string> others;
|
||||
|
||||
std::vector<std::string> errors;
|
||||
};
|
||||
|
||||
} // cmdline
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
./TestAPI_Profile "-s" "sky" "-d" "Y16"
|
||||
@ -0,0 +1,75 @@
|
||||
#include "Arith_PosAnalyse.h"
|
||||
|
||||
ImagePosRecord::ImagePosRecord()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
ImagePosRecord::~ImagePosRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ImagePosRecord::STATUS ImagePosRecord::update(POINT32F pos)
|
||||
{
|
||||
if (p_Last.x == 0 && p_Last.y == 0)
|
||||
{
|
||||
stPositonMove[ubEnd].x = 0;
|
||||
stPositonMove[ubEnd].y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stPositonMove[ubEnd].x = pos.x - p_Last.x;
|
||||
stPositonMove[ubEnd].y = pos.y - p_Last.y;
|
||||
}
|
||||
|
||||
p_Last = pos;
|
||||
ubEnd = (ubEnd + 1) % TRACK_POS_REC_MAX;
|
||||
nTotalCnt++;
|
||||
|
||||
return Analyse();
|
||||
}
|
||||
|
||||
void ImagePosRecord::reset()
|
||||
{
|
||||
ubEnd = 0;
|
||||
nTotalCnt = 0;
|
||||
p_Last.x = 0;
|
||||
p_Last.y = 0;
|
||||
memset(stPositonMove, 0, sizeof(POINT32F) * TRACK_POS_REC_MAX);
|
||||
}
|
||||
|
||||
|
||||
ImagePosRecord::STATUS ImagePosRecord::Analyse()
|
||||
{
|
||||
//
|
||||
int VecFluCnt = 0; //速度波动
|
||||
int aFluCnt = 0; //加速度波动
|
||||
|
||||
if (nTotalCnt > 10)
|
||||
{
|
||||
for (size_t i = 0; i < MIN(TRACK_POS_REC_MAX, nTotalCnt); i++)
|
||||
{
|
||||
int indCurr = (ubEnd - i + TRACK_POS_REC_MAX) % TRACK_POS_REC_MAX;
|
||||
int indLast = (ubEnd - i - 1 + TRACK_POS_REC_MAX) % TRACK_POS_REC_MAX;
|
||||
auto movedisCurr = sqrt(stPositonMove[indCurr].x * stPositonMove[indCurr].x + stPositonMove[indCurr].y * stPositonMove[indCurr].y);
|
||||
auto movedisLast = sqrt(stPositonMove[indLast].x * stPositonMove[indLast].x + stPositonMove[indLast].y * stPositonMove[indLast].y);
|
||||
if (movedisCurr > 6)
|
||||
{
|
||||
VecFluCnt++;
|
||||
}
|
||||
|
||||
if (ABS(movedisCurr) > ABS(movedisLast) * 2 && ABS(movedisCurr) > 5)
|
||||
{
|
||||
aFluCnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (VecFluCnt > 2 || aFluCnt > 0)
|
||||
{
|
||||
return STATUS::NOTSTABLE;
|
||||
}
|
||||
|
||||
return STATUS::STATBLE;
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
// 目标像方位置记录,并估计伺服控制状态,不稳定时不使用惯性预测
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arith_Common.hpp"
|
||||
|
||||
|
||||
class ImagePosRecord
|
||||
{
|
||||
enum STATUS
|
||||
{
|
||||
STATBLE,
|
||||
NOTSTABLE
|
||||
};
|
||||
public:
|
||||
ImagePosRecord();
|
||||
~ImagePosRecord();
|
||||
|
||||
public:
|
||||
STATUS update(POINT32F pos); // 更新坐标
|
||||
|
||||
void reset();
|
||||
|
||||
STATUS Analyse();
|
||||
|
||||
private:
|
||||
UBYTE8 ubEnd;
|
||||
SINT32 nTotalCnt;
|
||||
POINT32F stPositonMove[TRACK_POS_REC_MAX]; //帧间运动
|
||||
|
||||
POINT32F p_Last; //起始点
|
||||
|
||||
//
|
||||
BBOOL bStable; //稳态
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
file = open('dump_y16_640x513_2025-08-23-21_47_05.data','rb')
|
||||
|
||||
dy500 = np.zeros(1500)
|
||||
dy300 = np.zeros(1500)
|
||||
|
||||
for i in range(1500):
|
||||
frame = file.read(640*513*2+640*513+640*4)
|
||||
y8 = np.frombuffer(frame[640*513*2:640*513*2+640*513],dtype=np.uint8).reshape([513,640])
|
||||
y16 = np.frombuffer(frame[0:640*513*2],dtype=np.uint16).reshape([513,640])
|
||||
|
||||
dy500[i] = abs(y16[500,:].astype(np.int16) - (y16[501,:]).astype(np.int16)).mean()
|
||||
dy300[i] = abs(y16[300,:].astype(np.int16) - (y16[301,:]).astype(np.int16)).mean()
|
||||
|
||||
|
||||
cv2.imshow("",y8)
|
||||
cv2.waitKey(1)
|
||||
|
||||
|
||||
plt.plot(dy500)
|
||||
plt.plot(dy300)
|
||||
plt.show()
|
||||
|
||||
Loading…
Reference in new issue