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.

320 lines
12 KiB
C++

4 years ago
#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();
// 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 > 25)
{
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;
4 years ago
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_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;
}