2026-02-19 00:45:00 +08:00
|
|
|
|
#ifndef POINTCLOUDIMAGEUTILS_H
|
|
|
|
|
|
#define POINTCLOUDIMAGEUTILS_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <QImage>
|
|
|
|
|
|
#include <QColor>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <utility> // for std::pair
|
|
|
|
|
|
|
|
|
|
|
|
#include "VZNL_Types.h"
|
|
|
|
|
|
|
|
|
|
|
|
// 简单的颗粒信息结构 - 避免依赖OpenCV
|
|
|
|
|
|
struct SimpleParticleInfo {
|
|
|
|
|
|
SVzNL3DPoint vertix[8]; // 8个顶点
|
|
|
|
|
|
struct {
|
|
|
|
|
|
double width;
|
|
|
|
|
|
double height;
|
|
|
|
|
|
} size;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 通用检测目标结构体 - 替代算法SDK的 SSG_peakRgnInfo
|
|
|
|
|
|
struct DetectionTargetInfo {
|
|
|
|
|
|
struct {
|
|
|
|
|
|
double x;
|
|
|
|
|
|
double y;
|
|
|
|
|
|
double z_yaw; // 偏航角(度)
|
|
|
|
|
|
} centerPos;
|
|
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
|
|
double dWidth;
|
|
|
|
|
|
double dHeight;
|
|
|
|
|
|
} objSize;
|
|
|
|
|
|
|
|
|
|
|
|
int orienFlag = 0; // 朝向标记: 0=无, 1=正面, 2=反面
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-03-11 23:39:28 +08:00
|
|
|
|
// 孔洞标记信息结构体 - 用于孔洞检测结果可视化
|
|
|
|
|
|
struct HoleMarkerInfo {
|
|
|
|
|
|
SVzNL3DPoint center; // 孔洞中心 (double x,y,z)
|
|
|
|
|
|
double radius; // 孔洞半径 (mm)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-02-19 00:45:00 +08:00
|
|
|
|
class PointCloudImageUtils
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
// 点云转图像 - 使用通用检测目标结构体
|
|
|
|
|
|
static QImage GeneratePointCloudImage(SVzNL3DLaserLine* scanData,
|
|
|
|
|
|
int lineNum,
|
|
|
|
|
|
const std::vector<DetectionTargetInfo>& objOps);
|
|
|
|
|
|
|
|
|
|
|
|
static QImage GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData,
|
|
|
|
|
|
int lineNum,
|
|
|
|
|
|
const std::vector<DetectionTargetInfo>& objOps);
|
|
|
|
|
|
|
|
|
|
|
|
// 新的点云图像生成函数 - 基于X、Y范围创建图像
|
|
|
|
|
|
static QImage GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData,
|
|
|
|
|
|
int lineNum);
|
|
|
|
|
|
|
|
|
|
|
|
// LapWeld点云和检测结果转图像 - 基于scan lines格式
|
|
|
|
|
|
static QImage GeneratePointCloudImage(const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPoint>>& weldResults,
|
|
|
|
|
|
int imageWidth = 800, int imageHeight = 600);
|
|
|
|
|
|
|
|
|
|
|
|
// Workpiece点云和角点检测结果转图像 - 将角点画成圆点
|
|
|
|
|
|
static QImage GeneratePointCloudRetPointImage(const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPoint>>& cornerPoints,
|
2026-04-05 12:55:15 +08:00
|
|
|
|
double margin = 0.0,
|
|
|
|
|
|
double* outXMin = nullptr,
|
|
|
|
|
|
double* outXMax = nullptr,
|
|
|
|
|
|
double* outYMin = nullptr,
|
|
|
|
|
|
double* outYMax = nullptr);
|
2026-02-19 00:45:00 +08:00
|
|
|
|
|
|
|
|
|
|
// ParticleSize点云和颗粒检测结果转图像 - 生成带颗粒标记的点云图像 (直接返回QImage)
|
|
|
|
|
|
static QImage GeneratePointCloudImageWithParticles(
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
const std::vector<SimpleParticleInfo>& particles,
|
|
|
|
|
|
int cameraIndex);
|
|
|
|
|
|
|
|
|
|
|
|
// WheelMeasure点云和轮眉检测结果转图像 - 生成带轮眉标记的点云图像
|
|
|
|
|
|
static QImage GenerateWheelArchImage(
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
const SVzNL3DPoint& wheelArchPos,
|
|
|
|
|
|
const SVzNL3DPoint& wheelUpPos,
|
|
|
|
|
|
const SVzNL3DPoint& wheelDownPos,
|
|
|
|
|
|
double archToCenterHeight,
|
|
|
|
|
|
bool hasResult = true);
|
|
|
|
|
|
|
|
|
|
|
|
// 从检测数据缓存生成深度图像
|
|
|
|
|
|
static int GenerateDepthImage(
|
|
|
|
|
|
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& detectionDataCache,
|
|
|
|
|
|
QImage& outImage);
|
|
|
|
|
|
|
|
|
|
|
|
// 通道间距测量图像生成 - 根据算法标记的nPointIdx着色
|
|
|
|
|
|
// 参考 HC_chanelSpaceMeasure_test.cpp 的 _outputRGBDScan_RGBD 函数
|
|
|
|
|
|
// nPointIdx > 0: 使用预定义的8种颜色, 否则使用灰色
|
|
|
|
|
|
static QImage GenerateChannelSpaceImage(
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
int imageWidth = 1056, int imageHeight = 992);
|
|
|
|
|
|
|
2026-03-11 23:39:28 +08:00
|
|
|
|
// 点云灰度图生成 - 灰色着色 + 自适应点大小填充扫描线间隙(通用接口)
|
|
|
|
|
|
static QImage GenerateHeatmapImage(
|
2026-03-26 18:10:59 +08:00
|
|
|
|
const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
double rotateX_deg = 0.0,
|
|
|
|
|
|
double rotateY_deg = 0.0);
|
2026-03-11 23:39:28 +08:00
|
|
|
|
|
|
|
|
|
|
// 孔洞检测图像生成 - 热力图底图 + 孔洞标记
|
2026-03-29 22:21:10 +08:00
|
|
|
|
// useZGradient: 为true时根据点云Z值范围生成灰度渐变底图,否则使用统一灰色底图
|
2026-03-11 23:39:28 +08:00
|
|
|
|
static QImage GenerateHoleDetectionImage(
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
2026-03-26 18:10:59 +08:00
|
|
|
|
const std::vector<HoleMarkerInfo>& holes,
|
|
|
|
|
|
double rotateX_deg = 0.0,
|
2026-03-29 22:21:10 +08:00
|
|
|
|
double rotateY_deg = 0.0,
|
|
|
|
|
|
bool useZGradient = false);
|
2026-03-11 23:39:28 +08:00
|
|
|
|
|
2026-04-12 00:28:12 +08:00
|
|
|
|
// 计算scan lines格式点云的范围
|
|
|
|
|
|
static void CalculateScanLinesRange(const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
double& xMin, double& xMax,
|
|
|
|
|
|
double& yMin, double& yMax);
|
2026-02-19 00:45:00 +08:00
|
|
|
|
private:
|
|
|
|
|
|
// 定义线特征颜色和大小获取函数
|
|
|
|
|
|
static void GetLineFeatureStyle(int vType, int hType, int objId,
|
|
|
|
|
|
QColor& pointColor, int& pointSize);
|
|
|
|
|
|
|
|
|
|
|
|
// 获取对象颜色
|
|
|
|
|
|
static QColor GetObjectColor(int index);
|
|
|
|
|
|
|
|
|
|
|
|
// 计算点云范围
|
|
|
|
|
|
static void CalculatePointCloudRange(SVzNL3DLaserLine* scanData, int lineNum,
|
|
|
|
|
|
double& xMin, double& xMax,
|
|
|
|
|
|
double& yMin, double& yMax);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制LapWeld检测结果
|
|
|
|
|
|
static void DrawLapWeldResults(QPainter& painter,
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPoint>>& weldResults,
|
|
|
|
|
|
double xMin, double xMax, double yMin, double yMax,
|
|
|
|
|
|
int imageWidth, int imageHeight);
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制scan lines点云数据
|
|
|
|
|
|
static void DrawScanLinesPointCloud(QPainter& painter,
|
|
|
|
|
|
const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
double xMin, double xMax, double yMin, double yMax,
|
|
|
|
|
|
int imageWidth, int imageHeight);
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制检测目标(使用通用结构体)
|
|
|
|
|
|
static void DrawDetectionTargets(QPainter& painter,
|
|
|
|
|
|
const std::vector<DetectionTargetInfo>& objOps,
|
|
|
|
|
|
double xMin, double xScale, int xSkip,
|
|
|
|
|
|
double yMin, double yScale, int ySkip,
|
|
|
|
|
|
int imgCols, int imgRows);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-04-12 00:28:12 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 通用点云画布类
|
|
|
|
|
|
* 封装点云底图生成 + 3D→2D投影 + 通用绘图原语
|
|
|
|
|
|
* 调用方可自由组合绘制点、文字、线段、圆等标记
|
|
|
|
|
|
*/
|
|
|
|
|
|
class PointCloudCanvas
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 从 scan lines 创建画布,生成灰色点云底图
|
|
|
|
|
|
* @param scanLines 扫描线数据
|
|
|
|
|
|
* @param imageWidth 图像宽度(像素)
|
|
|
|
|
|
* @param imageHeight 图像高度(像素)
|
|
|
|
|
|
* @param margin 边距(像素)
|
|
|
|
|
|
*/
|
|
|
|
|
|
static PointCloudCanvas Create(const std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
|
|
|
|
|
int imageWidth = 1056, int imageHeight = 992, int margin = 50);
|
|
|
|
|
|
|
|
|
|
|
|
bool isValid() const;
|
|
|
|
|
|
QImage& image();
|
|
|
|
|
|
const QImage& image() const;
|
|
|
|
|
|
|
|
|
|
|
|
/// 3D坐标→图像像素坐标
|
|
|
|
|
|
QPoint project(double x, double y) const;
|
|
|
|
|
|
|
|
|
|
|
|
/// 绘制实心圆点
|
|
|
|
|
|
void drawPoint(double x, double y, const QColor& color, int size = 4);
|
|
|
|
|
|
|
|
|
|
|
|
/// 绘制圆(radius3D为3D空间半径,自动投影为像素半径)
|
|
|
|
|
|
void drawCircle(double x, double y, double radius3D, const QColor& color, int penWidth = 2, bool fill = false);
|
|
|
|
|
|
|
|
|
|
|
|
/// 绘制文字(offsetX/offsetY 为像素偏移)
|
|
|
|
|
|
void drawText(double x, double y, const QString& text, const QColor& color, int fontSize = 14, int offsetX = 8, int offsetY = 6);
|
|
|
|
|
|
|
|
|
|
|
|
/// 绘制线段
|
|
|
|
|
|
void drawLine(double x1, double y1, double x2, double y2, const QColor& color, int penWidth = 2);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
QImage m_image;
|
|
|
|
|
|
double m_xMin = 0.0;
|
|
|
|
|
|
double m_yMin = 0.0;
|
|
|
|
|
|
double m_scale = 1.0;
|
|
|
|
|
|
int m_offsetX = 0;
|
|
|
|
|
|
int m_offsetY = 0;
|
|
|
|
|
|
int m_imgWidth = 0;
|
|
|
|
|
|
int m_imgHeight = 0;
|
|
|
|
|
|
bool m_valid = false;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-02-19 00:45:00 +08:00
|
|
|
|
#endif // POINTCLOUDIMAGEUTILS_H
|