You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
12 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "algEg.h"
#include "ValveDetector.h"
#include "qmap.h"
#include "qtcvutils.h"
#include "BatchTest4Alg.h"
#include "modelVerfication.h"
#pragma execution_character_set("utf-8")
using namespace luffy_base;
static QMap <QString, InputParam*> listModes;
algEg::algEg()
{
luffy_triangle::createNewTrigValue(360);
luffy_triangle::createNewTrigValue(3600);
}
algEg::~algEg()
{
}
const int nAngleMax = 3600;//将角度精确到0.1度 把整个圆分成3600份
bool algEg::Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm)
{
int64 nStart = cv::getTickCount();qDebug() << "start alg valve detect";
ValveDetector m_objDetect;
InputParam paramInput = { 0 };
OutputParam paramOutput;
paramInput.nMaxAngle = nAngleMax;
paramInput.dScoreThres = lpAlgorithm->GetParamValue("scoreTh", LP_DOUBLE).toDouble();//匹配分数阈值 低于该阈值 表示气门芯寻找失败
paramInput.nBarScore = lpAlgorithm->GetParamValue("barScore", LP_INT).toDouble();//辐条分数
paramInput.nBarScore = paramInput.nBarScore > 50 ? paramInput.nBarScore : 50;
paramInput.withinOffset = lpAlgorithm->GetParamValue("withinOffset", LP_INT).toInt();
paramInput.barNum = lpAlgorithm->GetParamValue("barNum", LP_INT).toInt();
paramInput.flagCircle = lpAlgorithm->GetParamValue("flagCircle", LP_INT).toInt();
paramInput.roi = lpAlgorithm->GetParamValue("cirlceArea", LP_ROI).value<LP_DETECTOR_ROI_DATA>();
paramInput.cMatchScore = lpAlgorithm->GetParamValue("cMatchScore", LP_DOUBLE).toDouble();
paramInput.wheelType = lpAlgorithm->GetParamValue("wheelType", LP_INT).toInt();
paramInput.backgroundThresh = lpAlgorithm->GetParamValue("backgroundThresh", LP_INT).toInt();
paramInput.nValveOffset = lpAlgorithm->GetParamValue("valveOffset", LP_INT).toInt();//获取气门芯标定位置在圆心坐标系中的角度偏移值
paramInput.nStartOffset = lpAlgorithm->GetParamValue("startOffset", LP_INT).toInt();
paramInput.fValveWidth = lpAlgorithm->GetParamValue("valveWidth", LP_DOUBLE).toDouble();
paramInput.fValveDis = lpAlgorithm->GetParamValue("valveDis", LP_DOUBLE).toDouble();
paramInput.fStartDis = lpAlgorithm->GetParamValue("startDis", LP_DOUBLE).toDouble();//标定时标定点的圆心坐标与轮毂中心的坐标距离
paramOutput.bIsFind = false;
paramOutput.dScore = 0;
paramOutput.showMatchScore = -1;
paramOutput.dAngle = 361;
paramOutput.nErrorType = 0;
Mat mask;
Mat gray;
Mat centerRoi = lpAlgorithm->GetParamValue("centerRoi", LP_MAT).value<cv::Mat>();
if (!lpTask->GetTaskInfo()->detectImg.empty()) {
luffy_imageProc::createImage(lpTask->GetTaskInfo()->detectImg, gray, luffy_imageProc::emCreateGray);
qDebug() << "luffy_imageProc::createImage";
}
if (gray.empty()) {
paramOutput.nErrorType += 1;
qWarning() << "valve detect, gray is empty";
return false;
}
luffy_imageProc::createImage(gray, mask, luffy_imageProc::emCreateColor);
QString strObj = paramInput.strObj = lpTask->GetTaskInfo()->strName;
bool bExist = true;
if (strObj.isEmpty()) {
bExist = false;
paramOutput.nErrorType += 2;
}
if (!centerRoi.empty()) {
qDebug() << "valve detection: creating CenterRoi";
luffy_imageProc::createImage(centerRoi, paramInput.centerRoi, luffy_imageProc::emCreateGray);
}
else {
qWarning() << "valve detection: fail to get CenterRoi";
bExist = false;
}
//保护 防止越界
QPointF pt = lpAlgorithm->GetParamValue("center", LP_POINTF).toPointF();
if (pt.x() > gray.size().width||pt.y()>gray.size().height)
{
qWarning() << "center point big ";
return false;
}
// add original center
paramInput.originalPoint = Point2f(pt.x(), pt.y());
paramInput.nCenterAlg = lpAlgorithm->GetParamValue("centerAlg", LP_INT).toInt();
double centeroffset = lpAlgorithm->GetParamValue("centerOffset", LP_INT).toInt();
// add background
paramInput.backGround = lpAlgorithm->GetParamValue("background", LP_MAT).value<cv::Mat>();
luffy_imageProc::createImage(paramInput.backGround, paramInput.backGround, luffy_imageProc::emCreateGray);
Mat rstMat;
if (bExist)
{
qDebug() << "valve detection: found CenterRoi, trying to get the center points";
paramInput.ptCenter = m_objDetect.getCenterPoints(gray, centerRoi, paramInput, Point(pt.x(), pt.y()), rstMat);
}
if (paramInput.ptCenter.x == 0) {
bExist = false;
qWarning() << "valve detection: center point is null, background is empty";
}
else
{
float dis = luffy_math::disofPoints(paramInput.originalPoint, paramInput.ptCenter);
if (dis > centeroffset)
{
bExist = false;
paramOutput.nErrorType += 8;
paramOutput.flag = 1;
}
}
Mat tmp = lpAlgorithm->GetParamValue("valveTemplate", LP_MAT).value<cv::Mat>();//获取气门芯模板图
Mat barTemp = lpAlgorithm->GetParamValue("barTemplate", LP_MAT).value<cv::Mat>();//获取辐条模板图
Mat weightMat = lpAlgorithm->GetParamValue("weightMat", LP_MAT).value<cv::Mat>();//
Mat baseImage = lpAlgorithm->GetParamValue("baseImage", LP_MAT).value<cv::Mat>();
int num = lpTask->GetSystemInfoValue("station").toInt();
if (num == 2)
{
if (!baseImage.empty() && !weightMat.empty())
{
if (baseImage.size() != weightMat.size())
{
paramOutput.showMatchScore = 366;
paramOutput.nErrorType += 16;
bExist = false;
}
else
{
modelVerfication verObj(20, 127);
verObj.setWeightMat(weightMat);
bool ok = verObj.objectVerification(rstMat, baseImage, paramInput.cMatchScore, 360, paramOutput.showMatchScore);
if (!ok)
{
paramOutput.nErrorType += 16;
bExist = false;
}
}
}
}
if (!tmp.empty() && !barTemp.empty()) {
luffy_imageProc::createImage(tmp, paramInput.imgTemplate, luffy_imageProc::emCreateGray);
luffy_imageProc::createImage(barTemp, paramInput.barTemplate, luffy_imageProc::emCreateGray);
}
else {
if (!barTemp.empty() && paramInput.flagCircle == 1)
{
luffy_imageProc::createImage(barTemp, paramInput.barTemplate, luffy_imageProc::emCreateGray);
}
else
{
qWarning() << "valve detection: can not get template for detecting";
bExist = false;
}
}
if (bExist) {
qDebug() << "valve detection: try finding";
//定位检测
m_objDetect.detect(gray, paramInput, paramOutput, mask);
}
else {
qWarning() << "valve detection: some param is missing";
}
QPointF centerPoint;
centerPoint.setX(paramInput.ptCenter.x);
centerPoint.setY(paramInput.ptCenter.y);
if (lpTask->GetSystemInfoValue("wf_batch_test").toBool()) {
int nAngle = paramOutput.dAngle;
nAngle = nAngle >= paramInput.nMaxAngle ? 0 : nAngle;
int tmpX = paramInput.ptCenter.x + paramInput.fValveDis * luffy_base::luffy_triangle::getCos(paramInput.nMaxAngle, nAngle);
int tmpY = paramInput.ptCenter.y - paramInput.fValveDis * luffy_base::luffy_triangle::getSin(paramInput.nMaxAngle, nAngle);
Point ptValve(tmpX, tmpY);
QString strBase = lpTask->GetSystemInfoValue("folderBase").toString();
QString strFile = lpTask->GetSystemInfoValue("fileName").toString();
bool b = BatchTest4Alg::batchTest(strObj, ptValve, paramOutput.nErrorType, strBase, lpTask->GetTaskInfo()->strImageName);
BatchTest4Alg::saveResult(strObj, b, lpTask->GetTaskInfo()->strImageName, strBase + "\\" + strFile);
}
QVariantMap vMap = lpTask->GetTaskInfo()->property.toMap();
vMap.insert("model_cali", true);
lpTask->GetTaskInfo()->property = vMap;
//paramOutput.dAngleRes = (paramOutput.dAngle - paramInput.nValveOffset) / paramInput.nMaxAngle * 360.0;
if (paramOutput.dAngle >= 3610)
paramOutput.dAngleRes = 3610;
else
paramOutput.dAngleRes = (paramOutput.dAngle - paramInput.nStartOffset) / paramInput.nMaxAngle * 360.0;
paramOutput.dAngleRes = m_objDetect.ruleData(paramOutput.dAngleRes, paramOutput.nErrorType);//随机数
paramOutput.strResultTip = m_objDetect.genResultTip(paramOutput.strResultTip, paramOutput.nErrorType);
paramOutput.dTime = (double)(cv::getTickCount() - nStart) / cv::getTickFrequency() * 1000.0;
m_objDetect.drawResult(mask, paramInput, paramOutput);
//m_objDetect.saveResult(gray, paramInput, paramOutput, strObj);
lpAlgorithm->SetOutParamValue("image", EngineBase::convMat2QImage(mask));
lpAlgorithm->SetOutParamValue("score", paramOutput.dScore);
lpAlgorithm->SetOutParamValue("angle", paramOutput.dAngleRes);
lpAlgorithm->SetOutParamValue("error", paramOutput.nErrorType);
lpAlgorithm->SetOutParamValue("centerPoint", centerPoint);
QString cLetter = paramOutput.strResultTip + "/" + QString::number(paramInput.dScoreThres);
lpAlgorithm->SetOutParamValue("resultTip", cLetter);
QString strImgName = lpTask->GetTaskInfo()->strImageName;
lpAlgorithm->SetOutParamValue("imageName", lpTask->GetTaskInfo()->strImageName);
qDebug() << "finish alg valve detect";
return true;
}
bool algEg::Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm)
{
LP_ALGORITHM_PARAM param1_centeroffset("centerOffset", LP_INT, 25, QObject::tr("圆心偏差距离,单位像素"));
lpAlgorithm->AddParam(&param1_centeroffset, 1);
LP_ALGORITHM_PARAM param1_1("backgroundThresh", LP_INT, 15, QObject::tr("背景差异性阈值"));
lpAlgorithm->AddParam(&param1_1, 1);
LP_ALGORITHM_PARAM param1("scoreTh", LP_DOUBLE, 90, QObject::tr("相似度评价阈值在0~100之间"));
lpAlgorithm->AddParam(&param1, 1);
LP_ALGORITHM_PARAM param2_1("wheelType", LP_INT, 0, QObject::tr("轮毂类型0摩伦1汽轮"));
lpAlgorithm->AddParam(&param2_1, 1);
LP_ALGORITHM_PARAM param3("flagCircle", LP_INT, 0, QObject::tr("0无气门芯标识绑定气门芯标定"));
lpAlgorithm->AddParam(&param3, 1);
LP_ALGORITHM_PARAM param3_1("centerAlg", LP_INT, 0, QObject::tr("是否开启中心定位0关闭1开启"));
lpAlgorithm->AddParam(&param3_1, 1);
LP_ALGORITHM_PARAM param3_2("center", LP_POINTF, QVariant(), QObject::tr("轮毂中心坐标,绑定气门芯标定"));
lpAlgorithm->AddParam(&param3_2, 1);
LP_ALGORITHM_PARAM param3_3("centerRoi", LP_MAT, QVariant(), QObject::tr("轮毂中心模板, 绑定圆定位"));
lpAlgorithm->AddParam(&param3_3, 1);
LP_ALGORITHM_PARAM param3_6("cirlceArea", LP_ROI, QVariant(), QObject::tr("轮毂区域框选"));
lpAlgorithm->AddParam(&param3_6, 1);
LP_ALGORITHM_PARAM param3_7("cMatchScore", LP_DOUBLE, 0.2000, QObject::tr("轮毂型号匹配分值"));
lpAlgorithm->AddParam(&param3_7, 1);
LP_ALGORITHM_PARAM param3_9("barScore", LP_INT, 0, QObject::tr("辐条得分值"));
lpAlgorithm->AddParam(&param3_9, 1);
LP_ALGORITHM_PARAM param13_1("withinOffset", LP_INT, 0, QObject::tr(" "));
lpAlgorithm->AddParam(&param13_1, 1);
LP_ALGORITHM_PARAM param13_2("barNum", LP_INT, 0, QObject::tr(" "));
lpAlgorithm->AddParam(&param13_2, 1);
LP_ALGORITHM_PARAM param13("valveOffset", LP_INT, 0, QObject::tr(" "));
lpAlgorithm->AddParam(&param13, 1);
LP_ALGORITHM_PARAM param_start("startOffset", LP_INT, 0, QObject::tr(" "));
lpAlgorithm->AddParam(&param_start, 1);
LP_ALGORITHM_PARAM param23("valveWidth", LP_DOUBLE, 0, QObject::tr(" "));
lpAlgorithm->AddParam(&param23, 1);
LP_ALGORITHM_PARAM param33("valveDis", LP_DOUBLE, 0, QObject::tr(" "));//标定时气门芯的圆心坐标与轮毂中心的坐标距离
lpAlgorithm->AddParam(&param33, 1);
LP_ALGORITHM_PARAM param_startDis("startDis", LP_DOUBLE, 0, QObject::tr(" "));//标定时标定点的圆心坐标与轮毂中心的坐标距离
lpAlgorithm->AddParam(&param_startDis, 1);
LP_ALGORITHM_PARAM param43("valveTemplate", LP_MAT, QVariant(), QObject::tr(" "));
lpAlgorithm->AddParam(&param43, 1);
LP_ALGORITHM_PARAM param44("barTemplate", LP_MAT, QVariant(), QObject::tr(" "));
lpAlgorithm->AddParam(&param44, 1);
LP_ALGORITHM_PARAM param45("weightMat", LP_MAT, QVariant(), QObject::tr(" "));
lpAlgorithm->AddParam(&param45, 1);
LP_ALGORITHM_PARAM param46("baseImage", LP_MAT, QVariant(), QObject::tr(" "));
lpAlgorithm->AddParam(&param46, 1);
LP_ALGORITHM_PARAM param4_1("background", LP_MAT, QVariant(), QObject::tr(" "));
lpAlgorithm->AddParam(&param4_1, 1);
LP_ALGORITHM_PARAM param6("image", LP_IMAGE);
lpAlgorithm->AddOutParam(&param6, 1);
LP_ALGORITHM_PARAM param7("score", LP_DOUBLE, 0, QObject::tr("相似度得分"));
lpAlgorithm->AddOutParam(&param7, 1);
LP_ALGORITHM_PARAM param8("angle", LP_DOUBLE, 0, QObject::tr("结果角度"));
lpAlgorithm->AddOutParam(&param8, 1);
LP_ALGORITHM_PARAM param9("error", LP_INT, 0, QObject::tr("错误类型"));
lpAlgorithm->AddOutParam(&param9, 1);
LP_ALGORITHM_PARAM param10("resultTip", LP_STRING, 0, QObject::tr("结果提示"));
lpAlgorithm->AddOutParam(&param10, 1);
QString AlgoName = QObject::tr("检测");
QString AlgoName2 = QObject::tr("圆心定位");
QString AlgoName3 = QObject::tr("气门芯标定");
return true;
}
void LpAlgoNewInstance(IAlgo** lppAlgo)
{
*lppAlgo = (IAlgo*)new algEg();
}
bool LpAlgoDeleteInstance()
{
return true;
}