Qt + OpenCV + Halcon + QScintilla implement Halcon’s script engine function (source code)

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