加入抠图算法参数到UI上使用

master
bob.pan 5 years ago
parent c8334361ac
commit 0cc1d79843

@ -97,8 +97,6 @@ CAlgorithmCompare::~CAlgorithmCompare(void)
} }
//cv::BackgroundSubtractorMOG CAlgorithmFluorescence::bgSubtractor(30, 5, 0.95, false);
QString CAlgorithmCompare::bestMatch(const QMap<QString, IWheelModel*>* modelMap, CLocalWheel*pLocal, double* pMinDis /*= NULL*/, int minDisNum /*= -1*/) const QString CAlgorithmCompare::bestMatch(const QMap<QString, IWheelModel*>* modelMap, CLocalWheel*pLocal, double* pMinDis /*= NULL*/, int minDisNum /*= -1*/) const
{ {
double minDis = DBL_MAX; double minDis = DBL_MAX;
@ -279,7 +277,9 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj)
double dD2H = vMap.value("d2h", -1).toDouble(); double dD2H = vMap.value("d2h", -1).toDouble();
int nthreshold = vMap.value("Threshold", 15).toInt(); int nthreshold = vMap.value("Threshold", 15).toInt();
bool bUseBackground = vMap.value("useBackground",false).toBool();//true 使用背景图抠图 false 不使用背景 bool bUseBackground = vMap.value("useBackground",false).toBool();//true 使用背景图抠图 false 不使用背景
int filterCircleSize = vMap.value("filterSize", 50).toInt();//过滤尺寸
bool bEqual = vMap.value("bEqual", false).toBool();//是否使用图像增强
if (nthreshold <= 0) if (nthreshold <= 0)
nthreshold = 15; nthreshold = 15;
int IsCutedImg = vMap.value("IsCutImg", 0).toInt();//裁剪后的轮毂图 int IsCutedImg = vMap.value("IsCutImg", 0).toInt();//裁剪后的轮毂图
@ -301,17 +301,16 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj)
else{ else{
bReload = false; bReload = false;
} }
//imageSegementation(matSrc);
//matMatch = ImageProcess::findCircleObject(matSrc, matBack, bUseBackground, nthreshold/*15*/, &lCircle/* NULL*/); //matMatch = ImageProcess::findCircleObject(matSrc, matBack, bUseBackground, nthreshold/*15*/, &lCircle/* NULL*/);
Point2f centerPoint; Point2f centerPoint;
double radius = 0; double radius = 0;
matMatch = ImageProcess::findCircle(matSrc, centerPoint, radius); matMatch = ImageProcess::findCircle(matSrc, centerPoint, radius, bEqual, filterCircleSize);
lCircle.ptCenter = centerPoint; lCircle.ptCenter = centerPoint;
lCircle.fRadius = radius; lCircle.fRadius = radius;
if (matMatch.cols >= 900 || matMatch.rows >= 900) if (matMatch.cols >= 900 || matMatch.rows >= 900)
{ {
cv::resize(matMatch, matMatch, cv::Size(matMatch.cols / 2, matMatch.rows / 2)); cv::resize(matMatch, matMatch, cv::Size(matMatch.cols / 2, matMatch.rows / 2));
lCircle.fRadius = lCircle.fRadius / 2; lCircle.fRadius = lCircle.fRadius / 2;
} }
@ -327,10 +326,8 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj)
pImgObj->IVariantMapToUI(rltMap); pImgObj->IVariantMapToUI(rltMap);
return 0; return 0;
} }
//Mat matMatch = ImageProcess::findCircleObject(matSrc, matBack, 15, NULL/* &lCircle*/);
//double dDiameter = dD2H * matMatch.rows;
double dDiameter = dD2H * lCircle.fRadius * 2;
double dDiameter = dD2H * lCircle.fRadius * 2;
QVariantMap mResult;//匹配算法结果 QVariantMap mResult;//匹配算法结果
CLocalWheel wheelLocal; CLocalWheel wheelLocal;
wheelLocal.defectList = strModelList; wheelLocal.defectList = strModelList;
@ -370,7 +367,6 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj)
return 1; return 1;
} }
cv::Mat CAlgorithmCompare::getImage(class IImageObject *pImgObj) cv::Mat CAlgorithmCompare::getImage(class IImageObject *pImgObj)
{ {
emTpColorFormat colorFormat = pImgObj->IColorFormat(); emTpColorFormat colorFormat = pImgObj->IColorFormat();
@ -418,71 +414,3 @@ cv::Mat CAlgorithmCompare::getBackGroundImage(class IImageObject *pObj, bool bRe
} }
return matback; return matback;
} }
//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<cv::Mat> 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<vector<Point>> cons;
// cv::findContours(imgBinary, cons, RETR_EXTERNAL, CHAIN_APPROX_NONE);
// for (const vector<Point> & pContour : cons)
// {
// const int& size = pContour.size();
// if (size < 200)
// {
// Mat(pContour).setTo(255);
// //continue;
// }
// //cv::fillPoly(canvas, vector<vector<Point>>(1, pContour), Scalar(255));
// }
// //Mat tarMat = (~canvas).mul(mats[1]) / 255;
// //openOper(imgBinary, Mat::ones(1, 13, CV_32FC1));
//
//
//
//
// return;
//
//}

