1101 lines
36 KiB
C++
1101 lines
36 KiB
C++
#include <algorithmThread.h>
|
|
#include <ReadBarcode.h>
|
|
#include "camera_thread.h"
|
|
#include "myiothread.h"
|
|
#include "FrontendBackendBridge.h"
|
|
#include <myTools.h>
|
|
#include <algo.h>
|
|
bool showOk = true;//显示ok缺陷的框
|
|
std::string fileSavePath("D://CCD//");
|
|
//////////////////////
|
|
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);
|
|
}
|
|
/////////////////////ALGOTHREAD/////////////////////////
|
|
bool algoThread::addDetTask(detData* data)
|
|
{
|
|
detQueueMutex.lock();
|
|
detQueue.append(data);
|
|
detQueueMutex.unlock();
|
|
this->start();
|
|
return false;
|
|
}
|
|
bool algoThread::waitForImg(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();
|
|
detData* data = detQueue.dequeue();//取出数据
|
|
detQueueMutex.unlock();
|
|
if (waitForImg(data) == false)
|
|
{
|
|
qDebug() << "取图失败";
|
|
cout << "get img err" << endl;
|
|
break;
|
|
}
|
|
oriSaveThread->saveOriImg(data);//保存原图
|
|
bridge.front.showImg("Camera", data->imgs[0], data->oriShowIndex);//显示原图
|
|
int threadId = data->algoThreadIndex;//获取线程id
|
|
switch (threadId)
|
|
{
|
|
case 0:
|
|
_25D_1_Algo(data);
|
|
break;
|
|
case 1:
|
|
_25D_2_Algo(data);
|
|
break;
|
|
}
|
|
if (data->resultImgs.size() > 0)
|
|
{
|
|
for (int cnt = 0; cnt < data->resultImgs.size(); cnt++)
|
|
{
|
|
bridge.front.showImg("Algorithm", data->resultImgs[cnt], data->oriShowIndex + cnt);//显示原图
|
|
}
|
|
resSaveThread->saveResImg(data);//保存结果图
|
|
}
|
|
if (!data->SNcode.compare(snDatas->snErrorsnError))//无sn阻塞
|
|
data->SNcode = snDatas->waitForSn(data->timeCode);
|
|
//cout << "algoEnd" << data->algoThreadIndex;
|
|
sqlDataStruct sqlDataStruct;//定义sql数据
|
|
sqlDataStruct.SN = data->SNcode;//
|
|
for (auto sqlData : data->sqlVec)//将算法中的数据导入到数据结构中
|
|
sqlDataStruct.dataVec.push_back(sql->sqlDatasInit(sqlData.first, sqlData.second));
|
|
sql->addData(sqlDataStruct);//将数据插入数据库
|
|
//delete data;
|
|
detDataController* dController = data->dController;
|
|
data->dController->deleteDetData(data->timeCode);
|
|
}
|
|
QThread::msleep(10);
|
|
}
|
|
}
|
|
void algoThread::_25D_1_Algo(detData* data)
|
|
{
|
|
if (data->imgs.size() < 6)
|
|
{
|
|
qDebug() << __FUNCDNAME__ << __LINE__ << "camera Mat size is Error!";
|
|
return;
|
|
}
|
|
///////////////////取图///声明/////////////////////
|
|
ngNoteCls Note;
|
|
|
|
cv::Mat SprfSpecularReflectionImage = data->imgs[0];
|
|
cv::Mat SprfDiffuseReflectionImage = data->imgs[1];
|
|
cv::Mat SprfShapeImage1 = data->imgs[2];
|
|
cv::Mat SprfShapeImage2 = data->imgs[3];
|
|
cv::Mat SprfGlossRatioImage = data->imgs[4];
|
|
cv::Mat SprfNormalImage = data->imgs[5];
|
|
|
|
cv::Mat Paint;
|
|
if (SprfGlossRatioImage.channels() == 1)
|
|
{
|
|
cv::cvtColor(SprfGlossRatioImage, Paint, cv::COLOR_GRAY2BGR);
|
|
}
|
|
int CCD1OK = 1;
|
|
double CCD1height = -1;
|
|
double dmCodeWidth = 0, dmCodeHeight = 0;
|
|
double pixAccX = bridge.back.json.PixelAccuracy.getData("_25D_1_X");
|
|
double pixAccY = bridge.back.json.PixelAccuracy.getData("_25D_1_Y");
|
|
cv::Point qrPos;
|
|
Rect qrRect;
|
|
////////////////算法///////////////////////////////
|
|
if (data->skip[0] != 1)
|
|
{
|
|
HObject ho_Image=simpleAlgo::MatToHObject(SprfShapeImage1);
|
|
HTuple hv_Out_Mean;
|
|
HTuple hv_Out_Max;
|
|
HTuple hv_Out_Min;
|
|
HTuple hv_Out_Line1;
|
|
HTuple hv_Out_Line2;
|
|
HTuple hv_Make;
|
|
_952_15_Distance(ho_Image, &hv_Out_Mean, &hv_Out_Max, &hv_Out_Min, &hv_Out_Line1, &hv_Out_Line2, &hv_Make);
|
|
if (hv_Make.D() != -1)
|
|
{
|
|
line(Paint,
|
|
cv::Point(hv_Out_Line1[1].D(), hv_Out_Line1[0].D()),
|
|
cv::Point(hv_Out_Line1[3].D(), hv_Out_Line1[2].D()),
|
|
Scalar(0, 255, 0), 1);
|
|
line(Paint,
|
|
cv::Point(hv_Out_Line2[1].D(), hv_Out_Line2[0].D()),
|
|
cv::Point(hv_Out_Line2[3].D(), hv_Out_Line2[2].D()),
|
|
Scalar(0, 255, 0), 1);
|
|
cv::putText(Paint, "hv_Out_Max:" + to_string(hv_Out_Max.D()*0.03), cv::Point(100, 100), 1, 10, Scalar(0, 255, 0), 5);
|
|
}
|
|
}
|
|
#if 0
|
|
/////////二维码位置屏蔽
|
|
avoidArea avoidA;
|
|
avoidA.addArea(SprfShapeImage1Resize, modelPtr->camera1Seg_erWeiMa);
|
|
///////////脏污///////////////////////
|
|
if (data->skip[2] != 1)
|
|
{
|
|
#if 1
|
|
int amount = 0, limit = 1;
|
|
cv::Mat resMat = ~modelPtr->camera1Seg_ZangWu->Evaluate(SprfSpecularReflectionImageResize);
|
|
std::vector<std::vector<cv::Point>>contours;
|
|
cv::findContours(resMat, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
std::vector<rectAndData>paintVec;//flase NG true OK
|
|
for (auto contour : contours)
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
|
|
if (rect.height > 10 &&
|
|
rect.width > 10)
|
|
{
|
|
//amount++;
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
if (defectHeight > 2 || defectWidth > 2)//2mm
|
|
{
|
|
amount++;
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,true) });
|
|
|
|
}
|
|
}
|
|
for (auto& data : paintVec)
|
|
{
|
|
Scalar color;
|
|
if (amount >= limit || data.result == false)//NG
|
|
{
|
|
Note.insertNgData(u8"脏污", data.defectWidth, data.defectHeight);
|
|
color = Scalar(0, 0, 255);
|
|
}
|
|
else//OK
|
|
color = Scalar(0, 255, 0);
|
|
cv::rectangle(Paint, data.rect, color, 2);
|
|
writeSpecificStatement(Paint, L"脏污", data, amount, limit, color);
|
|
|
|
}
|
|
if (amount >= limit)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"脏污NG").c_str()), { 6800,3600 }, Scalar(0, 0, 255), 300);
|
|
CCD1OK = 1;
|
|
}
|
|
#endif
|
|
}
|
|
///////////////凹坑///////////////
|
|
if (data->skip[3] != 1)
|
|
{
|
|
int amount = 0, limit = 1;
|
|
cv::Mat resMat = ~modelPtr->camera1Seg_aoKeng->Evaluate(SprfShapeImage1Resize);
|
|
drawContourOnImage(resMat, SprfShapeImage1Paint);
|
|
std::vector<std::vector<cv::Point>>contours;
|
|
cv::findContours(resMat, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
std::vector<std::vector<cv::Point>>contourForGrayShow;//给灰度值计算
|
|
std::vector<rectAndData>paintVec;//flase NG true OK
|
|
for (auto contour : contours)
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
if (rect.height > 10 &&
|
|
rect.width > 10)
|
|
{
|
|
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
Mat img_cls = simpleAlgo::cutImg2Cls(contour, SprfShapeImage1Resize);
|
|
int res = modelPtr->camera1Cls_aoKeng->Evaluate(img_cls);
|
|
if (defectHeight > 0 || defectWidth > 0)//有就算
|
|
{
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,res,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,res,true) });
|
|
}
|
|
}
|
|
//Paint
|
|
for (auto& data : paintVec)
|
|
{
|
|
Scalar color(0, 255, 0);
|
|
if (data.result == false)//NG
|
|
{
|
|
//0--OK 1--凹坑 2--划痕
|
|
switch (data.badType)
|
|
{
|
|
case 1://凹坑
|
|
Note.insertNgData(u8"壳体凹坑", data.defectWidth, data.defectHeight);
|
|
amount++;
|
|
color = Scalar(0, 0, 255);
|
|
writeSpecificStatement(Paint, L"凹坑", data, amount, limit, color);
|
|
break;
|
|
case 2://划痕
|
|
// Note.insertNgData(u8"壳体划痕", data.first.defectWidth, data.first.defectHeight);
|
|
// writeSpecificStatement(Paint, L"划痕", data, amount, limit, color);
|
|
// color = Scalar(0, 0, 255);
|
|
// forHuaHeng++;
|
|
break;
|
|
}
|
|
}
|
|
cv::rectangle(Paint, data.rect, color, 2);
|
|
}
|
|
|
|
#if GRAY_DISPLAY
|
|
drawContoursOverlap(resMat, contourForGrayShow);//除了容器内的缺陷全部画黑(0
|
|
vector<std::pair<Rect2f, double>> res = grayScaleCalculation(~resMat, SprfShapeImage1Resize);
|
|
for (auto& data : res)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"G:" + to_wstring(data.second))).c_str(),
|
|
cv::Point(data.first.x * 2, data.first.y * 2 - 40), Scalar(0, 0, 255), 15);
|
|
}
|
|
#endif
|
|
if (amount >= limit)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"凹坑NG").c_str()), { 6800,3800 }, Scalar(0, 0, 255), 300);
|
|
CCD1OK = 1;
|
|
}
|
|
}
|
|
///////////////划伤///////////////
|
|
if (data->skip[4] != 1)
|
|
{
|
|
int amount = 0, limit = 5;
|
|
cv::Mat resMat = ~modelPtr->camera1Seg_huaShang->Evaluate(SprfNormalImageResize);
|
|
cv::Mat resMat2 = ~modelPtr->camera1Seg_huaShang->Evaluate(SprfGlossRatioImageResize);
|
|
drawContourOnImage(resMat, SprfNormalImagePaint);
|
|
drawContourOnImage(resMat2, SprfGlossRatioImagePaint);
|
|
//cv::Mat resM = mergeBinaryMats(resMat, resMat2);//融合两张图片中白色的区域
|
|
std::vector<std::vector<cv::Point>>contourForGrayShow;//给灰度值计算
|
|
std::vector<rectAndData>paintVec;//flase NG true OK
|
|
std::vector<rectAndData>paintVec2;//flase NG true OK
|
|
|
|
//将resMat中的缺陷切出给cls检测后放入paintvec中
|
|
camera1HuaHeng(resMat, SprfNormalImage, modelPtr->camera1Cls_huaHeng,
|
|
pixAccX, pixAccY, avoidA,
|
|
paintVec, contourForGrayShow);
|
|
camera1HuaHeng(resMat2, SprfGlossRatioImage, modelPtr->camera1Cls_huaHeng,
|
|
pixAccX, pixAccY, avoidA,
|
|
paintVec2, contourForGrayShow);
|
|
#if 1
|
|
//将paintVec2中的缺陷放入paintVec中,有是否重叠的判读
|
|
for (auto& data : paintVec2)
|
|
{
|
|
bool overLap = false;
|
|
for (auto& data2 : paintVec)
|
|
if (simpleAlgo::isRectOverlap(data.rect, data2.rect) == true)//重合
|
|
{
|
|
data2.contour = simpleAlgo::contourPlusContour(data.contour, data2.contour);
|
|
overLap = true;
|
|
if (data.badType > 0)//如果另一张图检测出ng 如果两个都是不同的ng可能有点问题
|
|
data2.badType = data.badType;
|
|
break;
|
|
}
|
|
//不重合
|
|
if (overLap == false)
|
|
paintVec.push_back(data);
|
|
}
|
|
paintVec2.clear();
|
|
#endif
|
|
#if 0
|
|
//将paintVec2中的缺陷放入paintVec中
|
|
for (auto& data : paintVec2)
|
|
{
|
|
paintVec.push_back(data);
|
|
}
|
|
paintVec2.clear();
|
|
#endif
|
|
#if 0
|
|
std::vector<std::vector<cv::Point>>contours1;
|
|
cv::findContours(resMat, contours1, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
std::vector<std::vector<cv::Point>>contours2;
|
|
cv::findContours(resMat, contours2, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
|
|
//0 OK 1凹坑 2脏污 3划痕
|
|
for (auto contour : contours1)//遍历第一张图
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
if (rect.height > 10 && rect.width > 10)
|
|
{
|
|
amount++;
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
Mat forCls = simpleAlgo::cutImg2Cls(contour, SprfNormalImageResize);
|
|
int res = modelPtr->camera1Cls_huaHeng->Evaluate(forCls);
|
|
if (res == 0)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,0,true) });
|
|
else
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,res,false) });
|
|
if (defectHeight > 10 || defectWidth > 10)//10mm
|
|
{
|
|
amount = 10;
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
|
|
contourForGrayShow.push_back(contour);
|
|
}
|
|
}
|
|
for (auto contour : contours2)//遍历第二张图
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
if (rect.height > 10 && rect.width > 10)
|
|
{
|
|
amount++;
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
if (defectHeight > 10 || defectWidth > 10)//10mm
|
|
{
|
|
amount = 10;
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,true) });
|
|
contourForGrayShow.push_back(contour);
|
|
}
|
|
}
|
|
#endif
|
|
//Paint
|
|
for (auto& data : paintVec)
|
|
{
|
|
switch (data.badType)
|
|
{
|
|
case 0://OK
|
|
writeSpecificStatement(Paint, L"clsOk", data, amount, limit, Scalar(0, 255, 0));
|
|
cv::rectangle(Paint, data.rect, Scalar(0, 255, 0), 2);
|
|
break;
|
|
case 1:
|
|
//color = Scalar(0, 0, 255);
|
|
//Note.insertNgData(u8"壳体凹坑", data.defectWidth, data.defectHeight);
|
|
//writeSpecificStatement(Paint, L"凹坑", data, amount, limit, color);
|
|
break;
|
|
case 2:
|
|
//if (max(data.defectHeight, data.defectWidth) > 2)//>2mm
|
|
//{
|
|
// color = Scalar(0, 0, 255);
|
|
// Note.insertNgData(u8"壳体脏污", data.defectWidth, data.defectHeight);
|
|
// writeSpecificStatement(Paint, L"脏污", data, amount, limit, color);
|
|
//}
|
|
//else
|
|
// writeSpecificStatement(Paint, L"脏污OK", data, amount, limit, color);
|
|
break;
|
|
case 3:
|
|
|
|
if (max(data.defectHeight, data.defectWidth) > 10)//>10mm
|
|
{
|
|
Note.insertNgData(u8"壳体划痕", data.defectWidth, data.defectHeight);
|
|
writeSpecificStatement(Paint, L"划痕", data, amount, limit, Scalar(0, 0, 255));
|
|
cv::rectangle(Paint, data.rect, Scalar(0, 0, 255), 2);
|
|
}
|
|
else
|
|
{
|
|
writeSpecificStatement(Paint, L"划痕OK", data, amount, limit, Scalar(0, 255, 0));
|
|
cv::rectangle(Paint, data.rect, Scalar(0, 255, 0), 2);
|
|
}
|
|
amount++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
CCD1OK = 1;
|
|
|
|
|
|
}
|
|
|
|
if (amount >= limit)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"划痕NG").c_str()), { 6800,4000 }, Scalar(0, 0, 255), 300);
|
|
CCD1OK = 1;
|
|
}
|
|
#if GRAY_DISPLAY
|
|
drawContoursOverlap(resMat, contourForGrayShow);//除了容器内的缺陷全部画黑(0
|
|
vector<std::pair<Rect2f, double>> res = grayScaleCalculation(~resMat, SprfNormalImageResize);
|
|
for (auto& data : res)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"G:" + to_wstring(data.second))).c_str(),
|
|
cv::Point(data.first.x * 2, data.first.y * 2 - 40), Scalar(0, 0, 255), 15);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
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({ "_25D1Result", CCD1OK });
|
|
////////////////////结果保存//////////////////
|
|
data->resultImgs.push_back(Paint);
|
|
//data->resultImgs.push_back(SprfSpecularReflectionImagePaint);
|
|
//data->resultImgs.push_back(SprfDiffuseReflectionImagePaint);
|
|
//data->resultImgs.push_back(SprfShapeImage1Paint);
|
|
//data->resultImgs.push_back(SprfShapeImage2Paint);
|
|
//data->resultImgs.push_back(SprfGlossRatioImagePaint);
|
|
//data->resultImgs.push_back(SprfNormalImagePaint);
|
|
//////////////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;
|
|
writeToData_xxxCSVNew(data, OKNG, &Note);
|
|
}
|
|
void algoThread::_25D_2_Algo(detData* data)
|
|
{
|
|
if (data->imgs.size() < 6)
|
|
{
|
|
qDebug() << __FUNCDNAME__ << __LINE__ << "camera Mat size is Error!";
|
|
return;
|
|
}
|
|
///////////////////取图///声明/////////////////////
|
|
ngNoteCls Note;
|
|
|
|
cv::Mat SprfSpecularReflectionImage = data->imgs[0];
|
|
cv::Mat SprfDiffuseReflectionImage = data->imgs[1];
|
|
cv::Mat SprfShapeImage1 = data->imgs[2];
|
|
cv::Mat SprfShapeImage2 = data->imgs[3];
|
|
cv::Mat SprfGlossRatioImage = data->imgs[4];
|
|
cv::Mat SprfNormalImage = data->imgs[5];
|
|
|
|
cv::Mat Paint;
|
|
if (SprfGlossRatioImage.channels() == 1)
|
|
{
|
|
cv::cvtColor(SprfGlossRatioImage, Paint, cv::COLOR_GRAY2BGR);
|
|
}
|
|
int CCD1OK = 1;
|
|
double CCD1height = -1;
|
|
double dmCodeWidth = 0, dmCodeHeight = 0;
|
|
double pixAccX = bridge.back.json.PixelAccuracy.getData("_25D_1_X");
|
|
double pixAccY = bridge.back.json.PixelAccuracy.getData("_25D_1_Y");
|
|
cv::Point qrPos;
|
|
Rect qrRect;
|
|
////////////////算法///////////////////////////////
|
|
if (data->skip[0] != 1)
|
|
{
|
|
HObject ho_Image = simpleAlgo::MatToHObject(SprfShapeImage1);
|
|
HTuple hv_Out_Mean;
|
|
HTuple hv_Out_Max;
|
|
HTuple hv_Out_Min;
|
|
HTuple hv_Out_Line1;
|
|
HTuple hv_Out_Line2;
|
|
HTuple hv_Make;
|
|
_952_15_Distance(ho_Image, &hv_Out_Mean, &hv_Out_Max, &hv_Out_Min, &hv_Out_Line1, &hv_Out_Line2, &hv_Make);
|
|
if (hv_Make.D() != -1)
|
|
{
|
|
line(Paint,
|
|
cv::Point(hv_Out_Line1[1].D(), hv_Out_Line1[0].D()),
|
|
cv::Point(hv_Out_Line1[3].D(), hv_Out_Line1[2].D()),
|
|
Scalar(0, 255, 0), 1);
|
|
line(Paint,
|
|
cv::Point(hv_Out_Line2[1].D(), hv_Out_Line2[0].D()),
|
|
cv::Point(hv_Out_Line2[3].D(), hv_Out_Line2[2].D()),
|
|
Scalar(0, 255, 0), 1);
|
|
cv::putText(Paint, "hv_Out_Max:" + to_string(hv_Out_Max.D()), cv::Point(100, 100), 1, 10, Scalar(0, 255, 0), 5);
|
|
}
|
|
}
|
|
#if 0
|
|
/////////二维码位置屏蔽
|
|
avoidArea avoidA;
|
|
avoidA.addArea(SprfShapeImage1Resize, modelPtr->camera1Seg_erWeiMa);
|
|
///////////脏污///////////////////////
|
|
if (data->skip[2] != 1)
|
|
{
|
|
#if 1
|
|
int amount = 0, limit = 1;
|
|
cv::Mat resMat = ~modelPtr->camera1Seg_ZangWu->Evaluate(SprfSpecularReflectionImageResize);
|
|
std::vector<std::vector<cv::Point>>contours;
|
|
cv::findContours(resMat, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
std::vector<rectAndData>paintVec;//flase NG true OK
|
|
for (auto contour : contours)
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
|
|
if (rect.height > 10 &&
|
|
rect.width > 10)
|
|
{
|
|
//amount++;
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
if (defectHeight > 2 || defectWidth > 2)//2mm
|
|
{
|
|
amount++;
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,true) });
|
|
|
|
}
|
|
}
|
|
for (auto& data : paintVec)
|
|
{
|
|
Scalar color;
|
|
if (amount >= limit || data.result == false)//NG
|
|
{
|
|
Note.insertNgData(u8"脏污", data.defectWidth, data.defectHeight);
|
|
color = Scalar(0, 0, 255);
|
|
}
|
|
else//OK
|
|
color = Scalar(0, 255, 0);
|
|
cv::rectangle(Paint, data.rect, color, 2);
|
|
writeSpecificStatement(Paint, L"脏污", data, amount, limit, color);
|
|
|
|
}
|
|
if (amount >= limit)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"脏污NG").c_str()), { 6800,3600 }, Scalar(0, 0, 255), 300);
|
|
CCD1OK = 1;
|
|
}
|
|
#endif
|
|
}
|
|
///////////////凹坑///////////////
|
|
if (data->skip[3] != 1)
|
|
{
|
|
int amount = 0, limit = 1;
|
|
cv::Mat resMat = ~modelPtr->camera1Seg_aoKeng->Evaluate(SprfShapeImage1Resize);
|
|
drawContourOnImage(resMat, SprfShapeImage1Paint);
|
|
std::vector<std::vector<cv::Point>>contours;
|
|
cv::findContours(resMat, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
std::vector<std::vector<cv::Point>>contourForGrayShow;//给灰度值计算
|
|
std::vector<rectAndData>paintVec;//flase NG true OK
|
|
for (auto contour : contours)
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
if (rect.height > 10 &&
|
|
rect.width > 10)
|
|
{
|
|
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
Mat img_cls = simpleAlgo::cutImg2Cls(contour, SprfShapeImage1Resize);
|
|
int res = modelPtr->camera1Cls_aoKeng->Evaluate(img_cls);
|
|
if (defectHeight > 0 || defectWidth > 0)//有就算
|
|
{
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,res,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,res,true) });
|
|
}
|
|
}
|
|
//Paint
|
|
for (auto& data : paintVec)
|
|
{
|
|
Scalar color(0, 255, 0);
|
|
if (data.result == false)//NG
|
|
{
|
|
//0--OK 1--凹坑 2--划痕
|
|
switch (data.badType)
|
|
{
|
|
case 1://凹坑
|
|
Note.insertNgData(u8"壳体凹坑", data.defectWidth, data.defectHeight);
|
|
amount++;
|
|
color = Scalar(0, 0, 255);
|
|
writeSpecificStatement(Paint, L"凹坑", data, amount, limit, color);
|
|
break;
|
|
case 2://划痕
|
|
// Note.insertNgData(u8"壳体划痕", data.first.defectWidth, data.first.defectHeight);
|
|
// writeSpecificStatement(Paint, L"划痕", data, amount, limit, color);
|
|
// color = Scalar(0, 0, 255);
|
|
// forHuaHeng++;
|
|
break;
|
|
}
|
|
}
|
|
cv::rectangle(Paint, data.rect, color, 2);
|
|
}
|
|
|
|
#if GRAY_DISPLAY
|
|
drawContoursOverlap(resMat, contourForGrayShow);//除了容器内的缺陷全部画黑(0
|
|
vector<std::pair<Rect2f, double>> res = grayScaleCalculation(~resMat, SprfShapeImage1Resize);
|
|
for (auto& data : res)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"G:" + to_wstring(data.second))).c_str(),
|
|
cv::Point(data.first.x * 2, data.first.y * 2 - 40), Scalar(0, 0, 255), 15);
|
|
}
|
|
#endif
|
|
if (amount >= limit)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"凹坑NG").c_str()), { 6800,3800 }, Scalar(0, 0, 255), 300);
|
|
CCD1OK = 1;
|
|
}
|
|
}
|
|
///////////////划伤///////////////
|
|
if (data->skip[4] != 1)
|
|
{
|
|
int amount = 0, limit = 5;
|
|
cv::Mat resMat = ~modelPtr->camera1Seg_huaShang->Evaluate(SprfNormalImageResize);
|
|
cv::Mat resMat2 = ~modelPtr->camera1Seg_huaShang->Evaluate(SprfGlossRatioImageResize);
|
|
drawContourOnImage(resMat, SprfNormalImagePaint);
|
|
drawContourOnImage(resMat2, SprfGlossRatioImagePaint);
|
|
//cv::Mat resM = mergeBinaryMats(resMat, resMat2);//融合两张图片中白色的区域
|
|
std::vector<std::vector<cv::Point>>contourForGrayShow;//给灰度值计算
|
|
std::vector<rectAndData>paintVec;//flase NG true OK
|
|
std::vector<rectAndData>paintVec2;//flase NG true OK
|
|
|
|
//将resMat中的缺陷切出给cls检测后放入paintvec中
|
|
camera1HuaHeng(resMat, SprfNormalImage, modelPtr->camera1Cls_huaHeng,
|
|
pixAccX, pixAccY, avoidA,
|
|
paintVec, contourForGrayShow);
|
|
camera1HuaHeng(resMat2, SprfGlossRatioImage, modelPtr->camera1Cls_huaHeng,
|
|
pixAccX, pixAccY, avoidA,
|
|
paintVec2, contourForGrayShow);
|
|
#if 1
|
|
//将paintVec2中的缺陷放入paintVec中,有是否重叠的判读
|
|
for (auto& data : paintVec2)
|
|
{
|
|
bool overLap = false;
|
|
for (auto& data2 : paintVec)
|
|
if (simpleAlgo::isRectOverlap(data.rect, data2.rect) == true)//重合
|
|
{
|
|
data2.contour = simpleAlgo::contourPlusContour(data.contour, data2.contour);
|
|
overLap = true;
|
|
if (data.badType > 0)//如果另一张图检测出ng 如果两个都是不同的ng可能有点问题
|
|
data2.badType = data.badType;
|
|
break;
|
|
}
|
|
//不重合
|
|
if (overLap == false)
|
|
paintVec.push_back(data);
|
|
}
|
|
paintVec2.clear();
|
|
#endif
|
|
#if 0
|
|
//将paintVec2中的缺陷放入paintVec中
|
|
for (auto& data : paintVec2)
|
|
{
|
|
paintVec.push_back(data);
|
|
}
|
|
paintVec2.clear();
|
|
#endif
|
|
#if 0
|
|
std::vector<std::vector<cv::Point>>contours1;
|
|
cv::findContours(resMat, contours1, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
std::vector<std::vector<cv::Point>>contours2;
|
|
cv::findContours(resMat, contours2, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
|
|
|
|
//0 OK 1凹坑 2脏污 3划痕
|
|
for (auto contour : contours1)//遍历第一张图
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
if (rect.height > 10 && rect.width > 10)
|
|
{
|
|
amount++;
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
Mat forCls = simpleAlgo::cutImg2Cls(contour, SprfNormalImageResize);
|
|
int res = modelPtr->camera1Cls_huaHeng->Evaluate(forCls);
|
|
if (res == 0)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,0,true) });
|
|
else
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,res,false) });
|
|
if (defectHeight > 10 || defectWidth > 10)//10mm
|
|
{
|
|
amount = 10;
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
|
|
contourForGrayShow.push_back(contour);
|
|
}
|
|
}
|
|
for (auto contour : contours2)//遍历第二张图
|
|
{
|
|
cv::Rect rect = cv::boundingRect(contour);
|
|
double defectHeight = rect.height * pixAccY * 2;
|
|
double defectWidth = rect.width * pixAccX * 2;
|
|
int rectCenterX = 0, rectCenterY = 0;
|
|
rectCenterX = rect.x + rect.width / 2;
|
|
rectCenterY = rect.y + rect.height / 2;
|
|
if (avoidA.checkOverLap(Point(rectCenterX, rectCenterY)) == true)//有与二维码重叠
|
|
continue;
|
|
if (rect.height > 10 && rect.width > 10)
|
|
{
|
|
amount++;
|
|
rect.x *= 2;
|
|
rect.y *= 2;
|
|
rect.width *= 2;
|
|
rect.height *= 2;
|
|
if (defectHeight > 10 || defectWidth > 10)//10mm
|
|
{
|
|
amount = 10;
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,false) });
|
|
}
|
|
else //if (showOk == true)
|
|
paintVec.push_back({ rectAndData(rect,defectHeight,defectWidth,true) });
|
|
contourForGrayShow.push_back(contour);
|
|
}
|
|
}
|
|
#endif
|
|
//Paint
|
|
for (auto& data : paintVec)
|
|
{
|
|
switch (data.badType)
|
|
{
|
|
case 0://OK
|
|
writeSpecificStatement(Paint, L"clsOk", data, amount, limit, Scalar(0, 255, 0));
|
|
cv::rectangle(Paint, data.rect, Scalar(0, 255, 0), 2);
|
|
break;
|
|
case 1:
|
|
//color = Scalar(0, 0, 255);
|
|
//Note.insertNgData(u8"壳体凹坑", data.defectWidth, data.defectHeight);
|
|
//writeSpecificStatement(Paint, L"凹坑", data, amount, limit, color);
|
|
break;
|
|
case 2:
|
|
//if (max(data.defectHeight, data.defectWidth) > 2)//>2mm
|
|
//{
|
|
// color = Scalar(0, 0, 255);
|
|
// Note.insertNgData(u8"壳体脏污", data.defectWidth, data.defectHeight);
|
|
// writeSpecificStatement(Paint, L"脏污", data, amount, limit, color);
|
|
//}
|
|
//else
|
|
// writeSpecificStatement(Paint, L"脏污OK", data, amount, limit, color);
|
|
break;
|
|
case 3:
|
|
|
|
if (max(data.defectHeight, data.defectWidth) > 10)//>10mm
|
|
{
|
|
Note.insertNgData(u8"壳体划痕", data.defectWidth, data.defectHeight);
|
|
writeSpecificStatement(Paint, L"划痕", data, amount, limit, Scalar(0, 0, 255));
|
|
cv::rectangle(Paint, data.rect, Scalar(0, 0, 255), 2);
|
|
}
|
|
else
|
|
{
|
|
writeSpecificStatement(Paint, L"划痕OK", data, amount, limit, Scalar(0, 255, 0));
|
|
cv::rectangle(Paint, data.rect, Scalar(0, 255, 0), 2);
|
|
}
|
|
amount++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
CCD1OK = 1;
|
|
|
|
|
|
}
|
|
|
|
if (amount >= limit)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"划痕NG").c_str()), { 6800,4000 }, Scalar(0, 0, 255), 300);
|
|
CCD1OK = 1;
|
|
}
|
|
#if GRAY_DISPLAY
|
|
drawContoursOverlap(resMat, contourForGrayShow);//除了容器内的缺陷全部画黑(0
|
|
vector<std::pair<Rect2f, double>> res = grayScaleCalculation(~resMat, SprfNormalImageResize);
|
|
for (auto& data : res)
|
|
{
|
|
putTextHusky(Paint, (WString2String(L"G:" + to_wstring(data.second))).c_str(),
|
|
cv::Point(data.first.x * 2, data.first.y * 2 - 40), Scalar(0, 0, 255), 15);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
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({ "batteryHeight", (int)(CCD1height * 1000) });
|
|
////////////////////结果保存//////////////////
|
|
data->resultImgs.push_back(Paint);
|
|
//data->resultImgs.push_back(SprfSpecularReflectionImagePaint);
|
|
//data->resultImgs.push_back(SprfDiffuseReflectionImagePaint);
|
|
//data->resultImgs.push_back(SprfShapeImage1Paint);
|
|
//data->resultImgs.push_back(SprfShapeImage2Paint);
|
|
//data->resultImgs.push_back(SprfGlossRatioImagePaint);
|
|
//data->resultImgs.push_back(SprfNormalImagePaint);
|
|
//////////////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;
|
|
writeToData_xxxCSVNew(data, OKNG, &Note);
|
|
} |