HALCON. 配合C++,为了在处理大量图片的定位时,节约时间。因此将大量图片放在多线程中同步执行,但是目前测试发现HACLON中我使用的查找模板算子,导致线程之间互斥了,窝查了下Halcon我使用的相关算子属于:Reentrant (可重入,适合并行处理,允许多线程)。
跪寻大神有偿解答,百度谷歌各种都试过了。。。代码也各种屏蔽测试。。
之前都没有使用过多线程并发进行,这次准备提速,测试了下多线程同时进行模板匹配突然遇到这个问题。。。。搞了我好几天了,目前我可以确定肯定不是我线程的问题,问题肯定出在HALCON的算子执行上。
其中
1、每个线程中使用的图片都是我单独复制的图片
2、每个线程中使用的模版也都是我读取本地100多个模板文件(为了排除这方面的原因,特意将模板文件复制了100分)
HALCON对于算子的介绍
find_scaled_shape_model (Operator)
Name
find_scaled_shape_model — Find the best matches of an isotropically scaled shape model in an image.
Parallelization
Multithreading type: reentrant (runs in parallel with non-exclusive operators).
Multithreading scope: global (may be called from any thread).
Automatically parallelized on internal data level.
希望哪位大神是否可以指点一二,一旦完美解决微信红包:500RMB 小小意思
- std::vector<HObject> WnLibOfFindScaleShapeModel::apply(const std::vector<HObject>& inputs, bool& error, std::string& errMsg,
- const HTuple dataDictionary)
- {
- // Local iconic variables
- HObject ho_ImageReduced, ho_ModelContours, ho_Cross;
- // Local control variables
- HTuple hv_windowHandle, hv_FindScaleShapeModelParam;
- HTuple hv_HomMat2D_Read, hv_ModelID;
- HTuple hv_ErrCode, hv_Number;
- HTuple hv_ActualRow, hv_ActualColumn, hv_Angle, hv_Scale;
- HTuple hv_Score, hv_HomMat2D, hv_MovementOfObject;
- HTuple hv_deltaAngle, hv_CenterData;
- //Matching 01: Find the model
- HTuple hv_FindScore;
- HTuple hv_ReturnCode;
- HObject ho_TransContours;
- HObject ho_RegionAffineTrans;
- GenEmptyObj(&(ho_TransContours));
- GenEmptyObj(&(ho_RegionAffineTrans));
- error = false;
- errMsg = "";
- const HTuple hv_DataDictionary = dataDictionary;
- try
- {
- GetMessageTuple(hv_DataDictionary, "ErrCode", &hv_ErrCode);
- hv_ReturnCode = hv_ErrCode;
- //判断上一个过程是否正常
- if (0 != (hv_ErrCode < 0))
- {
- return { ho_TransContours, ho_RegionAffineTrans };
- }
- //上一步执行正常,方可执行下面步骤
- //************************************获取输入参数************************************
- const HObject image = inputs[0];
- const HObject ho_RoiRegion = inputs[1];
- const HObject ho_ShapeModelRegion = inputs[2];
- //读取参数
- GetMessageTuple(hv_DataDictionary, "WindowHandle", &hv_windowHandle);
- GetMessageTuple(hv_DataDictionary, "FindScaleShapeModelParam", &hv_FindScaleShapeModelParam);
- GetMessageTuple(hv_DataDictionary, "HomMat2D_Read", &hv_HomMat2D_Read);
- GetMessageTuple(hv_DataDictionary, "ScaleShapeModeID", &hv_ModelID);
- int modeIIII = hv_ModelID.I();
- HTuple hv_WindowHandle = hv_windowHandle[0];
- const HTuple hv_AngleStart = hv_FindScaleShapeModelParam[0];
- const HTuple hv_AngleExtent = hv_FindScaleShapeModelParam[1];
- const HTuple hv_ScaleMin = hv_FindScaleShapeModelParam[2];
- const HTuple hv_ScaleMax = hv_FindScaleShapeModelParam[3];
- const HTuple hv_ScoreMin = hv_FindScaleShapeModelParam[4];
- const HTuple hv_ValidScore = hv_FindScaleShapeModelParam[5];
- CountObj(ho_RoiRegion, &hv_Number);
- if (0 != (hv_Number > 0))
- {
- ReduceDomain(image, ho_RoiRegion, &ho_ImageReduced);
- }
- else
- {
- CropDomain(image, &ho_ImageReduced);
- }
- //HTuple m_ParamPathIndex = "01";
- //HTuple m_MatchType = "形状";
- //HTuple m_ParamPath = ".\\HalconObject\\芯片\\定位相机\\2024071118295566\";
- //HTuple m_FullParamPath = m_ParamPath + m_MatchType + "\";
- //const HTuple hv_ModelPath = m_FullParamPath + "匹配模板" + "01" + ".shm";
- //ReadShapeModel(hv_ModelPath, &hv_ModelID);
- //auto start = std::chrono::high_resolution_clock::now();
- //// 将时间点转换为时间戳(以纳秒为单位)
- //auto startTime = std::chrono::duration_cast<std::chrono::nanoseconds>(start.time_since_epoch()).count();
- //设置查询超时
- //SetShapeModelParam(hv_ModelID, "timeout", 3000);
- FindScaledShapeModel(ho_ImageReduced, hv_ModelID, hv_AngleStart, hv_AngleExtent,
- hv_ScaleMin, hv_ScaleMax, hv_ScoreMin, 1, 0.5, "least_squares", 0, 0.1, &hv_ActualRow,
- &hv_ActualColumn, &hv_Angle, &hv_Scale, &hv_Score);
-
- //auto end = std::chrono::high_resolution_clock::now();
- //// 将时间点转换为时间戳(以纳秒为单位)
- //auto endTime = std::chrono::duration_cast<std::chrono::nanoseconds>(end.time_since_epoch()).count();
- //std::cout << "匹配开始时间:"<< startTime <<" 结束时间:"<< endTime << std::endl;
- //std::this_thread::sleep_for(std::chrono::milliseconds(100));
-
-
- //hv_ActualRow = hv_ActualRow;
- //hv_ActualColumn = hv_ActualColumn;
- //const HTuple hv_ActualAngel = hv_Angle;
- //GetShapeModelContours(&ho_ModelContours, hv_ModelID, 1);
- //{
- // const HTuple end_val54 = (hv_Score.TupleLength()) - 1;
- // const HTuple step_val54 = 1;
- // for (HTuple hv_I = 0; hv_I.Continue(end_val54, step_val54); hv_I += step_val54)
- // {
- // HomMat2dIdentity(&hv_HomMat2D);
- // HomMat2dRotate(hv_HomMat2D, hv_ActualAngel, 0, 0, &hv_HomMat2D);
- // HomMat2dTranslate(hv_HomMat2D, hv_ActualRow, hv_ActualColumn, &hv_HomMat2D);
- // AffineTransContourXld(ho_ModelContours, &(ho_TransContours), hv_HomMat2D);
- // }
- //}
- //
- ////*************************************计算圆心偏移量******************
- //if (0 != ((hv_Score.TupleLength()) > 0))
- //{
- // //测试代码
- // const float fScre = hv_Score.D();
- // if (0 != (HTuple(hv_Score[0]) >= hv_ValidScore))
- // {
- // //VectorAngleToRigid(HTuple(hv_HomMat2D_Read[0]), HTuple(hv_HomMat2D_Read[1]),
- // // 0, hv_ActualRow, hv_ActualColumn, hv_Angle, &hv_MovementOfObject);
- // //AffineTransRegion(ho_ShapeModelRegion, &(ho_RegionAffineTrans), hv_MovementOfObject,
- // // "nearest_neighbor");
- // HomMat2dIdentity(&hv_MovementOfObject);
- // HomMat2dScale(hv_MovementOfObject, HTuple(hv_Scale[0]), HTuple(hv_Scale[0]),
- // HTuple(hv_HomMat2D_Read[0]), HTuple(hv_HomMat2D_Read[1]), &hv_MovementOfObject);
- // HomMat2dRotate(hv_MovementOfObject, hv_Angle, HTuple(hv_HomMat2D_Read[0]),
- // HTuple(hv_HomMat2D_Read[1]), &hv_MovementOfObject);
- // HomMat2dTranslate(hv_MovementOfObject, hv_ActualRow - HTuple(hv_HomMat2D_Read[0]),
- // hv_ActualColumn - HTuple(hv_HomMat2D_Read[1]), &hv_MovementOfObject);
- // AffineTransRegion(ho_ShapeModelRegion, &(ho_RegionAffineTrans), hv_MovementOfObject,
- // "nearest_neighbor");
- // //下面的方法,用于避免在创建模板时使用了掩膜,一旦使用掩膜,图像中心就不一定是区域中心了
- // //因此在创建模板时,提前记录了图像中心位置
- // if (0 != ((hv_HomMat2D_Read.TupleLength()) >= 5))
- // {
- // const HTuple hv_OrigShapeRegionRow = hv_HomMat2D_Read[3];
- // const HTuple hv_OrigShapeRegionColumn = hv_HomMat2D_Read[4];
- // AffineTransPixel(hv_MovementOfObject, hv_OrigShapeRegionRow, hv_OrigShapeRegionColumn,
- // &hv_ActualRow, &hv_ActualColumn);
- // GenCrossContourXld(&ho_Cross, hv_ActualRow, hv_ActualColumn, 120, 0);
- // }
- // //当前角度+原始模板角度=实际物体角度---->相对图像水平面
- // if (0 != ((hv_HomMat2D_Read.TupleLength()) >= 3))
- // {
- // hv_deltaAngle = hv_HomMat2D_Read[2];
- // }
- // else
- // {
- // hv_deltaAngle = 0;
- // }
- // const HTuple hv_ActualAngle = (hv_Angle.TupleDeg()) + hv_deltaAngle;
- // hv_CenterData.Clear();
- // hv_CenterData.Append(hv_ActualRow);
- // hv_CenterData.Append(hv_ActualColumn);
- // hv_CenterData.Append(hv_ActualAngle);
- // hv_CenterData.Append(hv_Score[0]);
- // SetMessageTuple(dataDictionary, "CenterData", hv_CenterData);
- // hv_ReturnCode = 1;
- // }
- // else
- // {
- // hv_FindScore = hv_Score[0];
- // hv_ReturnCode = -11;
- // }
- //}
- //else
- //{
- // hv_FindScore = 0;
- // hv_ReturnCode = -12;
- //}
- }
- catch (HException& e)
- {
- CVisionPublicMethod::Get_HExceptionMsg(e, error, errMsg);
- hv_ReturnCode = -13;
- }
- ClearShapeModel(hv_ModelID);
- SetMessageTuple(dataDictionary, "ErrCode", hv_ReturnCode);
- //赋值输出参数
- return {ho_TransContours, ho_RegionAffineTrans};
复制代码
上面代码我注释了一部分(主要用于排除问题,不影响我测试结果)
多线程互斥了
|