V20260131-2.3.13
增加额外存储NG图片和数据清零的功能。
This commit is contained in:
+2
-2
@@ -7,11 +7,11 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <filesystem>
|
||||
#include <filesystem>
|
||||
#include <QDir>
|
||||
|
||||
#pragma execution_character_set("utf-8")
|
||||
const std::string softwareVersion = "20260129-2.3.12";
|
||||
const std::string softwareVersion = "20260131-2.3.13";
|
||||
const std::string euiJsonVersion = "1.0.6";
|
||||
#define GigaByte 1073741824
|
||||
#define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径
|
||||
|
||||
@@ -169,7 +169,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
QString defaultExtraNgSavePath = "{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{processResult}/";
|
||||
private:
|
||||
QString defaultPath = "{imgSaveRootDir}/{yyyy-MM-dd}/{saveObjectName}{imageType}/{HH}H/{processResult}/{SN}/";
|
||||
QString defaultFileName = "{SN}_{cameraName}_{imageType}_{index}_{HH-mm-ss}-{ms}";
|
||||
@@ -524,6 +524,7 @@ public:
|
||||
saveRes = _paramSyncManager->get("通用设置", "存储结果图", true).toBool();
|
||||
saveSeg = _paramSyncManager->get("通用设置", "存储Seg图", true).toBool();
|
||||
saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool();
|
||||
saveExtraNgImg = _paramSyncManager->get("通用设置", "额外存储NG图片", false).toBool();
|
||||
getParamTimer.restart();
|
||||
}
|
||||
}
|
||||
@@ -531,7 +532,9 @@ public:
|
||||
std::shared_ptr<saveJob> resJob(new saveJob("[RES_JOB]" + data->SNcode));
|
||||
std::shared_ptr<saveJob> oriJob(new saveJob("[ORI_JOB]" + data->SNcode));
|
||||
|
||||
QString resSavePath = _ImageSavePathFormatter.genPath(data, "结果图", data->customPath, data->customImageSaveTemplateParams);//获取文件夹名
|
||||
//生产存储结果图的路径
|
||||
QString resSavePath = _ImageSavePathFormatter.genPath(data, "结果图", data->customPath, data->customImageSaveTemplateParams);
|
||||
//根据预设生成每个文件夹的存储路径并打包
|
||||
if (saveRes == true) {
|
||||
if (createPathCache.contains(resSavePath) == false) {//不存在此文件夹则创建
|
||||
createDirectoryIfNotExists(resSavePath);
|
||||
@@ -546,7 +549,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
QString oriSavePath = _ImageSavePathFormatter.genPath(data, "原图", data->customPath, data->customImageSaveTemplateParams);//获取文件夹名
|
||||
//生产存储原图的路径
|
||||
QString oriSavePath = _ImageSavePathFormatter.genPath(data, "原图", data->customPath, data->customImageSaveTemplateParams);
|
||||
//根据预设生成每个文件夹的存储路径并打包
|
||||
if (saveOri == true || saveSeg == true || saveCls == true) {
|
||||
|
||||
if (createPathCache.contains(oriSavePath) == false) {//不存在此文件夹则创建
|
||||
@@ -570,11 +575,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
//将打包的图片加入存储队列,priority优先存储,多为jpg的结果图,为了尽快释放内存
|
||||
if (resJob->imgQueue.size() != 0)
|
||||
getSaveThread()->addJob(resJob, imgSaveThread::priority);
|
||||
if (oriJob->imgQueue.size() != 0)
|
||||
getSaveThread()->addJob(oriJob);
|
||||
|
||||
//额外单独存储NG图片
|
||||
if (saveExtraNgImg&&(data->halconOK == false || data->aiDetOK == false)) {
|
||||
std::shared_ptr<saveJob> saveExtraNgJob(new saveJob("[EXTRA_NG_JOB]" + data->SNcode));
|
||||
QString extraNgSavePath = _ImageSavePathFormatter.genPath(data, "结果图", _ImageSavePathFormatter.defaultExtraNgSavePath, data->customImageSaveTemplateParams);//获取文件夹名
|
||||
if (createPathCache.contains(extraNgSavePath) == false) {//不存在此文件夹则创建
|
||||
createDirectoryIfNotExists(extraNgSavePath);
|
||||
allDirectoryPaths.push_back(extraNgSavePath);//记录文件夹路径
|
||||
createPathCache.put(extraNgSavePath);//加入缓存
|
||||
}
|
||||
|
||||
//结果图保存
|
||||
if (data->getResultImgSize() != 0) {
|
||||
std::vector<std::string>fileNames = _ImageSavePathFormatter.genFileNames(data, ImageSavePathFormatter::resImg, data->getResultImgVec());//按规则为文件创建命名
|
||||
packageData(saveExtraNgJob->imgQueue, extraNgSavePath.toLocal8Bit().toStdString(), fileNames, data->getResultImgVec());//打包数据
|
||||
}
|
||||
if (saveExtraNgJob->imgQueue.size() != 0)
|
||||
getSaveThread()->addJob(saveExtraNgJob);
|
||||
}
|
||||
#pragma region 将存储目录写入数据库中
|
||||
#if savePathToDataBase
|
||||
if (!allDirectoryPaths.empty() && dbThread) {
|
||||
@@ -618,7 +642,7 @@ private:
|
||||
int maxSaveThreadCount = imgSaveTreadMaxCount;
|
||||
QMutex saveThreadMutexVec;
|
||||
std::vector<std::unique_ptr<imgSaveThread>> saveThreads;//存图线程池
|
||||
bool saveOri = true, saveRes = true, saveSeg = true, saveCls = true;
|
||||
bool saveOri = true, saveRes = true, saveSeg = true, saveCls = true, saveExtraNgImg = false;
|
||||
QElapsedTimer getParamTimer;//防止加锁次数过多导致卡顿
|
||||
paramSyncManager* _paramSyncManager;
|
||||
ImageSavePathFormatter _ImageSavePathFormatter;
|
||||
|
||||
@@ -8,11 +8,19 @@ class PieWidget : public QWidget {
|
||||
public:
|
||||
explicit PieWidget(QSize size,QWidget* parent = nullptr) : QWidget(parent) {
|
||||
goodRate = 1.0; // Ĭ��100%��Ʒ��
|
||||
hasData = true;
|
||||
this->setFixedSize(size);
|
||||
}
|
||||
|
||||
void setGoodRate(double rate) {
|
||||
goodRate = qBound(0.0, rate, 1.0);
|
||||
hasData = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void setGoodRate(double rate, bool hasDataValue) {
|
||||
goodRate = qBound(0.0, rate, 1.0);
|
||||
hasData = hasDataValue;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -25,23 +33,30 @@ protected:
|
||||
int size = qMin(width(), height()) - 10;
|
||||
QRect rect((width() - size) / 2, (height() - size) / 2, size, size);
|
||||
|
||||
// ������Ʒ��ɫ����
|
||||
p.setBrush(Qt::green);
|
||||
p.setPen(Qt::NoPen);
|
||||
int start = 1440;
|
||||
p.drawPie(rect, start, int(goodRate * 360 * 16));
|
||||
if (!hasData) {
|
||||
p.setBrush(QColor(90, 90, 90));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
// ������Ʒ��ɫ����
|
||||
p.setBrush(Qt::green);
|
||||
p.setPen(Qt::NoPen);
|
||||
int start = 1440;
|
||||
p.drawPie(rect, start, int(goodRate * 360 * 16));
|
||||
|
||||
// ����ʣ�ಿ�֣���ѡ�������������Ҫ��ʾ��
|
||||
p.setBrush(Qt::red);
|
||||
p.drawPie(rect, start, int(-(1 - goodRate) * 360 * 16));
|
||||
// ����ʣ�ಿ�֣���ѡ�������������Ҫ��ʾ��
|
||||
p.setBrush(Qt::red);
|
||||
p.drawPie(rect, start, int(-(1 - goodRate) * 360 * 16));
|
||||
|
||||
// ���ư�ɫ�ָ���
|
||||
p.setPen(QPen(Qt::white, 2));
|
||||
p.drawLine(rect.center(),
|
||||
QPoint(rect.center().x(), rect.top()));
|
||||
// ���ư�ɫ�ָ���
|
||||
p.setPen(QPen(Qt::white, 2));
|
||||
p.drawLine(rect.center(),
|
||||
QPoint(rect.center().x(), rect.top()));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
double goodRate;
|
||||
bool hasData;
|
||||
};
|
||||
#pragma once
|
||||
@@ -3,6 +3,9 @@
|
||||
#include <QLineEdit>
|
||||
#include <QGridLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
#include <QPainter>
|
||||
#include <QGroupBox>
|
||||
#include <uiModule/components/pieWidget.h>
|
||||
@@ -16,6 +19,21 @@ public:
|
||||
font.setPointSize(10);
|
||||
title->setFont(font);
|
||||
|
||||
clearButton = new QPushButton(QString::fromUtf8("清零"));
|
||||
clearButton->setFixedHeight(24);
|
||||
clearButton->setStyleSheet("QPushButton { color: white; background-color: rgb(70, 75, 80); border: 1px solid rgb(120, 125, 130); border-radius: 4px; padding: 2px 8px; } QPushButton:hover { background-color: rgb(90, 95, 100); } QPushButton:pressed { background-color: rgb(60, 65, 70); }");
|
||||
connect(clearButton, &QPushButton::clicked, this, [this]() {
|
||||
const auto reply = QMessageBox::question(
|
||||
this,
|
||||
QString::fromUtf8("确认清零"),
|
||||
QString::fromUtf8("确定要清零当前统计数据吗?"),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes) {
|
||||
clearAllData();
|
||||
}
|
||||
});
|
||||
|
||||
// 输入框(只读显示)
|
||||
totalEdit = createEdit();
|
||||
ngEdit = createEdit();
|
||||
@@ -42,7 +60,11 @@ public:
|
||||
pie = new PieWidget(QSize(size().width() / 4, size().width() / 4));
|
||||
// 整体布局
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->addWidget(title);
|
||||
QHBoxLayout* titleLayout = new QHBoxLayout();
|
||||
titleLayout->addWidget(title);
|
||||
titleLayout->addStretch();
|
||||
titleLayout->addWidget(clearButton);
|
||||
mainLayout->addLayout(titleLayout);
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(pie, 1, Qt::AlignCenter);
|
||||
|
||||
@@ -66,7 +88,7 @@ public:
|
||||
ngEdit->setText(QString::number(ng));
|
||||
double rate = total > 0 ? (double)good / total : 0.0;
|
||||
rateEdit->setText(QString::number(rate * 100, 'f', 1) + "%");
|
||||
pie->setGoodRate(rate);
|
||||
pie->setGoodRate(rate, total > 0);
|
||||
}
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override {
|
||||
@@ -85,12 +107,20 @@ protected:
|
||||
|
||||
}
|
||||
private:
|
||||
void clearAllData() {
|
||||
QMutexLocker locker(&mutex);
|
||||
okCnt = 0;
|
||||
ngCnt = 0;
|
||||
setStats(0, 0, 0);
|
||||
}
|
||||
|
||||
QLineEdit* createEdit() {
|
||||
QLineEdit* edit = new QLineEdit;
|
||||
edit->setReadOnly(true);
|
||||
edit->setText("0");
|
||||
return edit;
|
||||
}
|
||||
QPushButton* clearButton;
|
||||
QLineEdit* totalEdit;
|
||||
QLineEdit* ngEdit;
|
||||
QLineEdit* okEdit;
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
#include <QCursor>
|
||||
#include <QGraphicsSimpleTextItem>
|
||||
#include <QMessageBox>
|
||||
#include <QtCharts/QChart>
|
||||
#include <QtCharts/QChartView>
|
||||
#include <QtCharts/QBarSet>
|
||||
@@ -80,6 +82,7 @@ public:
|
||||
private:
|
||||
QMutex mutex;
|
||||
QLabel* titleLabel;
|
||||
QPushButton* clearButton;
|
||||
QLabel* labelLeft;
|
||||
QLabel* labelRight;
|
||||
QChart* chart;
|
||||
@@ -92,12 +95,36 @@ private:
|
||||
bool enableAnimation;
|
||||
QList<QGraphicsSimpleTextItem*> valueLabels;
|
||||
|
||||
void clearAllData() {
|
||||
clearBarData();
|
||||
setStats(0, 0, 0);
|
||||
}
|
||||
|
||||
void initUI(const QString& title) {
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
||||
|
||||
titleLabel = new QLabel(title);
|
||||
titleLabel->setStyleSheet("font-size: 16px; font-weight: bold;");
|
||||
mainLayout->addWidget(titleLabel);
|
||||
clearButton = new QPushButton(QString::fromUtf8("清零"));
|
||||
clearButton->setFixedHeight(24);
|
||||
clearButton->setStyleSheet("QPushButton { color: white; background-color: rgb(70, 75, 80); border: 1px solid rgb(120, 125, 130); border-radius: 4px; padding: 2px 8px; } QPushButton:hover { background-color: rgb(90, 95, 100); } QPushButton:pressed { background-color: rgb(60, 65, 70); }");
|
||||
connect(clearButton, &QPushButton::clicked, this, [this]() {
|
||||
const auto reply = QMessageBox::question(
|
||||
this,
|
||||
QString::fromUtf8("确认清零"),
|
||||
QString::fromUtf8("确定要清零当前统计数据吗?"),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes) {
|
||||
clearAllData();
|
||||
}
|
||||
});
|
||||
|
||||
QHBoxLayout* titleLayout = new QHBoxLayout();
|
||||
titleLayout->addWidget(titleLabel);
|
||||
titleLayout->addStretch();
|
||||
titleLayout->addWidget(clearButton);
|
||||
mainLayout->addLayout(titleLayout);
|
||||
|
||||
QHBoxLayout* dataLayout = new QHBoxLayout();
|
||||
labelLeft = new QLabel(QString::fromUtf8("检测总数\n不良数"));
|
||||
|
||||
@@ -28,12 +28,17 @@ void exceptionResume(std::shared_ptr<detData> data, yh_581_address address, QStr
|
||||
data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1,0,1");//发送结果
|
||||
|
||||
}
|
||||
halconResult dituo(std::shared_ptr <detData> data, cv::Mat& src, cv::Mat& Paint, bool isLeft,handdleAI::pClassification* cls) {
|
||||
halconResult dituo(std::shared_ptr <detData> data, cv::Mat& src, cv::Mat& Paint, bool isLeft, std::vector < std::string>& defects) {
|
||||
halconResult result;
|
||||
try {
|
||||
//src = cv::imread("D:\\testImg.bmp", -1);
|
||||
//cv::Mat srcHalf;
|
||||
//cv::resize(src, srcHalf, cv::Size(0, 0), 0.5, 0.5);
|
||||
double widthThreshold = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 2.0).toDouble();
|
||||
double heightThreshold = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 2.0).toDouble();
|
||||
double areaThreshold = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 2.0).toDouble();
|
||||
bool clsJugmentEnable = data->service->_paramSyncManager->get("底托检测", "CLS判定启用", true).toBool();
|
||||
double clsProbThreshold = data->service->_paramSyncManager->get("底托检测", "CLS置信度阈值", 0.9).toDouble();
|
||||
//double DiTuoPiYi_DistanceWight = data->service->_paramSyncManager->get("底托检测", "底托偏移长度最大值(mm)", 50.0).toDouble();
|
||||
//double DiTuoPiYi_DistanceHeight = data->service->_paramSyncManager->get("底托检测", "底托偏移宽度最大值(mm)", 0.8).toDouble();
|
||||
//double DiTuoPiYi_DistanceArea = data->service->_paramSyncManager->get("底托检测", "底托偏移面积最大值(mm)", 40.0).toDouble();
|
||||
if (src.channels() != 3)
|
||||
cv::cvtColor(src, Paint, cv::COLOR_GRAY2BGR);
|
||||
else
|
||||
@@ -48,14 +53,12 @@ halconResult dituo(std::shared_ptr <detData> data, cv::Mat& src, cv::Mat& Paint,
|
||||
/*HDevEngineCpp::HDevEngine myEngine;
|
||||
myEngine.StartDebugServer();
|
||||
procedureCall.SetWaitForDebugConnection(true);*/
|
||||
float resolution = data->service->_paramSyncManager->get("相机精度", QString::fromStdString(data->cameraKeyName) + "精度", 0.046276).toFloat();
|
||||
float resolution = data->service->_paramSyncManager->get("相机精度", QString::fromStdString(data->cameraKeyName) + "精度", 0.040888).toFloat();
|
||||
HTuple in_Par, in_FilePath("./halconFiles/");
|
||||
double widthThreshold = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 2.0).toDouble();
|
||||
double heightThreshold = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 2.0).toDouble();
|
||||
double areaThreshold = data->service->_paramSyncManager->get("底托检测", "宽度阈值(mm)", 2.0).toDouble();
|
||||
in_Par[0] = widthThreshold;
|
||||
in_Par[1] = heightThreshold;
|
||||
in_Par[2] = areaThreshold;
|
||||
|
||||
procedureCall.SetInputIconicParamObject("in_Image", in_Image);
|
||||
procedureCall.SetInputCtrlParamTuple("in_Par", in_Par);
|
||||
procedureCall.SetInputCtrlParamTuple("in_FilePath", in_FilePath);
|
||||
@@ -83,59 +86,73 @@ halconResult dituo(std::shared_ptr <detData> data, cv::Mat& src, cv::Mat& Paint,
|
||||
//输出的点集不是正常的轮廓点集,把点集在黑图上画出来,在用opencv重新找一遍轮廓
|
||||
|
||||
std::vector<cv::Point> contour;
|
||||
for (int i = 0; i < out_Y.Length(); i++)
|
||||
{
|
||||
for (int i = 0; i < out_Y.Length(); i++) {
|
||||
contour.push_back(cv::Point(out_X[i].D(), out_Y[i].D()));
|
||||
whiteMat.at<uchar>(out_Y[i].D(), out_X[i].D()) = (255);
|
||||
}
|
||||
contours.push_back(contour);
|
||||
|
||||
}
|
||||
for (int i = 0; i < contours.size(); i++)
|
||||
{
|
||||
std::string ngDetails = (out_NgDetails[i].ToTuple().ToString().Text());
|
||||
ngDetails = gbkToUtf8(ngDetails.substr(1, ngDetails.length() - 2));
|
||||
if (data->service->_paramSyncManager->get("底托检测","底托偏移检测启用",false).toBool() == false && ngDetails == "底托偏移")
|
||||
return result;
|
||||
cv::Rect rect = cv::boundingRect(contours[i]);
|
||||
if (rect.width * resolution >= widthThreshold || rect.height * resolution >= heightThreshold) {
|
||||
cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3);
|
||||
float realWidth = rect.width;
|
||||
float realHeight = rect.height;
|
||||
float realArea = cv::contourArea(contours[i]);
|
||||
QString DefectStr = "宽:" + QString::number(realWidth * resolution, 'f', 3)
|
||||
+ "mm高:" + QString::number(realHeight * resolution, 'f', 3)
|
||||
+ "mm面积:" + QString::number(realArea * resolution * resolution, 'f', 3);
|
||||
textPainterdefect.appendPaintJob(DefectStr.toStdString() + ngDetails, cv::Point(rect.x, rect.y), cv::Scalar(0, 255, 255));
|
||||
cv::Mat clsImg = src(rect);
|
||||
cv::resize(clsImg, clsImg, cv::Size(128, 128));
|
||||
int clsResult = cls->Evaluate(clsImg);
|
||||
double prob = cls->getProbability();
|
||||
clsImgs.push_back({ "result" + std::to_string(clsResult) + "_prob" + std::to_string(prob),clsImg });
|
||||
data->halconOK = false;
|
||||
result.defects.push_back(ngDetails);
|
||||
result.isNg = true;
|
||||
}
|
||||
|
||||
}
|
||||
//画轮廓
|
||||
std::vector<std::vector<cv::Point>> contoursPaint;
|
||||
cv::findContours(whiteMat, contoursPaint, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
|
||||
int maxIndex = 0, maxArea = 0;
|
||||
for (int i = 0; i < contoursPaint.size(); i++)
|
||||
{
|
||||
for (int i = 0; i < contoursPaint.size(); i++) {
|
||||
cv::Rect rect = cv::boundingRect(contoursPaint[i]);
|
||||
if (rect.width * resolution >= widthThreshold || rect.height * resolution >= heightThreshold) {
|
||||
cv::drawContours(Paint, contoursPaint, i, cv::Scalar(0, 0, 255), 3);
|
||||
}
|
||||
|
||||
}
|
||||
for (int i = 0; i < contours.size(); i++) {
|
||||
std::string ngDetails = (out_NgDetails[i].ToTuple().ToString().Text());
|
||||
ngDetails = gbkToUtf8(ngDetails.substr(1, ngDetails.length() - 2));
|
||||
if (data->service->_paramSyncManager->get("底托检测", "底托偏移检测启用", false).toBool() == false && ngDetails == "底托偏移")
|
||||
return result;
|
||||
cv::Rect rect = cv::boundingRect(contours[i]);
|
||||
if (rect.width * resolution >= widthThreshold || rect.height * resolution >= heightThreshold) {
|
||||
float realWidth = rect.width;
|
||||
float realHeight = rect.height;
|
||||
float realArea = cv::contourArea(contours[i]);
|
||||
cv::Mat clsImg = src(rect);
|
||||
cv::resize(clsImg, clsImg, cv::Size(128, 128));
|
||||
//int clsResult = cls->Evaluate(clsImg);
|
||||
//double prob = cls->getProbability();
|
||||
//clsImgs.push_back({ "result" + std::to_string(clsResult) + "_prob" + std::to_string(prob),clsImg });
|
||||
//if (clsJugmentEnable == true) {//CLS处理
|
||||
// if (clsResult != 0 && prob > clsProbThreshold) {//NG
|
||||
// data->halconOK = false;
|
||||
// result.defects.push_back(ngDetails);
|
||||
// result.isNg = true;
|
||||
// cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3);
|
||||
// }
|
||||
// else
|
||||
// cv::rectangle(Paint, rect, cv::Scalar(0, 255, 0), 3);
|
||||
// QString DefectStr = "宽:" + QString::number(realWidth * resolution, 'f', 3)
|
||||
// + "mm高:" + QString::number(realHeight * resolution, 'f', 3)
|
||||
// + "mm面积:" + QString::number(realArea * resolution * resolution, 'f', 3)
|
||||
// + "r" + QString::number(clsResult) + "_p" + QString::number(prob);
|
||||
// textPainterdefect.appendPaintJob(DefectStr.toStdString() + ngDetails, cv::Point(rect.x, rect.y), cv::Scalar(0, 255, 255));
|
||||
//}
|
||||
//else {//不经过CLS直接判为NG
|
||||
data->halconOK = false;
|
||||
result.defects.push_back(ngDetails);
|
||||
result.isNg = true;
|
||||
cv::rectangle(Paint, rect, cv::Scalar(0, 0, 255), 3);
|
||||
QString DefectStr = "宽:" + QString::number(realWidth * resolution, 'f', 3)
|
||||
+ "mm高:" + QString::number(realHeight * resolution, 'f', 3)
|
||||
+ "mm面积:" + QString::number(realArea * resolution * resolution, 'f', 3);
|
||||
clsImgs.push_back({ "result0_prob0",clsImg });
|
||||
textPainterdefect.putText(Paint,DefectStr.toStdString() + ngDetails, cv::Point(rect.x, rect.y), cv::Scalar(0, 255, 255));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
//释放存储画图文字
|
||||
textPainterdefect.executePaintJobs(Paint);
|
||||
//textPainterdefect.executePaintJobs(Paint);
|
||||
}
|
||||
data->insertClsOriginImg(clsImgs);
|
||||
}
|
||||
CATCH_EXCEPTIONS
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
bool ALGO_BaoMoHouDiBu(std::shared_ptr <detData> data, baoMoHouDiBuDetParams* _detParams, yh_581_address address) {
|
||||
try {
|
||||
@@ -146,12 +163,17 @@ bool ALGO_BaoMoHouDiBu(std::shared_ptr <detData> data, baoMoHouDiBuDetParams* _d
|
||||
std::vector < std::string> defects;
|
||||
|
||||
//data->oriImgs.clear();
|
||||
|
||||
//cv:: Mat dituo_1 =(cv::imread("D://testImage/dituo_1.bmp", -1));
|
||||
//data->oriImgs.push_back(cv::imread("D://testImage/dituo_2.bmp", -1));
|
||||
///////////////////取图//处理//////////////////
|
||||
if (data->getOriImgSize() < 2)
|
||||
{
|
||||
qCritical() << "图片数量不满足要求:" << data->getOriImgSize();
|
||||
exceptionResume(data, address, "图片数量不满足要求");
|
||||
//data->service->_triggerManager->writeShort("D" + address.resultAddr + "_1");//发送结果
|
||||
//cv::Mat Paint;
|
||||
//data->getOriImg(0).copyTo(Paint);
|
||||
//data->insertResultImg(Paint);
|
||||
return false;
|
||||
}
|
||||
if (data->getOriImgVec()[0].rows == 100) {
|
||||
@@ -161,20 +183,17 @@ bool ALGO_BaoMoHouDiBu(std::shared_ptr <detData> data, baoMoHouDiBuDetParams* _d
|
||||
|
||||
cv::Mat Paint, Paint1, Paint2;
|
||||
bool leftFirst = address.triggerAddr != 20200;
|
||||
cv::Mat first = data->getOriImg(0);
|
||||
cv::Mat second = data->getOriImg(1);
|
||||
//first = cv::imread("D://testImg/dituo (2).bmp", -1);
|
||||
//second = cv::imread("D://testImg/dituo (1).bmp", -1);
|
||||
auto feature1 = std::async(std::launch::async, dituo, data, std::ref(first), std::ref(Paint1), leftFirst, _detParams->cls1);
|
||||
auto feature2 = std::async(std::launch::async, dituo, data, std::ref(second), std::ref(Paint2), ~leftFirst, _detParams->cls2);
|
||||
|
||||
//cv::Mat first = data->getOriImg(0);
|
||||
//cv::Mat second = data->getOriImg(1);
|
||||
cv::Mat first = cv::imread("C:\\Users\\RCi\\Downloads\\dituo\\04QCB43581020PG1W0002024\\04QCB43581020PG1W0002024_Camera1_ORI_0_18-26-04-169.bmp", -1);
|
||||
cv::Mat second = cv::imread("C:\\Users\\RCi\\Downloads\\dituo\\04QCB43581020PG1W0002024\\04QCB43581020PG1W0002024_Camera1_ORI_1_18-26-04-169.bmp", -1);
|
||||
auto feature1 = std::async(std::launch::async, dituo, data, std::ref(first), std::ref(Paint1), leftFirst, std::ref(defects));
|
||||
auto feature2 = std::async(std::launch::async, dituo, data, std::ref(second), std::ref(Paint2), ~leftFirst, std::ref(defects));
|
||||
feature1.wait();
|
||||
halconResult hResult1 = feature1.get();
|
||||
defects.insert(defects.end(), hResult1.defects.begin(), hResult1.defects.end());
|
||||
|
||||
feature2.wait();
|
||||
halconResult hResult2 = feature2.get();
|
||||
defects.insert(defects.end(), hResult2.defects.begin(), hResult2.defects.end());
|
||||
|
||||
if (address.triggerAddr == 20400)
|
||||
cv::hconcat(Paint2, Paint1, Paint);
|
||||
|
||||
@@ -9,33 +9,28 @@ QStringList headList({ "条码", "时间","位置","结果","缺陷明细" });
|
||||
|
||||
class baoMoHouDiBuDetParams {
|
||||
public:
|
||||
handdleAI::pClassification* cls1 = nullptr;
|
||||
handdleAI::pClassification* cls2 = nullptr;
|
||||
|
||||
};
|
||||
static bool ALGO_BaoMoHouDiBu(std::shared_ptr <detData> data, baoMoHouDiBuDetParams* _detParams, yh_581_address address);
|
||||
|
||||
class _581_BaoMo : public mission {
|
||||
public:
|
||||
using baoMoHouDiBuTrigger = _581_Single_triggerTemplate<baoMoHouDiBuDetParams>;
|
||||
using baoMoHouDiBuTrigger = _581_Single_triggerTemplate<baoMoHouDiBuDetParams>;
|
||||
baoMoHouDiBuTrigger _station_1;
|
||||
baoMoHouDiBuTrigger _station_2;
|
||||
|
||||
baoMoHouDiBuDetParams _baoMoHouDiBuDetParams1;
|
||||
baoMoHouDiBuDetParams _baoMoHouDiBuDetParams2;
|
||||
baoMoHouDiBuDetParams _baoMoHouDiBuDetParams;
|
||||
|
||||
void onConfigReloaded() {
|
||||
HDevEngineCpp::HDevEngine myEngine;
|
||||
myEngine.SetProcedurePath("");
|
||||
myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_602.hdpl");
|
||||
_baoMoHouDiBuDetParams1.cls1 = handdleAI::CreateClsObjV3("./handleaiModels/dituo_cls.BHD", 0, 1);
|
||||
_baoMoHouDiBuDetParams1.cls2 = handdleAI::CreateClsObjV3("./handleaiModels/dituo_cls.BHD", 0, 1);
|
||||
_baoMoHouDiBuDetParams2.cls1 = handdleAI::CreateClsObjV3("./handleaiModels/dituo_cls.BHD", 0, 1);
|
||||
_baoMoHouDiBuDetParams2.cls2 = handdleAI::CreateClsObjV3("./handleaiModels/dituo_cls.BHD", 0, 1);
|
||||
myEngine.SetProcedurePath("./halconAlgo/AlgoLibrary_581.hdpl");
|
||||
}
|
||||
bool initCustom() {
|
||||
#pragma region 注册触发器回调
|
||||
|
||||
_station_1.init("Camera1","包膜后底托位置度检测-左-相机12",20200,1,2, &_baoMoHouDiBuDetParams1,_serviceManager,bridge, ALGO_BaoMoHouDiBu);
|
||||
_station_2.init("Camera2", "包膜后底托位置度检测-右-相机13",20400,1,2,&_baoMoHouDiBuDetParams2, _serviceManager, bridge, ALGO_BaoMoHouDiBu);
|
||||
_station_1.init("Camera1","包膜后底托位置度检测-左-相机12",20400,1,2, &_baoMoHouDiBuDetParams,_serviceManager,bridge, ALGO_BaoMoHouDiBu);
|
||||
_station_2.init("Camera2", "包膜后底托位置度检测-右-相机13",20200,1,2,&_baoMoHouDiBuDetParams, _serviceManager, bridge, ALGO_BaoMoHouDiBu);
|
||||
#pragma endregion
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user