@ -573,7 +573,7 @@ cv::Mat ImageProcess::getForeImage(const Mat & src, const Mat &backgroundImg)
return (src - resizedBackgroundImg); return (src - resizedBackgroundImg);
} }
//输入一张灰度图,输出抠出的圆小图和半径,圆心坐标 //输入一张灰度图,输出抠出的圆小图和半径,圆心坐标
cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center ,double &radius) cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center ,double &radius, bool bEqual,int filterSize)
{ {
Mat detectImg; Mat detectImg;
Mat src = srcImg; Mat src = srcImg;
@ -581,7 +581,9 @@ cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center ,double &rad
cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE));
int bBaseX = detectImg.cols; int bBaseX = detectImg.cols;
int bBaseY = detectImg.rows; int bBaseY = detectImg.rows;
equalizeHist(detectImg, detectImg); if (bEqual == true)
equalizeHist(detectImg, detectImg);
detectImg = _EnhanImg_sharpen(detectImg); detectImg = _EnhanImg_sharpen(detectImg);
EDCircles edcircles(detectImg); EDCircles edcircles(detectImg);
@ -596,6 +598,10 @@ cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center ,double &rad
continue; continue;
if (EDCircle[i].center.x + EDCircle[i].r > bBaseX || EDCircle[i].center.y + EDCircle[i].r > bBaseY) if (EDCircle[i].center.x + EDCircle[i].r > bBaseX || EDCircle[i].center.y + EDCircle[i].r > bBaseY)
continue; continue;
if((EDCircle[i].r*REAIZE) < filterSize)
continue;
if (EDCircle[i].r > maxR) if (EDCircle[i].r > maxR)
{ {
maxR = EDCircle[i].r; maxR = EDCircle[i].r;
@ -612,26 +618,48 @@ cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center ,double &rad
center.x = (EDCircle[nIndex].center.x * REAIZE); center.x = (EDCircle[nIndex].center.x * REAIZE);
center.y = (EDCircle[nIndex].center.y * REAIZE); center.y = (EDCircle[nIndex].center.y * REAIZE);
radius = radius * REAIZE; radius = radius * REAIZE;
return DetectCircle(srcImg, center, radius); return DetectCircle(srcImg, center, radius, bEqual);
} }
else { else {//EDCirle 没找到圆 直径调用精细找圆算法
center.x = 0; center.x = srcImg.cols / 2;
center.y = 0; center.y = srcImg.rows / 2;
radius = 0; radius = 0;
return Mat(); return DetectCircle(srcImg, center, radius, bEqual);
} }
} }
Mat ImageProcess::DetectCircle(Mat img, Point2f& center, double& radius) Mat ImageProcess::DetectCircle(Mat img, Point2f& center, double& radius, bool bEqual)
{ {
Mat detectImg; Mat detectImg;
equalizeHist(img, detectImg); if (bEqual == true)
{
equalizeHist(img, detectImg);
}
else {
detectImg = img;
}
CircleDetector cd; CircleDetector cd;
cd.setAlgoType(CircleDetector::PeakCircle); cd.setAlgoType(CircleDetector::PeakCircle);
cd.setEdgeWidth(3); cd.setEdgeWidth(3);
cd.setPolarity(Polarity::White2Black); cd.setPolarity(Polarity::White2Black);
cd.setFindBy(FindBy::Best); cd.setFindBy(FindBy::Best);
cd.setRadii(radius - 100, radius + 150); double difRadiusMin = radius - 100;
double difRadiusMax = radius + 150;
if (difRadiusMin < 0)
{
difRadiusMin = 0;
if(radius>0)
difRadiusMax = abs(center.y - (img.cols / 2)) - 50;
else {
int minV = (img.rows / 2) > (img.cols / 2) ? (img.cols / 2) : (img.rows / 2);
difRadiusMax = minV - 50;
center.x = img.cols / 2;
center.y = img.rows / 2;
}
}
cd.setRadii(difRadiusMin, difRadiusMax);
cd.setACThres(3); cd.setACThres(3);
vector<float> allScores; vector<float> allScores;
Vec3f bestCircle; Vec3f bestCircle;
@ -648,6 +676,10 @@ Mat ImageProcess::DetectCircle(Mat img, Point2f& center, double& radius)
Rect rect; Rect rect;
rect.x = cen.x - r; rect.x = cen.x - r;
rect.y = cen.y - r; rect.y = cen.y - r;
if (rect.x < 0)
rect.x = 0;
if (rect.y < 0)
rect.y = 0;
rect.width = 2 * r; rect.width = 2 * r;
rect.height = 2 * r; rect.height = 2 * r;
Mat s = img(rect); Mat s = img(rect);

@ -23,8 +23,10 @@ public:
static cv::Mat findCircleObject(const Mat &src, const Mat& backgroundImg, bool useBackgroundFlag, int nThres = 20, luffy_base::luffyCircle *pCircle = NULL); static cv::Mat findCircleObject(const Mat &src, const Mat& backgroundImg, bool useBackgroundFlag, int nThres = 20, luffy_base::luffyCircle *pCircle = NULL);
static cv::Mat getForeImage(const Mat & src, const Mat &backgroundImg); static cv::Mat getForeImage(const Mat & src, const Mat &backgroundImg);
static cv::Mat findCircle(const Mat &srcImg, Point2f& center, double &radius);//找圆 //找圆
static cv::Mat DetectCircle(Mat img, Point2f& center, double& radius);//精细找圆 static cv::Mat findCircle(const Mat &srcImg, Point2f& center, double &radius, bool bEqual = true, int filterSize = 50 );
//精细找圆
static cv::Mat DetectCircle(Mat img, Point2f& center, double& radius, bool bEqual);
}; };
#endif #endif

