Files
handleaiuinew/HanddleAI/HandleAiUi-new/back/algorithmThread.cpp
T
2024-05-22 16:47:14 +08:00

902 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <algorithmThread.h>
#include "FrontendBackendBridge.h"
#include <myTools.h>
#include <QtConcurrent/QtConcurrent>
#include <future>
#include <iostream>
#include <halconAlgo/Correction.h>
#include <halconAlgo/Inspection.h>
bool showOk = true;//显示ok缺陷的框
std::string fileSavePath("D://CCD//");
//////////////////////
std::vector<cv::Point2f> rotateRect(const cv::Rect& rect, const cv::Point2f& center, double angle) {
// 构建矩形的四个角点
std::vector<cv::Point2f> corners(4);
corners[0] = cv::Point2f(rect.x, rect.y);
corners[1] = cv::Point2f(rect.x + rect.width, rect.y);
corners[2] = cv::Point2f(rect.x + rect.width, rect.y + rect.height);
corners[3] = cv::Point2f(rect.x, rect.y + rect.height);
// 创建旋转矩阵
cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, 1.0);
// 对每个角点应用旋转变换
std::vector<cv::Point2f> rotatedCorners(4);
for (int i = 0; i < 4; ++i) {
cv::Mat pointMat = (cv::Mat_<double>(3, 1) << corners[i].x, corners[i].y, 1);
cv::Mat rotatedPoint = rotationMatrix * pointMat;
rotatedCorners[i] = cv::Point2f(rotatedPoint.at<double>(0, 0), rotatedPoint.at<double>(1, 0));
}
return rotatedCorners;
}
double calculateAngleWithXAxis(const cv::Point& p1, const cv::Point& p2) {
// 计算两点的坐标差异
double dx = p2.x - p1.x;
double dy = p2.y - p1.y;
// 使用反正切函数计算角度
double angle = std::atan2(dy, dx) * 180 / CV_PI;
// 确保角度在 0 到 360 度之间
if (angle < 0) {
angle += 360;
}
return angle;
}
void rotateImage(const cv::Mat& src, double angle, cv::Mat& dst) {
// 图像中心作为旋转中心
cv::Point2f center(static_cast<float>(src.cols / 2), static_cast<float>(src.rows / 2));
// 计算旋转矩阵
cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
// 应用旋转
cv::warpAffine(src, dst, rot, src.size());
}
double calculateDistance(const cv::Point& p1, const cv::Point& p2) {
// 计算距离
double distance = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2));
return distance;
}
//std::vector<std::pair<cv::Point, cv::Point>> fitLines(const std::vector<cv::Point>& points, double length) {
// // 进行多边形拟合
// std::vector<cv::Point> approxCurve;
// cv::approxPolyDP(points, approxCurve, length, true);
//
// std::vector<std::pair<cv::Point, cv::Point>> lines;
//
// // 从拟合后的多边形中提取直线段
// for (size_t i = 0; i < approxCurve.size(); ++i) {
// cv::Point p1 = approxCurve[i];
// cv::Point p2 = approxCurve[(i + 1) % approxCurve.size()];
//
// lines.push_back(std::make_pair(p1, p2));
// }
//
// return lines;
//}
std::vector<std::pair<cv::Point, cv::Point>> fitLines(const std::vector<cv::Point>& points, double length) {
// 进行多边形拟合
std::vector<cv::Point> approxCurve;
cv::approxPolyDP(points, approxCurve, length, true);
std::vector<std::pair<cv::Point, cv::Point>> lines;
// 构建凸包
std::vector<cv::Point> convexHull;
cv::convexHull(approxCurve, convexHull);
// 计算凸包的几何中心
cv::Point2f center(0, 0);
for (const auto& point : convexHull) {
center.x += point.x;
center.y += point.y;
}
center *= (1.0 / convexHull.size());
// 从拟合后的多边形中提取直线段,并排除方向向内的线段
for (size_t i = 0; i < approxCurve.size(); ++i) {
cv::Point p1 = approxCurve[i];
cv::Point p2 = approxCurve[(i + 1) % approxCurve.size()];
// 计算线段的中点
cv::Point midPoint = (p1 + p2) * 0.5;
// 计算线段中点到多边形几何中心的向量
cv::Point2f centerToMid = cv::Point2f(midPoint) - center;
// 计算线段方向向量
cv::Point2f lineDirection = cv::Point2f(p2) - cv::Point2f(p1);
// 计算凸包法线
cv::Point2f normal = cv::Point2f(-centerToMid.y, centerToMid.x);
// 检查线段方向是否朝向凸包内部(与凸包法线方向相反)
if (lineDirection.dot(normal) < 0) {
lines.push_back(std::make_pair(p1, p2));
}
}
return lines;
}
void writeToData_xxxCsvOkNgNew(detData* rdata, QString OKNG, ngNoteCls* note)
{
QDateTime currentDateTime = QDateTime::currentDateTime();
std::string ymd = currentDateTime.toString("yyyy-MM-dd").toStdString();
QString filePath = QString::fromStdString(fileSavePath + "//result//" + ymd + "//Data_" + ymd + ".csv");
/* QString searchString = QString::fromStdString(rdata->getSN() + "_" + to_string(rdata->snCountIndex));*/
QString searchString = QString::fromStdString(rdata->SNcode);
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Error opening file.";
}
QStringList headers;
QList<QStringList> data;
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
QStringList fields = line.split(',');
if (headers.isEmpty()) {
// 如果headers为空,则当前行为标题行
headers = fields;
}
else {
data.append(fields);
}
}
file.close();
// 在data中进行字符串检索并修改匹配的行
int modifiedRowCount = 0;
for (int i = data.size() - 1; i > 0; --i) {
QStringList& row = data[i];
//if (row.size()<3||row.isEmpty())
//{
// break;
//}
// 在当前行中检索字符串
try
{
if (row.size() >= 6)
if (row[1].contains(searchString, Qt::CaseInsensitive)) {
// 匹配到字符串,进行修改
row[3] = OKNG;
row[4] += note->getNgSummaryStr();
row[5] += note->getOkSummaryStr();
modifiedRowCount++;
}
}
catch (...)
{
break;
}
}
// 将修改后的数据写回文件
QFile writeFile(filePath);
if (!writeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Error opening file for writing.";
}
QTextStream out(&writeFile);
// 写入标题行
out << headers.join(",") << "\n";
// 写入修改后的数据行
for (const auto& row : data) {
out << row.join(",") << "\n";
}
writeFile.close();
qDebug() << "Modified rows:" << modifiedRowCount;
qDebug() << "Data modified and saved to data_modified.csv";
//return 0;
}
void writeToData_xxxCSVNew(detData* resData, string OKNG, ngNoteCls* note)
{
QDateTime currentDateTime = QDateTime::currentDateTime();
std::string ymd = currentDateTime.toString("yyyy-MM-dd").toStdString();
int hour = currentDateTime.time().hour();
QString filePath = QString::fromStdString(fileSavePath + "//result//" + ymd + "//Data_" + ymd + ".csv");
//string sn(resData->SNcode + "-" + to_string(resData->snCountIndex));
string sn(resData->SNcode);
/*std::string str(to_string(hour) + "H//" + sn + "-" + to_string(resData->snCountIndex) + "//" + ymd
+ "-" + to_string(hour) + "_" + resData->getSN() + "-" + to_string(resData->snCountIndex));*/
std::string str(to_string(hour) + "H//" + sn + "//" + ymd
+ "-" + to_string(hour) + "_" + sn);
bool fileExist = false;
QStringList dataList;
if (hour < 10)
dataList.append("0" + QString::number(hour) + "H");
else
dataList.append(QString::number(hour) + "H");
dataList.append(QString::fromStdString(sn));
dataList.append(QString::fromStdString(str));
dataList.append(QString::fromStdString(OKNG));
dataList.append(note->getNgSummaryStr());
dataList.append(note->getOkSummaryStr());
// 创建CSV文件
QFile file(filePath);
if (!file.exists())
{
// 创建目录(如果不存在)
QDir dir;
if (!dir.mkpath(QFileInfo(filePath).absolutePath()))
{
//qWarning() << "无法创建目录:" << QFileInfo(filePath).absolutePath();
return;
}
fileExist = true;
}
// 打开CSV文件并写入数据
if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
QTextStream stream(&file);
if (fileExist == true)
{
stream << "Time,";
stream << "SN,";
stream << "Path,";
stream << "Result,";
stream << "summuryResult,";
stream << "\n";
}
// 将数据写入CSV文件
for (const QString& data : dataList) {
stream << data << ",";
}
stream << "\n";
file.close();
qDebug() << "CSV文件写入成功";
}
//else
// qWarning() << "无法打开CSV文件:" << filePath;
}
void algoThread::getAllFiles(string path, vector<string>& files, string format)
{
intptr_t hFile = 0;//恅璃曆梟
struct _finddata_t fileinfo;//恅璃陓洘
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) //恅璃湔婓
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))//瓚剿岆瘁峈恅璃標
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)//恅璃標靡笢祥漪"."睿".."
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name)); //悵湔恅璃標靡
getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format); //菰寥梢盪恅璃標
}
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));//彆祥岆恅璃標ㄛ揣湔恅璃靡
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
inline string getFileName(string path)
{
return path.substr(path.find_last_of("\\") + 1, path.find_last_of(".") - path.find_last_of("\\") - 1);
}
void drawContoursOverlap(cv::Mat& image, const std::vector<std::vector<cv::Point>>& contours) {
cv::Mat mask = cv::Mat::zeros(image.size(), CV_8U);
// 绘制轮廓在掩码上
cv::drawContours(mask, contours, -1, cv::Scalar(255), cv::FILLED);
// 将图像中与掩码不重叠的区域涂黑
cv::Mat result;
image.copyTo(result, mask);
image.setTo(cv::Scalar(0, 0, 0), ~mask);
}
void drawContourOnImage(Mat seg, cv::Mat& imgInput, Size offset = Size(0, 0)) {
if (seg.empty() || imgInput.empty()) {
std::cerr << "Empty contour or input image." << std::endl;
return;
}
cv::Mat imgWithAlpha;
cv::cvtColor(imgInput, imgWithAlpha, cv::COLOR_BGR2BGRA);
std::vector<std::vector<cv::Point>>contours;
if (offset.width != 0 && offset.height != 0)
{
Mat offsetImg(offset.width + seg.rows, offset.height + seg.cols, CV_8UC1, Scalar(0));
seg.copyTo(offsetImg(Rect(offset.width, offset.height, seg.rows, seg.cols)));
offsetImg.copyTo(seg);
}
cv::findContours(seg, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (auto& contour : contours)
{
cv::Scalar color(0, 255, 0, 128);
cv::polylines(imgWithAlpha, contour, true, color);
cv::cvtColor(imgWithAlpha, imgInput, cv::COLOR_BGRA2BGR);
}
}
/////Specified function////////////////
void writeSpecificStatement(Mat& Paint, const wchar_t* Text, rectAndData& data, int amount, int limit, Scalar& color)
{
wstring MM(to_wstring(max(data.defectHeight, data.defectWidth)));
MM = MM.substr(0, MM.find_first_of(L".") + 2);
putTextHusky(Paint, (WString2String(Text + to_wstring(amount)
+ L"/" + to_wstring(limit) + L"|" +
MM + L"mm")).c_str(),
cv::Point(data.rect.x, data.rect.y - 20), color, 20);
}
int getMaxAreaIndex(std::vector<std::vector<cv::Point>>& pts)
{
int maxVal = 0, maxI = -1;
for (int i =0;i<pts.size();i++)
{
int areaSize = cv::contourArea(pts[i]);
if (areaSize > maxVal)
{
maxI = i;
maxVal = areaSize;
}
}
return maxI;
}
std::vector < std::vector<std::pair<cv::Point, cv::Point>>> splitLinesByCenterAndAngle(const std::vector<std::pair<cv::Point, cv::Point>>& lines, const cv::Point& center) {
std::vector<std::pair<cv::Point, cv::Point>> topLines, bottomLines, leftLines, rightLines;
for (const auto& line : lines) {
const cv::Point& p1 = line.first;
const cv::Point& p2 = line.second;
// 计算线段的方向向量
cv::Point2f lineDirection = cv::Point2f(p2) - cv::Point2f(p1);
// 计算线段与 x 轴和 y 轴的夹角
double angleWithX = std::atan2(lineDirection.y, lineDirection.x) * 180 / CV_PI;
double angleWithY = std::atan2(lineDirection.x, lineDirection.y) * 180 / CV_PI;
angleWithX = (angleWithX < 0) ? 180 + angleWithX : angleWithX;
angleWithY = (angleWithY < 0) ? 180 + angleWithY : angleWithY;
// 根据线段方向和中心点位置将线段分组
if (p1.y <= center.y && p2.y <= center.y && (angleWithX < 10 || angleWithX > 170)) {
std::cout << "A" << to_string(angleWithX) << "A" << to_string(angleWithY) << std::endl;
topLines.push_back(line);
}
else if (p1.y >= center.y && p2.y >= center.y && (angleWithX < 10 || angleWithX > 170)) {
bottomLines.push_back(line);
}
else if (p1.x <= center.x && p2.x <= center.x && (angleWithY < 10 || angleWithY > 170)) {
leftLines.push_back(line);
}
else if (p1.x >= center.x && p2.x >= center.x && (angleWithY < 10 || angleWithY > 170)) {
rightLines.push_back(line);
}
}
// 返回四个方向的线段结果
return { topLines, bottomLines, leftLines, rightLines };
}
std::vector<std::pair<cv::Point, cv::Point>> filterLinesByAngle(const std::vector<std::pair<cv::Point, cv::Point>>& lines) {
std::vector<std::pair<cv::Point, cv::Point>> filteredLines;
for (const auto& line : lines) {
const cv::Point& p1 = line.first;
const cv::Point& p2 = line.second;
// 计算线段的方向向量
cv::Point2f lineDirection = cv::Point2f(p2) - cv::Point2f(p1);
// 计算线段与 x 轴和 y 轴的夹角
double angleWithX = std::abs(std::atan2(lineDirection.y, lineDirection.x) * 180 / CV_PI);
double angleWithY = std::abs(std::atan2(lineDirection.x, lineDirection.y) * 180 / CV_PI);
// 如果与 x 轴或 y 轴的夹角在正负30度内,则保留该线段
if ((angleWithX < 10 || angleWithX > 170) || (angleWithY < 10 || angleWithY > 170)) {
filteredLines.push_back(line);
}
}
return filteredLines;
}
double pointLineSegmentDistance(const cv::Point& p, const cv::Point& q, const cv::Point& a, const cv::Point& b) {
cv::Point pq = q - p;
cv::Point ab = b - a;
cv::Point pa = a - p;
double t = static_cast<double>(pq.dot(ab)) / pq.dot(pq);
if (t >= 0 && t <= 1) {
cv::Point pt = p + pq * t;
return cv::norm(pt - a);
}
else {
double dist1 = cv::norm(p - a);
double dist2 = cv::norm(q - b);
return std::min(dist1, dist2);
}
}
double calculateLineSegmentDistance(const std::pair<cv::Point, cv::Point>& line1, const std::pair<cv::Point, cv::Point>& line2) {
cv::Point p1 = line1.first;
cv::Point p2 = line1.second;
cv::Point p3 = line2.first;
cv::Point p4 = line2.second;
double distance1 = pointLineSegmentDistance(p1, p2, p3, p4);
double distance2 = pointLineSegmentDistance(p2, p1, p3, p4);
double distance3 = pointLineSegmentDistance(p3, p4, p1, p2);
double distance4 = pointLineSegmentDistance(p4, p3, p1, p2);
//return std::min({distance1, distance2, distance3, distance4 });
return (distance1 + distance2 + distance3 + distance4) / 4;
}
void calculateLineSegmentDistances(const std::vector<std::pair<cv::Point, cv::Point>>& lines1, const std::vector<std::pair<cv::Point, cv::Point>>& lines2) {
double minDistance = std::numeric_limits<double>::max();
double maxDistance = std::numeric_limits<double>::min();
double sumDistance = 0.0;
size_t count = 0;
for (const auto& line1 : lines1) {
for (const auto& line2 : lines2) {
double distance = calculateLineSegmentDistance(line1, line2);
if (distance >= 0) {
sumDistance += distance;
std::cout << "Minimum distansssdce: " << distance * 0.014744 << std::endl;
if (distance < minDistance) {
minDistance = distance;
}
if (distance > maxDistance) {
maxDistance = distance;
}
++count;
}
}
}
std::cout << "Minimum distance: " << minDistance* 0.014744 << std::endl;
std::cout << "Maximum distance: " << maxDistance* 0.014744 << std::endl;
std::cout << "Average distance: " << (sumDistance / count)* 0.014744 << std::endl;
}
/////////////////////ALGOTHREAD/////////////////////////
bool algoThread::addDetTask(std::shared_ptr <detData> data)
{
detQueueMutex.lock();
detQueue.append(data);
detQueueMutex.unlock();
this->start();
return false;
}
bool algoThread::waitForImg(std::shared_ptr <detData> data,int timeOutSet=10000)
{
int timeOut = 0;
int sleepMs = 100;
while (1)
{
int imgSize = data->imgs.size();
int imgAmountMin = data->imgAmountMin;
if (imgSize >= imgAmountMin)
return true;
timeOut+= sleepMs;
if (timeOut > timeOutSet)
return false;
QThread::msleep(sleepMs);
}
}
void algoThread::run()
{
while (m_runFlag == true)
{
while (detQueue.size() > 0)
{
detQueueMutex.lock();
std::shared_ptr <detData> data = detQueue.dequeue();//取出数据
detQueueMutex.unlock();
int threadId = data->algoThreadIndex;//获取线程id
if (waitForImg(data) == false)
{
qDebug() << "取图失败";
cout << "get img err" << endl;
detDataManager* dManager = data->dManager;
data->dManager->deleteDetData(data->timeCode);
break;
}
detDataManager* dManager = data->dManager;
data->dManager->deleteDetData(data->timeCode);
continue;
if (threadId == 0)
{
int timeOut = 0;
int sleepMs = 100;
while (data->correctionData==nullptr)
{
if (timeOut > 10000)break;
timeOut += sleepMs;
QThread::msleep(sleepMs);
}
ALGO_Correction(data);
}
else
{
if (waitForImg(data) == false)
{
qDebug() << "取图失败";
cout << "get img err" << endl;
break;
}
bridge.front.showImg("Camera", data->imgs[0], threadId);//显示原图
auto start = std::chrono::high_resolution_clock::now();
switch (threadId)
{
case 0:
Camera1_Algo(data);
break;
case 1:
Camera1_Algo(data);
break;
}
//oriSaveThread->saveOriImg(data);//保存原图
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Time taken by function: " << duration.count() << " milliseconds" << std::endl;
//if (!data->SNcode.compare(snDatas->snErrorsnError))//无sn阻塞
// data->SNcode = snDatas->waitForSn(data->timeCode);
if (data->resultImgs.size() > 0)
{
//resSaveThread->saveResImg(data);//保存结果图
bridge.front.showImg("Algorithm", data->resultImgs[0], threadId);//显示原图
//cout << "algoEnd" << data->algoThreadIndex;
}
std::vector<sqlData> sqlDatas;//定义sql数据
for (auto sqlData : data->sqlVec)//将算法中的数据导入到数据结构中
sqlDatas.push_back({ sqlData.first, std::to_string(sqlData.second) });
sql->addData(data->SNcode, sqlDatas);//将数据插入数据库
std::vector<QString>strVec({ QString::fromStdString(data->SNcode),QString::number(data->camera1Width) + "x" + QString::number(data->camera1Height) });
bridge.front.tableViewPtr->addRowDataValue(strVec);//将数据插入界面表格
detDataManager* dManager = data->dManager;
data->dManager->deleteDetData(data->timeCode);
}
}
QThread::msleep(10);
}
}
void matsToMat(cv::Mat& mat1, cv::Mat& mat2, cv::Mat* Paint)
{
auto start_time = std::chrono::high_resolution_clock::now();
*Paint = cv::Mat(mat1.rows + mat2.rows, mat1.cols, CV_8UC1);
memcpy(Paint->data, mat1.data, mat1.rows * mat1.cols);
memcpy(mat1.rows * mat1.cols + Paint->data, mat2.data, mat2.rows * mat2.cols);
if (Paint->channels() == 1)
cv::cvtColor(*Paint, *Paint, cv::COLOR_GRAY2BGR);
auto end_time = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
std::cout << "matsToMat: " << duration.count() << " microseconds" << std::endl;
}
void algoThread::ALGO_Correction(std::shared_ptr <detData> data)
{
ALGO_Inspection(data);
int pValueBounus = 100;
if (data->correctionData == nullptr)
return;
#pragma region XOY_DEFINE
HTuple hv_in_X_X0Y;
for (auto rangeData : data->correctionData->in_X_X0Y)
hv_in_X_X0Y.Append(rangeData);
HTuple hv_in_Y_X0Y;
for (auto rangeData : data->correctionData->in_Y_X0Y)
hv_in_Y_X0Y.Append(rangeData);
HTuple hv_in_Z_X0Y;
for (auto rangeData : data->correctionData->in_Z_X0Y)
hv_in_Z_X0Y.Append(rangeData);
HTuple hv_in_Z_X0Y_Value;
for (auto rangeData : data->correctionData->in_Z_X0Y_Value)
hv_in_Z_X0Y_Value.Append(rangeData);
#pragma endregion
#pragma region XOZ_DEFINE
HTuple hv_in_X_X0Z;
for (auto rangeData : data->correctionData->in_X_X0Z)
hv_in_X_X0Z.Append(rangeData);
HTuple hv_in_Y_X0Z;
for (auto rangeData : data->correctionData->in_Y_X0Z)
hv_in_Y_X0Z.Append(rangeData);
HTuple hv_in_Z_X0Z;
for (auto rangeData : data->correctionData->in_Z_X0Z)
hv_in_Z_X0Z.Append(rangeData);
HTuple hv_in_Y_X0Z_Value;
for (auto rangeData : data->correctionData->in_Y_X0Z_Value)
hv_in_Y_X0Z_Value.Append(rangeData);
#pragma endregion
#pragma region YOZ_DEFINE
HTuple hv_in_X_Y0Z;
for (auto rangeData : data->correctionData->in_X_Y0Z)
hv_in_X_Y0Z.Append(rangeData);
HTuple hv_in_Y_Y0Z;
for (auto rangeData : data->correctionData->in_Y_Y0Z)
hv_in_Y_Y0Z.Append(rangeData);
HTuple hv_in_Z_Y0Z;
for (auto rangeData : data->correctionData->in_Z_Y0Z)
hv_in_Z_Y0Z.Append(rangeData);
HTuple hv_in_X_Y0Z_Value;
for (auto rangeData : data->correctionData->in_X_Y0Z_Value)
hv_in_X_Y0Z_Value.Append(rangeData);
#pragma endregion
HTuple hv_out_Origin;
HTuple hv_out_Result_X;
HTuple hv_out_Result_Y;
HTuple hv_out_Result_Z;
HTuple hv_out_AngleZX;
HTuple hv_out_AngleYZ;
HTuple hv_out_AngleXY;
HTuple hv_out_Flag;
halcon_Correction(
hv_in_X_X0Y, hv_in_Y_X0Y, hv_in_Z_X0Y, hv_in_Z_X0Y_Value,
hv_in_X_X0Z, hv_in_Y_X0Z, hv_in_Z_X0Z, hv_in_Y_X0Z_Value,
hv_in_X_Y0Z, hv_in_Y_Y0Z, hv_in_Z_Y0Z, hv_in_X_Y0Z_Value,
&hv_out_Origin,&hv_out_Result_X,&hv_out_Result_Y,&hv_out_Result_Z,
&hv_out_AngleZX,&hv_out_AngleYZ,&hv_out_AngleXY,&hv_out_Flag);
int ok_Flag = 0;
vector<double>out_Origin;
vector<double>out_Result_X;
vector<double>out_Result_Y;
vector<double>out_Result_Z;
double out_AngleZX;
double out_AngleYZ;
double out_AngleXY;
if(hv_out_Flag.Length()==1)
if (hv_out_Flag[0].D()== 1)
{
if (hv_out_Origin.Length() == 3)
{
out_Origin = { hv_out_Origin[0].D(),hv_out_Origin[1].D(), hv_out_Origin[2].D() };
ok_Flag++;
}
if (hv_out_Result_X.Length() == 3)
{
out_Result_X = { hv_out_Result_X[0].D(),hv_out_Result_X[1].D(), hv_out_Result_X[2].D() };
ok_Flag++;
}
if (hv_out_Result_Y.Length() == 3)
{
out_Result_Y = { hv_out_Result_Y[0].D(),hv_out_Result_Y[1].D(), hv_out_Result_Y[2].D() };
ok_Flag++;
}
if (hv_out_Result_Z.Length() == 3)
{
out_Result_Z = { hv_out_Result_Z[0].D(),hv_out_Result_Z[1].D(), hv_out_Result_Z[2].D() };
ok_Flag++;
}
if (hv_out_AngleZX.Length() == 1)
{
out_AngleZX = hv_out_AngleZX[0].D();
ok_Flag++;
}
if (hv_out_AngleYZ.Length() == 1)
{
out_AngleYZ = hv_out_AngleYZ[0].D();
ok_Flag++;
}
if (hv_out_AngleXY.Length() == 1)
{
out_AngleXY = hv_out_AngleXY[0].D();
ok_Flag++;
}
}
else
{
std::cout << "error";
}
if (ok_Flag != 7)
{
//qDebug()
return;
}
//originX
_triggerManager->sendFinsMsg("write_short_310_" + QString::number(out_Origin[0] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_311_" + QString::number(abs(static_cast<int>(out_Origin[0]))));
double pvalue = out_Origin[0] - static_cast<int>(out_Origin[0]);
_triggerManager->sendFinsMsg("write_short_312_" + QString::number(abs(pvalue* pValueBounus)));
//originY
_triggerManager->sendFinsMsg("write_short_313_" + QString::number(out_Origin[1] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_314_" + QString::number(abs(static_cast<int>(out_Origin[1]))));
pvalue = out_Origin[1] - static_cast<int>(out_Origin[1]);
_triggerManager->sendFinsMsg("write_short_315_" + QString::number(abs(pvalue * pValueBounus)));
//originZ
_triggerManager->sendFinsMsg("write_short_316_" + QString::number(out_Origin[2] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_317_" + QString::number(abs(static_cast<int>(out_Origin[2]))));
pvalue = out_Origin[2] - static_cast<int>(out_Origin[2]);
_triggerManager->sendFinsMsg("write_short_318_" + QString::number(abs(pvalue * pValueBounus)));
//ResultX1
_triggerManager->sendFinsMsg("write_short_319_" + QString::number(out_Result_X[0] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_320_" + QString::number(abs(static_cast<int>(out_Result_X[0]))));
pvalue = out_Result_X[0] - static_cast<int>(out_Result_X[0]);
_triggerManager->sendFinsMsg("write_short_321_" + QString::number(abs(pvalue * pValueBounus)));
//ResultX2
_triggerManager->sendFinsMsg("write_short_322_" + QString::number(out_Result_X[1] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_323_" + QString::number(abs(static_cast<int>(out_Result_X[1]))));
pvalue = out_Result_X[1] - static_cast<int>(out_Result_X[1]);
_triggerManager->sendFinsMsg("write_short_324_" + QString::number(abs(pvalue * pValueBounus)));
//ResultX3
_triggerManager->sendFinsMsg("write_short_325_" + QString::number(out_Result_X[2] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_326_" + QString::number(abs(static_cast<int>(out_Result_X[2]))));
pvalue = out_Result_X[2] - static_cast<int>(out_Result_X[2]);
_triggerManager->sendFinsMsg("write_short_327_" + QString::number(abs(pvalue * pValueBounus)));
//ResultY1
_triggerManager->sendFinsMsg("write_short_328_" + QString::number(out_Result_Y[0] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_329_" + QString::number(abs(static_cast<int>(out_Result_Y[0]))));
pvalue = out_Result_Y[0] - static_cast<int>(out_Result_Y[0]);
_triggerManager->sendFinsMsg("write_short_330_" + QString::number(abs(pvalue * pValueBounus)));
//ResultY2
_triggerManager->sendFinsMsg("write_short_331_" + QString::number(out_Result_Y[1] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_332_" + QString::number(abs(static_cast<int>(out_Result_Y[1]))));
pvalue = out_Result_Y[1] - static_cast<int>(out_Result_Y[1]);
_triggerManager->sendFinsMsg("write_short_333_" + QString::number(abs(pvalue * pValueBounus)));
//ResultY3
_triggerManager->sendFinsMsg("write_short_334_" + QString::number(out_Result_Y[2] < 0 ? 2 : 1));
_triggerManager->sendFinsMsg("write_short_335_" + QString::number(abs(static_cast<int>(out_Result_Y[2]))));
pvalue = out_Result_Y[2] - static_cast<int>(out_Result_Y[2]);
_triggerManager->sendFinsMsg("write_short_336_" + QString::number(abs(pvalue * pValueBounus)));
}
void algoThread::ALGO_Inspection(std::shared_ptr <detData> data)
{
if (data->imgs.size() < 1)
{
qDebug() << __FUNCDNAME__ << __LINE__ << "camera Mat size is Error!";
return;
}
//hv_in_Parameter
//[0]-产品种类; 1A正面 2A反面 3B正面 4C正面
//[1]-图像序号第一位;
//[2]-图像序号第二位;
//[3]-3d相机精度(mm);
//[4]-ping针偏移判NG阈值(mm);
//[5]-切图存图开关
#pragma region halcon变量定义
//测量
HObject ho_in_Image;
HTuple hv_in_ShapePath;
HTuple hv_in_Parameter;
HTuple hv_out_Pings_X;
HTuple hv_out_Pings_Y;
HTuple hv_out_NG_Pings_X;
HTuple hv_out_NG_Pings_Y;
HTuple hv_out_Pings_Num;
HTuple hv_out_NG_Pings_Num;
HTuple hv_out_Flag_INS;
//ROI
HTuple hv_out_ROI_Value;
HTuple hv_out_Flag_ROI;
#pragma endregion
cv::Mat mat = cv::imread("C://NHMJDHNN78474-5_1-ASR1006X20240320-150822.BMP", -1);
ho_in_Image=simpleAlgo::MatToHObject(mat);
hv_in_Parameter.Append(3);
hv_in_Parameter.Append(5);
hv_in_Parameter.Append(1);
hv_in_Parameter.Append(0.0135);
hv_in_Parameter.Append(0.2);
hv_in_Parameter.Append(2);
hv_in_ShapePath = "./halconModel";
Pings_Inspection(ho_in_Image, hv_in_ShapePath, hv_in_Parameter, &hv_out_Pings_X,
&hv_out_Pings_Y, &hv_out_NG_Pings_X, &hv_out_NG_Pings_Y, &hv_out_Pings_Num,
&hv_out_NG_Pings_Num, &hv_out_Flag_INS);
Pings_ROI(ho_in_Image, hv_in_ShapePath, hv_in_Parameter, &hv_out_ROI_Value, &hv_out_Flag_ROI);
vector<Rect>Result;
for (int i = 0; i < hv_out_ROI_Value.Length()/4;i++)
{
Result.push_back(
cv::Rect(
hv_out_ROI_Value[i * 4 +1].D(),
hv_out_ROI_Value[i * 4].D(),
hv_out_ROI_Value[i * 4 +3].D() - hv_out_ROI_Value[i * 4 + 1].D(),
hv_out_ROI_Value[i * 4 +2].D() - hv_out_ROI_Value[i * 4].D()
));
}
cv::Mat Paint;
cvtColor(mat, Paint, COLOR_GRAY2BGR);
rectangle(Paint, Result[0], cv::Scalar(0, 0, 255), 4);
_sleep(100);
}
void algoThread::Camera1_Algo(std::shared_ptr <detData> data)
{
auto start_time = std::chrono::high_resolution_clock::now();
if (data->imgs.size() < 1)
{
qDebug() << __FUNCDNAME__ << __LINE__ << "camera Mat size is Error!";
return;
}
///////////////////取图///声明/////////////////////
ngNoteCls Note;
cv::Mat src;
cv::Mat Paint;
int CCD1OK = 1;
double CCD1height = -1;
double dmCodeWidth = 0, dmCodeHeight = 0;
double pixAccX = 0.013502052, pixAccY = 0.014005423575;
double camera1Width = 1, camera1Height = 2;
QFuture<void> future1;
if (data->imgs.size() == 1)
{
src = data->imgs[0];
if (Paint.channels() == 1)
cv::cvtColor(src, Paint, cv::COLOR_GRAY2BGR);
else
src.copyTo(Paint);
}
//}
if (CCD1OK == 2)
cv::putText(Paint, "NG", cv::Point(150, 600), 1, 10, cv::Scalar(0, 0, 255), 30);
else
cv::putText(Paint, "OK", cv::Point(150, 600), 1, 10, cv::Scalar(0, 255, 0), 30);
///////////////////无SN阻塞///////////////////////
//if (!data->SNcode.compare(snDatas->snErrorsnError))
// data->SNcode = snDatas->waitForSn(data->timeCode);
cv::putText(Paint, data->SNcode, cv::Point(150, 800), 1, 10, cv::Scalar(0, 255, 0), 10);
/////////////////////SQL////////////////////////
data->sqlVec.push_back({ "Camera1Result", CCD1OK });
data->sqlVec.push_back({ "Camera1_Width", camera1Width });
data->sqlVec.push_back({ "Camera1_Height", camera1Height });
////////////////////结果保存//////////////////
cv::resize(Paint, Paint, cv::Size(Paint.cols / 2, Paint.rows / 2));
data->resultImgs.push_back(Paint);
//////////////CSV/////////////////////////////
string OKNG("OK");
if (CCD1OK == 2)OKNG = "NG";
qDebug() << "[Debug]algo1 end:" << QString::fromStdString(data->SNcode);
std::cout << "algo1 end:" << QString::fromStdString(data->SNcode).toStdString() << endl;
}