稳定版本
This commit is contained in:
+49
-36
@@ -1,44 +1,57 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <triggerManager.h>
|
||||
#include <mutex>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
|
||||
template <typename summaryDataTemplate>
|
||||
class summaryData{
|
||||
class summaryData {
|
||||
public:
|
||||
summaryData(){
|
||||
summaryData() {}
|
||||
|
||||
summaryDataTemplate* get(const std::string& sn) {
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
cleanOldest(100);
|
||||
|
||||
auto it = map.find(sn);
|
||||
if (it != map.end()) {
|
||||
return &(it->second.first);
|
||||
}
|
||||
|
||||
order.push_back(sn);
|
||||
auto list_it = std::prev(order.end());
|
||||
map.emplace(sn, std::make_pair(summaryDataTemplate(), list_it));
|
||||
|
||||
return &(map.find(sn)->second.first);
|
||||
}
|
||||
|
||||
bool remove(const std::string& sn) {
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
auto it = map.find(sn);
|
||||
if (it != map.end()) {
|
||||
order.erase(it->second.second);
|
||||
map.erase(it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
void cleanAbove(int num){
|
||||
std::lock_guard<std::mutex>locker(_mutex);
|
||||
for (auto it = map.end(); map.size() > num ; it--){
|
||||
map.erase(it);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
summaryDataTemplate* get(std::string sn){
|
||||
cleanAbove(100);
|
||||
std::lock_guard<std::mutex>locker(_mutex);
|
||||
auto it = map.find(sn);
|
||||
if (it != map.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
map.insert(std::make_pair(sn, summaryDataTemplate()));
|
||||
return &map.find(sn)->second;
|
||||
}
|
||||
bool remove(std::string sn) {
|
||||
std::lock_guard<std::mutex>locker(_mutex);
|
||||
auto it = map.find(sn);
|
||||
if (it != map.end()) {
|
||||
map.erase(it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
std::unordered_map<std::string, summaryDataTemplate> map;
|
||||
std::mutex _mutex;
|
||||
void cleanOldest(int num) {
|
||||
while (map.size() > num) {
|
||||
const std::string& oldest_sn = order.front();
|
||||
auto it = map.find(oldest_sn);
|
||||
if (it != map.end()) {
|
||||
map.erase(it);
|
||||
}
|
||||
order.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::pair<summaryDataTemplate, std::list<std::string>::iterator>> map;
|
||||
std::list<std::string> order;
|
||||
QMutex _mutex;
|
||||
};
|
||||
#pragma once
|
||||
@@ -43,14 +43,14 @@ public:
|
||||
|
||||
// 主蓝色曲线
|
||||
m_plot->addGraph();
|
||||
m_plot->graph(0)->setPen(QPen(Qt::blue, 2));
|
||||
m_plot->graph(0)->setPen(QPen(QColor(0,191,255), 3));
|
||||
m_plot->graph(0)->setScatterStyle(QCPScatterStyle::ssNone);
|
||||
|
||||
// 新增红色点图层
|
||||
m_plot->addGraph();
|
||||
m_plot->graph(1)->setLineStyle(QCPGraph::lsNone);
|
||||
m_plot->graph(1)->setScatterStyle(
|
||||
QCPScatterStyle(QCPScatterStyle::ssDisc, QPen(Qt::red), QBrush(Qt::red), 6)
|
||||
QCPScatterStyle(QCPScatterStyle::ssDisc, QPen(Qt::red), QBrush(Qt::red), 5)
|
||||
);
|
||||
m_plot->xAxis->setBasePen(QPen(Qt::white, 2)); // 坐标轴线
|
||||
m_plot->yAxis->setBasePen(QPen(Qt::white, 2));
|
||||
@@ -67,7 +67,30 @@ public:
|
||||
m_plot->xAxis->setLabelColor(Qt::white); // "时间" / "数值" 文字
|
||||
m_plot->yAxis->setLabelColor(Qt::white);
|
||||
|
||||
m_plot->yAxis->setRange(m_limitLow - 1, m_limitHigh + 1);
|
||||
m_plot->yAxis->setRange(m_limitLow - 2, m_limitHigh + 2);
|
||||
|
||||
// 鼠标追踪用的 tracer
|
||||
m_tracer = new QCPItemTracer(m_plot);
|
||||
m_tracer->setGraph(m_plot->graph(0)); // 让它追踪你的蓝色曲线
|
||||
m_tracer->setStyle(QCPItemTracer::tsCircle);
|
||||
m_tracer->setPen(QPen(Qt::yellow));
|
||||
m_tracer->setBrush(Qt::yellow);
|
||||
m_tracer->setSize(7);
|
||||
m_tracer->setVisible(false); // 默认隐藏
|
||||
|
||||
// 文本提示
|
||||
m_tracerText = new QCPItemText(m_plot);
|
||||
m_tracerText->setColor(Qt::white); // 文字颜色
|
||||
m_tracerText->setFont(QFont("微软雅黑", 10, QFont::Bold));
|
||||
m_tracerText->position->setType(QCPItemPosition::ptPlotCoords);
|
||||
m_tracerText->setBrush(QBrush(QColor(0, 0, 0, 150))); // 半透明背景
|
||||
m_tracerText->setPadding(QMargins(5, 2, 5, 2)); // 留点内边距
|
||||
m_tracerText->setVisible(false);
|
||||
|
||||
// 绑定鼠标移动事件
|
||||
connect(m_plot, &QCustomPlot::mouseMove, this, &WaveFormWidget::onMouseMoveInPlot);
|
||||
|
||||
|
||||
addLimitLines(m_limitHigh, m_limitLow);
|
||||
}
|
||||
|
||||
@@ -81,12 +104,12 @@ public:
|
||||
m_yOverLimit.append(value);
|
||||
|
||||
auto* textItem = new QCPItemText(m_plot);
|
||||
textItem->setPositionAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
textItem->setPositionAlignment(Qt::AlignLeft | Qt::AlignBottom);
|
||||
textItem->position->setType(QCPItemPosition::ptPlotCoords);
|
||||
textItem->position->setCoords(m_timeCounter, value);
|
||||
textItem->setText(QString::number(value, 'f', 2));
|
||||
textItem->setColor(Qt::yellow);
|
||||
textItem->setFont(QFont("微软雅黑", 8, QFont::Bold));
|
||||
textItem->setFont(QFont("微软雅黑", 8,QFont::Bold));
|
||||
m_textItems.append(textItem);
|
||||
}
|
||||
|
||||
@@ -122,6 +145,13 @@ protected:
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
void leaveEvent(QEvent* event) override {
|
||||
if (m_tracer) m_tracer->setVisible(false);
|
||||
if (m_tracerText) m_tracerText->setVisible(false);
|
||||
m_plot->replot();
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void editJsonParameters() {
|
||||
JsonEditorDialog* dlg = new JsonEditorDialog(m_json, this);
|
||||
@@ -132,6 +162,36 @@ private slots:
|
||||
});
|
||||
dlg->show();
|
||||
}
|
||||
void onMouseMoveInPlot(QMouseEvent* event) {
|
||||
double x = m_plot->xAxis->pixelToCoord(event->pos().x());
|
||||
if (!m_xData.isEmpty()) {
|
||||
double y = findNearestYValue(x);
|
||||
|
||||
m_tracer->setGraphKey(x);
|
||||
m_tracer->updatePosition();
|
||||
m_tracer->setVisible(true);
|
||||
|
||||
m_tracerText->setText(QString("%1\n值:%2")
|
||||
.arg(static_cast<int>(std::round(x)))
|
||||
.arg(y, 0, 'f', 2));
|
||||
m_tracerText->setVisible(true);
|
||||
m_tracerText->setTextAlignment(Qt::AlignLeft);
|
||||
|
||||
// 判断左右边显示气泡
|
||||
int mouseX = event->pos().x();
|
||||
int mouseY = event->pos().y();
|
||||
int plotWidth = m_plot->width();
|
||||
int plotHeight = m_plot->height();
|
||||
|
||||
Qt::Alignment hAlign = (mouseX < plotWidth / 2) ? Qt::AlignLeft : Qt::AlignRight;
|
||||
Qt::Alignment vAlign = (mouseY < plotHeight / 2) ? Qt::AlignTop : Qt::AlignBottom;
|
||||
|
||||
m_tracerText->setPositionAlignment(hAlign | vAlign);
|
||||
|
||||
m_tracerText->position->setCoords(x, y);
|
||||
m_plot->replot();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void applyJsonParams() {
|
||||
@@ -152,15 +212,45 @@ private:
|
||||
|
||||
m_plot->replot();
|
||||
}
|
||||
|
||||
// 简单线性插值(或者最近点)
|
||||
double interpolateYValue(double x) {
|
||||
for (int i = 1; i < m_xData.size(); ++i) {
|
||||
if (m_xData[i] >= x) {
|
||||
double x0 = m_xData[i - 1], y0 = m_yData[i - 1];
|
||||
double x1 = m_xData[i], y1 = m_yData[i];
|
||||
if (x1 == x0) return y0;
|
||||
return y0 + (y1 - y0) * (x - x0) / (x1 - x0);
|
||||
}
|
||||
}
|
||||
return m_yData.last(); // 超出范围
|
||||
}
|
||||
double findNearestYValue(double x) {
|
||||
if (m_xData.isEmpty())
|
||||
return 0;
|
||||
|
||||
int nearestIndex = 0;
|
||||
double minDist = std::abs(m_xData[0] - x);
|
||||
|
||||
for (int i = 1; i < m_xData.size(); ++i) {
|
||||
double dist = std::abs(m_xData[i] - x);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
nearestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return m_yData[nearestIndex];
|
||||
}
|
||||
|
||||
void addLimitLines(double high, double low) {
|
||||
auto* line1 = new QCPItemStraightLine(m_plot);
|
||||
line1->setPen(QPen(Qt::green, 1, Qt::DashLine));
|
||||
line1->setPen(QPen(Qt::green, 1, Qt::SolidLine));
|
||||
line1->point1->setCoords(0, high);
|
||||
line1->point2->setCoords(1, high);
|
||||
|
||||
auto* line2 = new QCPItemStraightLine(m_plot);
|
||||
line2->setPen(QPen(Qt::green, 1, Qt::DashLine));
|
||||
line2->setPen(QPen(Qt::green, 1, Qt::SolidLine));
|
||||
line2->point1->setCoords(0, low);
|
||||
line2->point2->setCoords(1, low);
|
||||
}
|
||||
@@ -175,6 +265,9 @@ private:
|
||||
int m_maxPoints = 50;
|
||||
double m_timeCounter = 0;
|
||||
double m_limitHigh = -1, m_limitLow = 2;
|
||||
QCPItemTracer* m_tracer = nullptr;
|
||||
QCPItemText* m_tracerText = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -96,8 +96,15 @@ static bool _952_15_H_Algo(std::shared_ptr <detData> data, handleAIModels* _hand
|
||||
qCritical() << "图片数量不满足要求:" << data->oriImgs.size();
|
||||
return false;
|
||||
}
|
||||
if (data->oriImgs[0].rows == 100) {
|
||||
cv::Mat Paint;
|
||||
data->oriImgs[0].copyTo(Paint);
|
||||
cv::putText(Paint, "time out", cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255), 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
cv::Mat Paint;
|
||||
QMutex paintMutex;
|
||||
clock_t start, finish;
|
||||
start = clock();
|
||||
|
||||
@@ -109,7 +116,7 @@ static bool _952_15_H_Algo(std::shared_ptr <detData> data, handleAIModels* _hand
|
||||
cv::cvtColor(src2, Paint, cv::COLOR_GRAY2BGR);
|
||||
else
|
||||
src2.copyTo(Paint);
|
||||
QMutex paintMutex;
|
||||
|
||||
std::future <bool> future = std::async(std::launch::async, _952_15_H_25D_ALGO_HuaShangAI, data, data->oriImgs[2], _handleAIModels, std::ref(Paint), std::ref(paintMutex));
|
||||
HTuple out_Distance, out_ResultRows, out_ResultCols, out_Flag, out_LinePonit;
|
||||
{
|
||||
|
||||
@@ -49,7 +49,6 @@ static bool _952_15_Q_2D_P_ALGO_HuaShangAI(cv::Mat& img, handleAIModels* _handle
|
||||
if (clsIsNg == true) {
|
||||
color = cv::Scalar(0, 0, 255);
|
||||
isNg = true;
|
||||
cv::approxPolyDP(contours[i], contours[i], 3, true); // 多边形拟合
|
||||
QMutexLocker locker(&paintMutex);
|
||||
cv::drawContours(Paint, contours, i, color, 2);
|
||||
}
|
||||
@@ -83,7 +82,6 @@ static bool _952_15_Q_2D_P_ALGO_ZangWuAI(cv::Mat& img, handleAIModels* _handleAi
|
||||
if (clsIsNg == true) {
|
||||
color = cv::Scalar(0, 0, 255);
|
||||
isNg = true;
|
||||
cv::approxPolyDP(contours[i], contours[i], 3, true); // 多边形拟合
|
||||
QMutexLocker locker(&paintMutex);
|
||||
cv::drawContours(Paint, contours, i, color, 2);
|
||||
}
|
||||
@@ -400,9 +398,16 @@ public:
|
||||
//8040 1 Summary1
|
||||
void sumRequest1(QByteArray& byteArray){
|
||||
_serviceManager->_triggerManager->writeShort({ "D8040_0" ,"D9402_1","D9404_1"});
|
||||
int snPos = _3D_snPos;
|
||||
int snPos = summary_triggerPos;
|
||||
std::string sn = _serviceManager->_triggerManager->readSnFromQByteArray(byteArray, snPos, false, false, -1);
|
||||
_952_15_Q_2D3D_1_summaryData* dataPtr = _summaryData.get(sn);
|
||||
_serviceManager->_triggerManager->writeShort({
|
||||
"D6020_1", "D6021_1", "D6022_1", "D6023_1", "D6024_1",
|
||||
"D6025_1", "D6026_1", "D6027_1", "D6028_1", "D6029_1",
|
||||
"D6030_1", "D6031_1", "D6032_1", "D6033_1", "D6034_1",
|
||||
"D6035_1", "D6036_1", "D6037_1", "D6038_1", "D6039_1"
|
||||
});
|
||||
|
||||
_serviceManager->_triggerManager->sendFinsMsg("write_float_D8046_"+ dataPtr->_2D_P_Result);//右上留白
|
||||
_serviceManager->_triggerManager->sendFinsMsg("write_float_D8047_" + dataPtr->_2D_N_Result);//右下留白
|
||||
_serviceManager->_triggerManager->sendFinsMsg("write_float_D8048_" + dataPtr->_3D_1_Result);//右对其度
|
||||
@@ -410,7 +415,6 @@ public:
|
||||
std::cout << "通道1 SN:" << sn << " 发送结果" << std::endl;//:\n左留白->" << dataPtr->leftLiuBai.toStdString() << "\n右留白->" << dataPtr->rightLiuBai.toStdString() << "\n对其度->" << dataPtr->duiqidu.toStdString()<<std::endl;
|
||||
_summaryData.remove(sn);
|
||||
}
|
||||
|
||||
static bool processAlgo(std::shared_ptr <detData> data, handleAiModelManager* _handleAiModelManager){
|
||||
cv::Mat testImg;
|
||||
if(data->oriImgs[0].channels() == 1)
|
||||
|
||||
Reference in New Issue
Block a user