#include "AlgorithmFluorescence.h" #include "ImageCompareModel.h" #include "ImageProcess.h" #include "..\tpMain\IWheelModel.h" #include "ImageCompareModel.h" #include "QVariant" #include "QImage" #include "QDebug" #include "QPixmap" #include "CVUtils.h" #include "qtcvutils.h" #include "qfile.h" #include "qtextstream.h" #include "qiodevice.h" #include "..\tpMain\Result2Ui.h" #pragma execution_character_set("utf-8") using namespace cv; using namespace lp; class CLocalWheel{ public: CLocalWheel() { useHeight = true; useDiameter = true; } cv::Mat img; int height; int diameter; bool useHeight; bool useDiameter; QStringList defectList; }; CAlgorithmFluorescence::CAlgorithmFluorescence(void) { } CAlgorithmFluorescence::~CAlgorithmFluorescence(void) { } //cv::BackgroundSubtractorMOG CAlgorithmFluorescence::bgSubtractor(30, 5, 0.95, false); QString CAlgorithmFluorescence::bestMatch(const QMap* modelMap, CLocalWheel*pLocal, double* pMinDis /*= NULL*/, int minDisNum /*= -1*/) const { double minDis = DBL_MAX; QString bestName; vector disVec(modelMap->size()); int nIndex = 0; if (!modelMap) return bestName; QStringList strDetectModels = pLocal->defectList; while (strDetectModels.size()) { QString strModelName = strDetectModels.takeFirst(); if (!modelMap->contains(strModelName)) continue; QMap::const_iterator itsModel = modelMap->find(strModelName); disVec[nIndex] = DBL_MAX; IWheelModel *pWheel = itsModel.value(); if (!pWheel) break; if (pLocal->useDiameter) { if (abs(pLocal->diameter-pWheel->getDiameter()) >= 15) { nIndex++; continue; } } if (pLocal->useHeight) { if (abs(pLocal->height - pWheel->getThickness()) >= 15) { nIndex++; continue; } } QString name = strModelName;// i.key(); ImageCompareModel* pModel = pWheel->getImageComModel(); if (pModel->getBaseImg().data == NULL) { nIndex++; continue; } pModel->setIsEnableCache(false); double dis = pModel->compare(pLocal->img, NULL, true, 1); disVec[nIndex] = dis; if (dis < minDis && dis != -1) { minDis = dis; bestName = name; } nIndex++; } if (pMinDis) { *pMinDis = minDis; } if (minDisNum > 1) { sort(disVec.begin(), disVec.end()); std::copy_n(disVec.begin(), minDisNum, pMinDis); } return bestName; } int CAlgorithmFluorescence::IImageAnalysis(class IImageObject* pImgObj, TP_ALGORITHM_OPTION* pOpt, class IDetectorEngine* pDE) { QMutexLocker locker(&mutex); qDebug() << "start alg"; double dStart = cv::getTickCount(); Mat matSrc = getImage(pImgObj).clone(); QVariantMap vMap = pImgObj->IVarFromUI().toMap(); long long modelMapPtr = vMap.value("modelMap").toLongLong(); QMap *ptr = (QMap*)modelMapPtr; long long defectListPtr = vMap.value("defectList").toLongLong(); QStringList* strModelListptr = (QStringList*)defectListPtr; QStringList strModelList; if(strModelListptr) strModelList = *(strModelListptr); int th = vMap.value("thickness", -1).toInt(); bool useThickness = vMap.value("useThickness", 0).toBool(); bool useDiameter = vMap.value("useDiameter", 0).toBool(); double dD2H = vMap.value("d2h", -1).toDouble(); int nthreshold = vMap.value("Threshold", 15).toInt(); if (nthreshold <= 0) nthreshold = 15; int IsCutedImg = vMap.value("IsCutImg", 0).toInt();//裁剪后的轮毂图 QVariantMap rltMap; luffy_base::luffyCircle lCircle; static bool bReload = false; Mat matBack = getBackGroundImage(pImgObj, bReload);//获取背景图 Mat matMatch;//装载抠图后的图像 if (IsCutedImg == 0){ if (matSrc.size().height != matBack.size().height || matSrc.size().width != matBack.size().width) { rltMap.insert("error", 0); pImgObj->IVariantMapToUI(rltMap); bReload = true; return 0; } else{ bReload = false; } //imageSegementation(matSrc); matMatch = ImageProcess::findCircleObject(matSrc, matBack, nthreshold/*15*/, &lCircle/* NULL*/); } else{ matMatch = matSrc; } //Mat matMatch = ImageProcess::findCircleObject(matSrc, matBack, 15, NULL/* &lCircle*/); //double dDiameter = dD2H * matMatch.rows; double dDiameter = dD2H * lCircle.fRadius * 2; Result2Ui *pResult = new Result2Ui; CLocalWheel wheelLocal; wheelLocal.defectList = strModelList;// *getDefectListPtr(pImgObj); wheelLocal.img = matMatch.clone(); wheelLocal.height = th; wheelLocal.diameter = dDiameter; wheelLocal.useHeight = useThickness; wheelLocal.useDiameter = useDiameter; if (!matMatch.empty() && ptr && ptr->size() > 0) { vector minDisVec(ptr->size()); qDebug() << "start bestMatch"; QString str = bestMatch(ptr, &wheelLocal, &(minDisVec[0]), minDisVec.size()); qDebug() << "end bestMatch"; pResult->m_strModel = str; pResult->m_dMinDis = minDisVec[0]; if (ptr->contains(str) && ptr->value(str)->getImageComModel()) { ImageCompareModel *pModel = ptr->value(str)->getImageComModel(); double d = pModel->getDisThre(); double dValue = (d - minDisVec[0]) / d * 0.4 + 0.6; pResult->m_dScore = dValue; } } else { } qDebug() << "pull result"; pResult->m_pixSrc = QtCVUtils::cvMatToQPixmap(matSrc);//!>原图像发送值UI 用于保存备份和调试 QImage img = QtCVUtils::cvMatToQImage(matMatch); pResult->m_pixResult = QtCVUtils::cvMatToQPixmap(matMatch);// .scaled(125, 125); pResult->m_dDiameter = dDiameter; pResult->m_dThickness = th; //!>传递检测结果到UI //pImgObj->IDrawImage(img.scaled(300, 300));//!>显示结果图片到UI的第二个窗口上 double dTime = (cv::getTickCount() - dStart) / cv::getTickFrequency(); pResult->m_dRunTime = dTime; long long varRlt = (long long)pResult; rltMap.insert("result", varRlt); pImgObj->IVariantMapToUI(rltMap); qDebug() << "finish alg"; return 1; } QStringList *CAlgorithmFluorescence::getDefectListPtr(class IImageObject *pImgObj) { return nullptr; // IAlgorithmShared *pShare = pImgObj->IGetShared(); // int nMap = pShare->IGetInt("defectList"); // return (QStringList*)nMap; } QMap *CAlgorithmFluorescence::getWheelMapPtr(class IImageObject *pImgObj) { // IAlgorithmShared *pShare = pImgObj->IGetShared(); // if (!pShare) // return nullptr; // int nMap = pShare->IGetInt("modelMap"); // return (QMap*)nMap; return nullptr; } cv::Mat CAlgorithmFluorescence::getImage(class IImageObject *pImgObj) { emTpColorFormat colorFormat = pImgObj->IColorFormat(); int nImageW; int nImageH; int nBitsPerPixel; int nBytesPerLine; BYTE* pImageData = pImgObj->IImageData(nImageW, nImageH, nBitsPerPixel, nBytesPerLine); Mat matSrc; if (TP_COLOR_Y800 != colorFormat) { Mat colorMat = Mat(nImageH, nImageW, CV_8UC4, pImageData, nBytesPerLine); matSrc = getFirstChannel(colorMat); } else { matSrc = Mat(nImageH, nImageW, CV_8UC1, pImageData, nBytesPerLine); } return matSrc; } cv::Mat CAlgorithmFluorescence::getBackGroundImage(class IImageObject *pObj, bool bReLoad) { static Mat matback; if (matback.empty()) { QString filepath = /*getPath(pObj) +*/ ".\\user\\background.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); //matback = cv::imread(filepath.toLatin1().data(), 0); if (matback.empty()) { QString filepath = getPath(pObj) + "\\user\\background_r.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); //matback = cv::imread(filepath.toLatin1().data(), 0); cv::flip(matback, matback, 1); } } else { if (bReLoad) { QString filepath = getPath(pObj) + "\\user\\background.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); if (matback.empty()) { QString filepath = getPath(pObj) + "\\user\\background_r.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); //matback = cv::imread(filepath.toLatin1().data(), 0); cv::flip(matback, matback, 1); } } } return matback; } QString CAlgorithmFluorescence::getPath(class IImageObject *pObj) { IAlgorithmShared* pShare = pObj->IGetShared(); if (!pShare) return QString(); QStringList mlist = pObj->IGetShared()->IGetStringList("filepath"); if (mlist.empty()) { return QString(); } return mlist.first(); } //void CAlgorithmFluorescence::imageSegementation(const cv::Mat &srcImage) //{ // Mat mask; // //Mat sobelImg = srcImage.clone(); // //genSobelImage(sobelImg); // //sobelImg.convertTo(sobelImg, CV_8UC1); // // // Mat sobelX, sobelY; // Sobel(srcImage, sobelX, CV_32FC1, 1, 0, 3, BORDER_REPLICATE); // Sobel(srcImage, sobelY, CV_32FC1, 0, 1, 3, BORDER_REPLICATE); // Mat img = sobelX.mul(sobelX) + sobelY.mul(sobelY); // Mat tempImg; // img.convertTo(tempImg, CV_32FC1); // Mat tempImg0; // sqrt(tempImg, tempImg0); // img = tempImg0; // img.convertTo(img, CV_8UC1); // Mat blurImg; // cv::medianBlur(img, blurImg, 11); // bgSubtractor(img, mask, 0.001); // // /*cv::Mat element5(5, 5, CV_8U, cv::Scalar(1)); // cv::Mat closedMat; // cv::morphologyEx(mask, closedMat, cv::MORPH_CLOSE, element5);*/ // // //cv::floodFill(); // luffy_base::luffyCircle pCircle; // // vector mats= ImageProcess::findCircleObject(mask, srcImage, 15, &pCircle); // if (mats.size() == 0) // { // return; // } // if (mats[0].size() != mats[1].size()) // { // return; // } // Mat dilatedImgBin; // Mat imgBinary = mats[0] > 0; // dilate(imgBinary, dilatedImgBin, Mat::ones(5, 5, CV_32FC1)); // erode(dilatedImgBin, imgBinary, Mat::ones(5, 5, CV_32FC1)); // imgBinary = ~imgBinary; // //Mat canvas(imgBinary.size(), imgBinary.type(), Scalar::all(0)); // vector> cons; // cv::findContours(imgBinary, cons, RETR_EXTERNAL, CHAIN_APPROX_NONE); // for (const vector & pContour : cons) // { // const int& size = pContour.size(); // if (size < 200) // { // Mat(pContour).setTo(255); // //continue; // } // //cv::fillPoly(canvas, vector>(1, pContour), Scalar(255)); // } // //Mat tarMat = (~canvas).mul(mats[1]) / 255; // //openOper(imgBinary, Mat::ones(1, 13, CV_32FC1)); // // // // // return; // //}