轮毂检测算法更新

This commit is contained in:
yiyi 2026-04-02 00:38:50 +08:00
parent 839862ea26
commit 512c72b895
23 changed files with 124 additions and 36 deletions

View File

@ -164,28 +164,17 @@ int DetectPresenter::DetectRod(
objOps.push_back(rodCenters);
}
// 从点云数据生成投影图像10cm边界
detectionResult.image = PointCloudImageUtils::GeneratePointCloudRetPointImage(xyzData, objOps, 100.0);
// 从点云数据生成投影图像10cm边界同时获取点云原始范围
double margin = 100.0; // 10cm = 100mm
double xMin, xMax, yMin, yMax;
detectionResult.image = PointCloudImageUtils::GeneratePointCloudRetPointImage(xyzData, objOps, margin, &xMin, &xMax, &yMin, &yMax);
// 在图像上绘制棒材的轴向方向线
if (!detectionResult.image.isNull() && !rodInfo.empty()) {
QPainter painter(&detectionResult.image);
painter.setRenderHint(QPainter::Antialiasing);
// 计算点云范围与PointCloudImageUtils相同的方式
double xMin = 1e10, xMax = -1e10, yMin = 1e10, yMax = -1e10;
for (const auto& line : xyzData) {
for (const auto& pt : line) {
if (pt.pt3D.z < 1e-4) continue;
xMin = std::min(xMin, (double)pt.pt3D.x);
xMax = std::max(xMax, (double)pt.pt3D.x);
yMin = std::min(yMin, (double)pt.pt3D.y);
yMax = std::max(yMax, (double)pt.pt3D.y);
}
}
// 扩展边界与GeneratePointCloudRetPointImage相同
double margin = 100.0; // 10cm = 100mm
xMin -= margin;
xMax += margin;
yMin -= margin;

View File

@ -121,6 +121,11 @@ public:
*/
QStringList getCameraNames() const;
/**
* @brief
*/
QString GetAlgoVersion() const;
/**
* @brief
*/

View File

@ -256,6 +256,12 @@ QStringList WheelMeasurePresenter::getCameraNames() const
return names;
}
QString WheelMeasurePresenter::GetAlgoVersion() const
{
const char* version = wd_wheelArchHeigthMeasureVersion();
return version ? QString::fromUtf8(version) : QString();
}
void WheelMeasurePresenter::ResetDetect(int cameraIndex)
{
StopDetection();

View File

@ -2,8 +2,9 @@
#define VERSION_H
#define WHEELMEASURE_VERSION_STRING "1.0.1"
#define WHEELMEASURE_BUILD_STRING "6"
#define WHEELMEASURE_APP_NAME "轮眉高度测量"
#define WHEELMEASURE_VERSION_STRING "1.0.2"
#define WHEELMEASURE_BUILD_STRING "1"
#define WHEELMEASURE_FULL_VERSION_STRING "V" WHEELMEASURE_VERSION_STRING "_" WHEELMEASURE_BUILD_STRING
// 获取版本信息的便捷函数

View File

@ -1,3 +1,7 @@
# 1.0.2
## build_1 2026-04-01
1. 更新算法 1.3.2
# 1.0.1
## build_5 2026-01-17
1. 更新算法 1.3.0

View File

@ -7,6 +7,7 @@
#include "dialogcameralevel.h"
#include "dialogalgoarg.h"
#include "dialogcamera.h"
#include "AboutDialog.h"
#include <QImage>
#include <QStringList>
@ -148,6 +149,18 @@ void MainWindow::resizeEvent(QResizeEvent* event)
QMainWindow::resizeEvent(event);
}
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
if (watched == m_versionLabel && event->type() == QEvent::MouseButtonPress) {
const QString algoVersion = m_presenter ? m_presenter->GetAlgoVersion() : QString();
AboutDialog dlg(WHEELMEASURE_APP_NAME, m_versionLabel->text(), algoVersion, this);
dlg.exec();
return true;
}
return QMainWindow::eventFilter(watched, event);
}
void MainWindow::on_btn_hide_clicked()
{
this->showMinimized();
@ -554,6 +567,8 @@ void MainWindow::setupVersionDisplay()
m_versionLabel->setText(versionText);
m_versionLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
m_versionLabel->setCursor(Qt::PointingHandCursor);
m_versionLabel->installEventFilter(this);
m_versionLabel->setStyleSheet("QLabel { color: rgb(239, 241, 245); font-size: 24px; margin-right: 10px; }");

View File

@ -5,6 +5,7 @@
#include <QStringList>
#include <QSplitter>
#include <QResizeEvent>
#include <QEvent>
#include <QMessageBox>
#include <QPushButton>
#include <QStringListModel>
@ -48,6 +49,7 @@ public:
protected:
void resizeEvent(QResizeEvent* event) override;
bool eventFilter(QObject* watched, QEvent* event) override;
private slots:
void on_btn_hide_clicked();

View File

@ -109,10 +109,10 @@ struct WheelOutlierFilterParam
*/
struct WheelTreeGrowParam
{
double yDeviation_max = 5.0; // 生长时允许的最大Y偏差
double zDeviation_max = 2.0; // 生长时允许的最大Z偏差
double yDeviation_max = 10.0; // 生长时允许的最大Y偏差
double zDeviation_max = 10.0; // 生长时允许的最大Z偏差
int maxLineSkipNum = 10; // 生长时允许的最大跳线数
double maxSkipDistance = 5.0; // 当maxLineSkipNum为-1时使用
double maxSkipDistance = 10.0; // 当maxLineSkipNum为-1时使用
double minLTypeTreeLen = 100.0; // 最少的L型节点数目
double minVTypeTreeLen = 100.0; // 最少的V型节点数目
};

View File

@ -39,6 +39,13 @@ typedef struct
SWD3DPoint point;
}SWDIndexing3DPoint;
typedef struct
{
int lineIdx;
int ptIdx;
SVzNL3DPoint point;
}SWDIndexingVzPoint;
typedef struct
{
int start;
@ -124,6 +131,16 @@ struct RGB {
int b;
};
struct Plane {
double A, B, C, D; // Æ½Ãæ Ax+By+Cz+D=0
Plane() : A(0), B(0), C(0), D(0) {}
Plane(double a, double b, double c, double d) : A(a), B(b), C(c), D(d) {}
};
enum RobustType {
HUBER,
TUKEY
};
#define LINE_FEATURE_NUM 16
#define LINE_FEATURE_UNDEF 0
#define LINE_FEATURE_L_JUMP_H2L 1
@ -257,6 +274,18 @@ typedef struct
double featureValue;
}SWD_segFeature;
typedef struct
{
int lineIdx;
int startPtIdx;
int endPtIdx;
int peakPtIdx;
SVzNL3DPoint startPt;
SVzNL3DPoint endPt;
SVzNL3DPoint peakPt;
double featureValue;
}SWD_rodArcFeature;
typedef struct
{
double sameGapTh;
@ -330,6 +359,18 @@ typedef struct
int angleChkScalePos; //仅用于加速angleCheck的速度
}SSG_gapFeatureTree;
typedef struct
{
int treeState;
int treeType;
int sLineIdx;
int eLineIdx;
double tree_value;
SSG_ROIRectD roi;
std::vector< SWD_segFeature> treeNodes;
int angleChkScalePos; //½öÓÃÓÚ¼ÓËÙangleCheckµÄËÙ¶È
}SSG_segFeatureTree;
typedef struct
{
int treeState;
@ -352,6 +393,15 @@ typedef struct
std::vector< SWD_segFeature> treeNodes;
}SWD_segFeatureTree;
typedef struct
{
int treeState;
int sLineIdx;
int eLineIdx;
double tree_value;
std::vector< SWD_rodArcFeature> treeNodes;
}SWD_rodArcFeatureTree;
typedef struct
{
int vTreeFlag;
@ -359,7 +409,9 @@ typedef struct
int treeType;
int sLineIdx;
int eLineIdx;
int data;
SSG_ROIRectD roi;
SVzNLRange ptIdxRange;
}SSG_treeInfo;
typedef struct
@ -549,6 +601,8 @@ typedef struct
typedef struct
{
int pntIdx;
int forwardPntIdx;
int backwardPntIdx;
int type;
double forwardAngle; //前向角
double backwardAngle; //后向角
@ -557,6 +611,7 @@ typedef struct
double backwardDiffZ;
double pre_stepDist;
double post_stepDist;
double curr_z;
double forward_z;
double backward_z;
}SSG_pntDirAngle;