@ -43,6 +43,13 @@ void lpGlobalConfig::init(QString strPath)
bRunBackClosing = jsMyself.value("runBackClosing").toBool(false);//关闭页面时自动后台运行 bRunBackClosing = jsMyself.value("runBackClosing").toBool(false);//关闭页面时自动后台运行
strSysTitle = jsMyself.value("systitle").toString(QObject::tr("识别定位一体系统"));//系统标题 strSysTitle = jsMyself.value("systitle").toString(QObject::tr("识别定位一体系统"));//系统标题
QJsonObject algParamObj = jsMyself.value("algParam").toObject();
if (!algParamObj.isEmpty())
{
algParam.bEqual = algParamObj.value("bEqual").toBool(false);
algParam.filterCircleSize = algParamObj.value("filterSize").toInt(50);
}
QJsonObject algObj = jsMyself.value(WHEEL_SELFDEFINE_ALGPARA).toObject(); QJsonObject algObj = jsMyself.value(WHEEL_SELFDEFINE_ALGPARA).toObject();
if (!algObj.isEmpty()) if (!algObj.isEmpty())
{ {
@ -292,6 +299,11 @@ void lpGlobalConfig::saveDeteImage()
jsMyself.insert("runBackClosing", bRunBackClosing);//关闭页面时自动后台运行 jsMyself.insert("runBackClosing", bRunBackClosing);//关闭页面时自动后台运行
jsMyself.insert("systitle", strSysTitle);//系统标题 jsMyself.insert("systitle", strSysTitle);//系统标题
QJsonObject algParamObj;
algParamObj.insert("bEqual", algParam.bEqual);
algParamObj.insert("filterSize", algParam.filterCircleSize);
jsMyself.insert("algParam", algParamObj);
QZkJsonParser::WriteJsonObject(fileMyself, jsMyself); QZkJsonParser::WriteJsonObject(fileMyself, jsMyself);
} }

@ -7,6 +7,10 @@
#include <QPoint> #include <QPoint>
/*系统参数管理类 全局调用*/ /*系统参数管理类 全局调用*/
typedef struct tagAlgParam {//算法参数
bool bEqual{ false };//是否使用增强
int filterCircleSize{ 50 };//过滤
}AlgParam;
class lpGlobalConfig :public lpsingleton<lpGlobalConfig> class lpGlobalConfig :public lpsingleton<lpGlobalConfig>
{ {
public: public:
@ -101,6 +105,8 @@ public:
bool bRunBackRunning{ true };//启动是自动后台运行 bool bRunBackRunning{ true };//启动是自动后台运行
bool bRunBackClosing{ false };//关闭页面时自动后台运行 bool bRunBackClosing{ false };//关闭页面时自动后台运行
QString strSysTitle;//系统标题 QString strSysTitle;//系统标题
AlgParam algParam;
}; };
#endif #endif

