Foreword
In the industrial field, the application of functions such as defect detection and target counting is basically a matter of trial and error. There is no specific standard. Standard modules for the functions can be realized by standardizing the input and output interfaces and replacing the process with a script engine.
1. Qt + OpenCV + Halcon
The input and output interface is implemented using Qt + OpenCV. OpenCV needs to convert the collected pictures into Halcon’s image interface for script detection. The script output interface needs to be converted into Qt and OpenCV for drawing the contours and marks of defects or targets.
OpenCV’s Mat to Halcon’s HObject:
HObject HMatToHObject(Mat image) {<!-- --> HObject ho_obj=HObject(); if(image.empty()) return ho_obj; if(3==image.channels()) {<!-- --> int w=image.cols; int h=image.rows; if(image.depth()==CV_8U) {<!-- --> vector<cv::Mat> ichannels; cv::Mat imagB; cv::Mat imagG; cv::Mat imagR; cv::split(image, ichannels); imagB=ichannels.at(0); imagG=ichannels.at(1); imagR=ichannels.at(2); uchar* dataRed=new uchar[w*h]; uchar* dataGreen=new uchar[w*h]; uchar* dataBlue=new uchar[w*h]; for(int i=0;i<h;i + + ) {<!-- --> memcpy(dataRed + w*i, imagR.ptr() + imagR.step*i, w); memcpy(dataGreen + w*i, imagG.ptr() + imagG.step*i, w); memcpy(dataBlue + w*i, imagB.ptr() + imagB.step*i, w); } GenImage3( & amp;ho_obj, "byte", w, h, (Hlong)(dataRed), (Hlong)(dataGreen), (Hlong)(dataBlue)); delete[] dataRed; delete[] dataGreen; delete[] dataBlue; } } else if(1==image.channels()) {<!-- --> int w=image.cols; int h=image.rows; if(image.depth()==CV_8U) {<!-- --> uchar* dataGray=new uchar[w*h]; for(int i=0;i<h;i + + ) memcpy(dataGray + w*i, image.ptr() + image.step*i, w); GenImage1( & amp;ho_obj, "byte", w, h, (Hlong)(dataGray)); delete[] dataGray; } } return ho_obj; }
Input-script-output related code:
try {<!-- --> HObject ho_ImageIn, ho_RegionIn, ho_RegionOn, ho_Chamber; HTuple hv_Objs, hv_Phi; HTuple hv_Rows, hv_Cols, hv_Area, hv_Row, hv_Column; //Image Mat conversion ho_ImageIn=HMatToHObject(param->image); GenEmptyObj( & amp;ho_RegionIn); GenEmptyObj( & amp;ho_RegionOn); if(isOK) {<!-- --> //engine m_HdevHpdc.SetInputIconicParamObject("ImageIn", ho_ImageIn); m_HdevHpdc.SetInputIconicParamObject("RegionIn", ho_RegionIn); //Execute Haclon program m_HdevHpdc.Execute(); //Output results ho_RegionOn=m_HdevHpdc.GetOutputIconicParamObject("RegionOn"); try {<!-- --> CountObj(ho_RegionOn, & amp;hv_Objs); hv_Objs = hv_Objs.Length()!=1 ? (int)0 : hv_Objs; for(int i=1;i<=hv_Objs.I();i + + ) {<!-- --> //Defect coordinates, area SelectObj(ho_RegionOn, & amp;ho_Chamber, i); AreaCenter(ho_Chamber, & amp;hv_Area, & amp;hv_Row, & amp;hv_Column); OrientationRegion(ho_Chamber, & amp;hv_Phi); OutPatchResult result; result.col=(float)hv_Column.D(); result.row=(float)hv_Row.D(); result.angle=(float)hv_Phi.D()*180/QM_PI; result.area=(float)hv_Area.D(); GetRegionContour(ho_Chamber, & amp;hv_Rows, & amp;hv_Cols); for(int i=0;i<hv_Cols.Length();i + + ) {<!-- --> result.contour.push_back((float)hv_Cols[i].D()); result.contour.push_back((float)hv_Rows[i].D()); } importApi->results.push_back(result); //Record the total area and quantity Area + = hv_Area.D(); Count + + ; } //Loading successful inter->hdevOk=true; inter->hdevError=QString("RegionNum: %1; Area: %2; Time: %3ms") .arg(Count) .arg(Area) .arg((double)clock()-Times); } catch(HOperatorException & amp;hv_Except) {<!-- --> isOK=false; inter->hdevOk=false; inter->hdevError=QString("[error: EngineOperator=%1;]").arg(hv_Except.ErrorMessage().Text()); } } } catch(HDevEngineException & amp;hv_Except) {<!-- --> isOK=false; inter->hdevOk=false; inter->hdevError=QString("[error: EngineDetect=%1;]").arg(hv_Except.Message()); }
Halcon loading script file related code:
bool TB_HaclonEngin::loaded() {<!-- --> bool isOK=true; HaclonEnginImport* importApi= & amp;api.input; try {<!-- --> //initialization this->released(); QFile file(importApi->inter.hdevPath); isOK = file.exists() ? isOK : false; if(isOK) {<!-- --> //load m_HdevProgram.LoadProgram(importApi->inter.hdevPath.toLocal8Bit().data()); //variable name m_HdevParamNames=m_HdevProgram.GetCtrlVarNames(); //Object name m_HdevIconNames=m_HdevProgram.GetIconicVarNames(); //Function name m_HdevFunNames=m_HdevProgram.GetLocalProcedureNames(); //First sub-function variable (runApi) HTuple funName=m_HdevFunNames.TupleSelect(HTuple(0)); //process m_HdevHpd=HDevProcedure(m_HdevProgram, funName.ToSArr()->Text()); m_HdevHpdc=m_HdevHpd.CreateCall(); importApi->inter.hdevOk=true; importApi->inter.hdevError=QString::fromLocal8Bit("Load: %1").arg(importApi->inter.hdevPath); } } catch(HDevEngineException & amp;hv_Except) {<!-- --> isOK=false; importApi->inter.hdevOk=false; importApi->inter.hdevError=QString("[error: EngineLoad=%1;]").arg(hv_Except.Message()); } return isOK; }
2. QScintilla expansion package
The QScintilla tool can realize color compilation of Halcon scripts, including keyword prompts, syntax error message prompts, etc.
Keyword expansion documentation:
Keyword color, error prompt:
Summary
The complete source code of the software is available for reference.
https://download.csdn.net/download/dede28/88530232