View File

@ -32,6 +32,10 @@
//汽车轮眉高度测量
#define SX_ERR_INVALID_ARC -2301
#define SX_ERR_INVALID_WHEEL_EDGE -2302
#define SX_ERR_NO_WHEEL_COMMON_EDGE -2303
#define SX_ERR_NO_WHEEL_ARC -2304
//糖袋子拆线
#define SX_ERR_NO_MARK -2401

View File

@ -2637,9 +2637,9 @@ void _outputScanDataFile_removeZeros(char* fileName, SVzNL3DLaserLine * scanData
#define TEST_CONVERT_TO_GRID 0
#define TEST_COMPUTE_WHEEL_ARCH 1
#define TEST_COMPUTE_CALIB_PARA 1
#define TEST_COMPUTE_CALIB_PARA 0
#define TEST_GROUP 1
#define TEST_GROUP 2
int main()
{
#if TEST_CONVERT_TO_GRID
@ -2717,10 +2717,11 @@ int main()
#if TEST_COMPUTE_WHEEL_ARCH
const char* dataPath[TEST_GROUP] = {
"F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/现场数据/", //0
"F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/部署现场数据/", //1
};
SVzNLRange fileIdx[TEST_GROUP] = {
{1,2},
{1,2}, {1,4}
};
SSG_planeCalibPara poseCalibPara;
@ -2744,14 +2745,14 @@ int main()
char _scan_file[256];
int endGroup = TEST_GROUP - 1;
for (int grp = 0; grp <= endGroup; grp++)
for (int grp = 1; grp <= endGroup; grp++)
{
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
poseCalibPara = _readCalibPara(calibFile);
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 193;
//fidx = 4;
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanData;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanData);
@ -2783,17 +2784,17 @@ int main()
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 10;
growParam.yDeviation_max = 5.0;
growParam.maxSkipDistance = 5.0;
growParam.zDeviation_max = 2.0;//
growParam.yDeviation_max = 10.0;
growParam.maxSkipDistance = 10.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 100; //mm
growParam.minVTypeTreeLen = 100; //mm
WD_wheelArchInfo wheelArcHeight;
memset(&wheelArcHeight, 0, sizeof(WD_wheelArchInfo));
bool wheePresense = wd_wheelPresenseDetection( scanData, wheelRoi3d);
if (true == wheePresense)
bool wheelPresense = wd_wheelPresenseDetection( scanData, wheelRoi3d);
if (true == wheelPresense)
{
int lineNum = (int)scanData.size();
for (int i = 0; i < lineNum; i++)
@ -2802,7 +2803,7 @@ int main()
int kkk = 1;
//行处理
//调平,去除地面
wd_horizonCamera_lineDataR(scanData[i], poseCalibPara.planeCalib, poseCalibPara.planeHeight - 5);
wd_horizonCamera_lineDataR(scanData[i], poseCalibPara.planeCalib, -1); // poseCalibPara.planeHeight - 5);
}
#if 0 //数据转存
sprintf_s(_scan_file, "%sLaserLine%d_grid_RTadjust.txt", dataPath[grp], fidx);
@ -2819,7 +2820,7 @@ int main()
growParam,
poseCalibPara,
&errCode);
}
long t2 = GetTickCount64();
@ -2831,6 +2832,12 @@ int main()
#endif
printf("%s: height=%f, arcToGrund=%f, time=%d(ms)!\n", _scan_file, wheelArcHeight.archToCenterHeigth, wheelArcHeight.archToGroundHeigth, (int)(t2 - t1));
}
else
{
printf("%s: no Wheel!", _scan_file);
}
}
}
#endif
printf("all done!\n");