@ -196,7 +196,17 @@ Mat QAlgDetect::DetectCircle(Mat img, QPointF center, double radius,bool bEqual)
if (difRadiusMin < 0) if (difRadiusMin < 0)
{ {
difRadiusMin = 0; difRadiusMin = 0;
difRadiusMax = abs(center.y()-(img.cols / 2))-50; if (radius > 0)
{
difRadiusMax = abs(center.y() - (img.cols / 2)) - 50;
}
else
{
int minV = (img.rows / 2) > (img.cols / 2) ? (img.cols / 2) : (img.rows / 2);
difRadiusMax = minV - 50;
center.setX(img.cols / 2);
center.setY(img.rows / 2);
}
} }
cd.setRadii(difRadiusMin, difRadiusMax); cd.setRadii(difRadiusMin, difRadiusMax);

@ -736,6 +736,8 @@ QVariant lpMainWin::IGetVariantById(int id)
vMap.insert("Threshold", lpGlobalConfig::instance()->m_AlgThres); vMap.insert("Threshold", lpGlobalConfig::instance()->m_AlgThres);
vMap.insert("IsCutImg", lpGlobalConfig::instance()->m_UseCutImg); vMap.insert("IsCutImg", lpGlobalConfig::instance()->m_UseCutImg);
vMap.insert("useBackground", lpGlobalConfig::instance()->m_UseBackground>0?true:false);//使用背景图 vMap.insert("useBackground", lpGlobalConfig::instance()->m_UseBackground>0?true:false);//使用背景图
vMap.insert("filterSize", lpGlobalConfig::instance()->algParam.filterCircleSize);//定位圆过滤大小
vMap.insert("bEqual", lpGlobalConfig::instance()->algParam.bEqual);//是否使用图像增强
void* address = (void*)m_pCtrl->getAllModelMapPtr(); void* address = (void*)m_pCtrl->getAllModelMapPtr();
long long varadr = (long long)address; long long varadr = (long long)address;
@ -1787,8 +1789,8 @@ Q_SLOT void lpMainWin::onActivated(QSystemTrayIcon::ActivationReason reason)
void lpMainWin::setMainWindowVisibility(bool state) void lpMainWin::setMainWindowVisibility(bool state)
{ {
if (state) { if (state) {
//show(); show();
showMaximized(); //showMaximized();
qApp->processEvents(); qApp->processEvents();
qApp->setActiveWindow(this); qApp->setActiveWindow(this);
qApp->processEvents(); qApp->processEvents();

@ -40,6 +40,8 @@ Q_SLOT void lpSystemConfigUI::onButtonClicked()
lpGlobalConfig::instance()->bRunBackRunning = ui.checkBox_runBackRunning->isChecked(); lpGlobalConfig::instance()->bRunBackRunning = ui.checkBox_runBackRunning->isChecked();
lpGlobalConfig::instance()->bRunBackClosing = ui.checkBox_runBackClosing->isChecked(); lpGlobalConfig::instance()->bRunBackClosing = ui.checkBox_runBackClosing->isChecked();
lpGlobalConfig::instance()->strSysTitle = ui.lineEdit_4->text(); lpGlobalConfig::instance()->strSysTitle = ui.lineEdit_4->text();
lpGlobalConfig::instance()->algParam.bEqual = ui.checkBox_bEqual->isChecked();
lpGlobalConfig::instance()->algParam.filterCircleSize = ui.lineEdit_filterSize->text().toInt();
lpGlobalConfig::instance()->saveDeteImage(); lpGlobalConfig::instance()->saveDeteImage();
QString strLanguage = ui.comboBox->currentText(); QString strLanguage = ui.comboBox->currentText();
@ -83,6 +85,9 @@ void lpSystemConfigUI::showEvent(QShowEvent *event)
QSettings languageSetting("hubdetect.ini", QSettings::IniFormat); QSettings languageSetting("hubdetect.ini", QSettings::IniFormat);
QString strLanguage = languageSetting.value("language", "Chinese").toString(); QString strLanguage = languageSetting.value("language", "Chinese").toString();
ui.comboBox->setCurrentText(strLanguage); ui.comboBox->setCurrentText(strLanguage);
ui.checkBox_bEqual->setChecked(lpGlobalConfig::instance()->algParam.bEqual);
ui.lineEdit_filterSize->setText(QString("%1").arg(lpGlobalConfig::instance()->algParam.filterCircleSize));
} }
void lpSystemConfigUI::timerEvent(QTimerEvent *event) void lpSystemConfigUI::timerEvent(QTimerEvent *event)

@ -29,8 +29,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>577</width> <width>560</width>
<height>448</height> <height>510</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
@ -70,6 +70,19 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
@ -206,19 +219,6 @@
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="groupBox_4">
<property name="title"> <property name="title">
<string>其他:</string> <string>其他:</string>
@ -259,6 +259,59 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>算法参数:</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>过滤小于</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>的圆(单位:像素)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_filterSize">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="4">
<widget class="QCheckBox" name="checkBox_bEqual">
<property name="text">
<string>是否使用图像增强</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>

Loading…
Cancel
Save