【VM服务管家】VM4.x算法模块开发_4.3 联合Halcon开发-CSDN博客问题:有的用户在使用VisionMaster软件在开发视觉项目时,可能同时也使用HALCON,OpenCV等视觉算法库做一些图像的处理,并且希望能将HALCON等第三方算子集成到VM工具箱,能够在VM工具箱中拖拽出来,就像VisionMaster中的其他算法模块工具一样,可以通过弹出窗口配置运行参数,通过连线订阅其他模块传递的参数,设置ROI,通过图像窗口查看算法直接结果的渲染效果。实际上是可行的,VisionMaster是一个开放平台,可以接入第三方生态,这也是VisionMaster的一大亮点。https://blog.csdn.net/MVExpert/article/details/130413120
【VisionMaster】二次开发之第三方库的使用_visionmaster二次开发-CSDN博客二次开发之第三方库的使用_visionmaster二次开发https://blog.csdn.net/zhy29563/article/details/124115483
本来是Single,说明只有一个ROI,我改成Mul之后,就可以多个ROI了
下图中,再Init函数种,放入那两个函数,还是有必要的,防止每次运行该模块,都会耗费时间create
#ifdef EXAMPLEMODULE_EXPORTS
#define LINEMODULE_API __declspec(dllexport)
#else
#define LINEMODULE_API __declspec(dllimport)
#endif
#include "VmModuleBase.h"
#include "VmAlgModuBase.h"
#include "ErrorCodeDefine.h"
#include "VmModuleSharedMemoryBase.h"
#include "halconcpp.h"
using namespace HalconCpp;
// This class is exported from the LineModule.dll
class LINEMODULE_API CAlgorithmModule : public CVmAlgModuleBase, public CModuleSharedMemoryBase
{
public:
// 构造
explicit CAlgorithmModule();
// 析构
virtual ~CAlgorithmModule();
public:
// 初始化
int Init();
// 进行算法
int Process(IN void* hInput, IN void* hOutput, IN MVDSDK_BASE_MODU_INPUT* modu_input);
// 获取算法参数
int GetParam(IN const char* szParamName, OUT char* pBuff, IN int nBuffSize, OUT int* pDataLen);
// 设置算法参数
int SetParam(IN const char* szParamName, IN const char* pData, IN int nDataLen);
//获取halcon格式图像,高恩阳的函数
HObject GetHalconImage(MVDSDK_BASE_MODU_INPUT* modu_input);
//我的DeepOCR
string MyDeepOCR(IN HObject in);
void set_suitable_device_in_ocr_handle(HTuple hv_DeepOcrHandle);
public:
//void* m_hModule; // 模块句柄 - 4.3 在基类中定义了
private:
int m_ntheta;
HTuple hv_DeepOcrHandle;
};
/模块须导出的接口(实现开始)//
#ifdef __cplusplus
extern "C"
{
#endif
// 采用__stdcall调用约定,且须在.def文件中增加接口描述。
LINEMODULE_API CAbstractUserModule* __stdcall CreateModule(void* hModule);
LINEMODULE_API void __stdcall DestroyModule(void* hModule, CAbstractUserModule* pUserModule);
#ifdef __cplusplus
};
#endif
/模块须导出的接口(实现结束)//
#include "stdafx.h"
#include "AlgorithmModule.h"
#include
#include
#include "ErrorCodeDefine.h"
#include "iMVS-6000PixelFormatDefine.h"
#include
#include
#include
#include
#include
using namespace std;
CAlgorithmModule::CAlgorithmModule()
{
m_ntheta = 128;
}
CAlgorithmModule::~CAlgorithmModule()
{
}
int CAlgorithmModule::Init()
{
int nRet = VM_M_GetModuleId(m_hModule, &m_nModuleId);
if (IMVS_EC_OK != nRet)
{
m_nModuleId = -1;
return nRet;
}
nRet = ResetDefaultParam();
if (nRet != IMVS_EC_OK)
{
OutputDebugStringA("###Call ResetDefaultParam failed.");
}
CreateDeepOcr(HTuple(), HTuple(), &hv_DeepOcrHandle);
set_suitable_device_in_ocr_handle(hv_DeepOcrHandle);
return nRet;
}
HObject CAlgorithmModule::GetHalconImage(MVDSDK_BASE_MODU_INPUT* modu_input)
{
HObject ho_image;
GenEmptyObj(&ho_image);
if (modu_input->pImageInObj->GetImageData(0)->pData != nullptr)
{
if (MVD_PIXEL_MONO_08== modu_input->pImageInObj->GetPixelFormat())
{
GenImage1(&ho_image
, "byte"
, static_cast(modu_input->pImageInObj->GetWidth())
, static_cast(modu_input->pImageInObj->GetHeight())
, reinterpret_cast(modu_input->pImageInObj->GetImageData(0)->pData)
);
}
if (MVD_PIXEL_RGB_RGB24_C3 == modu_input->pImageInObj->GetPixelFormat())
{
GenImage3(&ho_image
, "byte"
, static_cast(modu_input->pImageInObj->GetWidth())
, static_cast(modu_input->pImageInObj->GetHeight())
, reinterpret_cast(modu_input->pImageInObj->GetImageData(0)->pData)
, reinterpret_cast(modu_input->pImageInObj->GetImageData(1)->pData)
, reinterpret_cast(modu_input->pImageInObj->GetImageData(2)->pData)
);
}
}
return ho_image;
}
string CAlgorithmModule::MyDeepOCR(IN HObject in)
{
HTuple hv_DeepOcrResult;
HTuple hv_RecognizedWords,hv_RecognizedWord;
ApplyDeepOcr(in, hv_DeepOcrHandle, "auto", &hv_DeepOcrResult);
GetDictTuple(hv_DeepOcrResult, "words", &hv_RecognizedWords);
GetDictTuple(hv_RecognizedWords, "word", &hv_RecognizedWord);
int wordCount = hv_RecognizedWord.Length();
string strBuff;
for (size_t i = 0; i < wordCount; i++)
{
strBuff += hv_RecognizedWord[i].S();
}
return strBuff;
}
void CAlgorithmModule::set_suitable_device_in_ocr_handle(HTuple hv_DeepOcrHandle)
{
// Local control variables
HTuple hv_DLDeviceHandles, hv_RecognitionImageWidthDefault;
HTuple hv_Exception, hv_Index;
//Determine deep learning device to work with (prefer GPU over CPU).
QueryAvailableDlDevices((HTuple("runtime").Append("runtime")), (HTuple("gpu").Append("cpu")),
&hv_DLDeviceHandles);
if (0 != (int((hv_DLDeviceHandles.TupleLength()) == 0)))
{
throw HException("No supported device found to continue this example.");
}
//Set recognition_image_width larger for the example to work without memory problems.
try
{
GetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width", &hv_RecognitionImageWidthDefault);
SetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width", 250);
}
// catch (Exception)
catch (HException& HDevExpDefaultException)
{
HDevExpDefaultException.ToHTuple(&hv_Exception);
}
//
{
HTuple end_val12 = (hv_DLDeviceHandles.TupleLength()) - 1;
HTuple step_val12 = 1;
for (hv_Index = 0; hv_Index.Continue(end_val12, step_val12); hv_Index += step_val12)
{
try
{
SetDeepOcrParam(hv_DeepOcrHandle, "device", HTuple(hv_DLDeviceHandles[hv_Index]));
break;
}
// catch (Exception)
catch (HException& HDevExpDefaultException)
{
HDevExpDefaultException.ToHTuple(&hv_Exception);
if (0 != (int(hv_Index == ((hv_DLDeviceHandles.TupleLength()) - 1))))
{
throw HException("Could not set any of the supported devices to continue this example.");
}
}
}
}
//Reset recognition_image_width to the default value.
try
{
SetDeepOcrParam(hv_DeepOcrHandle, "recognition_image_width", hv_RecognitionImageWidthDefault);
}
// catch (Exception)
catch (HException& HDevExpDefaultException)
{
HDevExpDefaultException.ToHTuple(&hv_Exception);
}
//
return;
}
int CAlgorithmModule::Process(IN void* hInput, IN void* hOutput, IN MVDSDK_BASE_MODU_INPUT* modu_input)
{
OutputDebugStringA("###Call CAlgorithmModule::Proces -->begin\n");
int nErrCode = 0;
// 1.获取输入
/************************************************/
//ToDo Code...............
HObject myImage=GetHalconImage(modu_input);
int nsize = modu_input->vtFixRoiShapeObj.size();
/************************************************/
// 2.算法处理
OutputDebugStringA("###Call CAlgorithmModule::Proces --> do algorighm process\n");
/************************************************/
for (size_t i = 0; i < nsize; i++)
{
IMvdRectangleF* rectangleRoi = dynamic_cast(modu_input->vtFixRoiShapeObj[i]);
int width = rectangleRoi->GetWidth();
int height = rectangleRoi->GetHeight();
int centerX = rectangleRoi->GetCenterX();
int centerY = rectangleRoi->GetCenterY();
HObject rect,imageReduced,imageCroped;
GenRectangle2(&rect, centerY, centerX, 0, width / 2, height / 2);
HTuple Row1, Column1, Row2, Column2;
SmallestRectangle1(rect, &Row1, &Column1, &Row2, &Column2);
CropRectangle1(myImage, &imageCroped, Row1, Column1, Row2, Column2);
ReduceDomain(myImage, rect, &imageReduced);
//if (0 == i)
//{
// WriteImage(imageCroped, "bmp", 0, "D:\\gao\\ocr0");
//}
//if (1 == i)
//{
// WriteImage(imageCroped, "bmp", 0, "D:\\gao\\ocr1");
//}
//if (2 == i)
//{
// WriteImage(imageCroped, "bmp", 0, "D:\\gao\\ocr2");
//}
//if (3 == i)
//{
// WriteImage(imageCroped, "bmp", 0, "D:\\gao\\ocr3");
//}
//if (4 == i)
//{
// WriteImage(imageCroped, "bmp", 0, "D:\\gao\\ocr4");
//}
string ocrStr = MyDeepOCR(imageCroped);
ofstream file1;
//file1.open("D:\\gao\\car.txt", ios::app); // 所有输出附加在文件末尾,用追加的方式写入,
// 写入追加的结果以换行的方式往下添加
if (file1.is_open())
{
cout << "正确打开文件! " << endl;
file1 << ocrStr << endl;
}
file1.close();
const char* p = ocrStr.data();
VM_M_SetString(hOutput, "mystring", i, p);
}
//ToDo Code...............
/************************************************/
// 3.输出结果
/************************************************/
//ToDo Code...............
//输出图像(渲染控件只能显示共享内存中的图像数据)
//char* pSharedName = NULL;
//HKA_IMAGE stImage;
//stImage.height = heightValue;
//stImage.width = widthValue;
//stImage.step[0] = widthValue;
//int nRet = AllocateSharedMemory(m_nModuleId, stImage.height*stImage.width, (char**)(&stImage.data), &pSharedName);
//if (nRet == IMVS_EC_OK && stImage.data != NULL)
//{
// memcpy_s(......);
// VmModule_OutputImageByName_8u_C1R(hOutput,
// status,
// OUTIMAGE,
// OUTIMAGEWIDTH,
// OUTIMAGEHEIGHT,
// OUTIMAGEPIXELFORMAT,
// &stImage,
// 0,
// pSharedName);
//}
/************************************************/
if (nErrCode != IMVS_EC_OK)
{
return IMVS_EC_PARAM;
}
/************************************************/
//默认算法时间20ms,根据实际时间计算
MODULE_RUNTIME_INFO struRunInfo = { 0 };
struRunInfo.fAlgorithmTime = 20;
VM_M_SetModuleRuntimeInfo(m_hModule, &struRunInfo);
OutputDebugStringA("###Call CAlgorithmModule::Proces end\n");
return IMVS_EC_OK;
}
int CAlgorithmModule::GetParam(IN const char* szParamName, OUT char* pBuff, IN int nBuffSize, OUT int* pDataLen)
{
OutputDebugStringA("###Call CAlgorithmModule::GetParam");
int nMsgLen = 0;
int nErrCode = IMVS_EC_OK;
if (szParamName == NULL || strlen(szParamName) == 0 || pBuff == NULL || nBuffSize <= 0 || pDataLen == NULL)
{
return IMVS_EC_PARAM;
}
//memset(pBuff, 0, nBuffSize);
if (0 == strcmp("theta", szParamName))
{
sprintf_s(pBuff, nBuffSize, "%d", m_ntheta);
}
else
{
return CVmAlgModuleBase::GetParam(szParamName, pBuff, nBuffSize, pDataLen);
}
//if(0 == strcmp(szParamName, "paramA"))
//{
// sprintf(pBuff, nBuffSize, "", ..);
//}
return nErrCode;
}
int CAlgorithmModule::SetParam(IN const char* szParamName, IN const char* pData, IN int nDataLen)
{
OutputDebugStringA("###Call CAlgorithmModule::SetParam");
int nErrCode = IMVS_EC_OK;
if (szParamName == NULL || strlen(szParamName) == 0 || pData == NULL || nDataLen == 0)
{
return IMVS_EC_PARAM;
}
if (0 == strcmp("theta", szParamName))
{
sscanf_s(pData, "%d", &m_ntheta);
}
else
{
return CVmAlgModuleBase::SetParam(szParamName, pData, nDataLen);
}
return nErrCode;
}
/模块须导出的接口(实现开始)//
LINEMODULE_API CAbstractUserModule* __stdcall CreateModule(void* hModule)
{
assert(hModule != NULL);
// 创建用户模块,并记录实例。
CAlgorithmModule* pUserModule = new(nothrow) CAlgorithmModule;
if (pUserModule == NULL)
{
return NULL;
}
pUserModule->m_hModule = hModule;
int nRet = pUserModule->Init();
if (IMVS_EC_OK != nRet)
{
delete pUserModule;
return NULL;
}
OutputDebugStringA("###Call CreateModule");
return pUserModule;
}
LINEMODULE_API void __stdcall DestroyModule(void* hModule, CAbstractUserModule* pUserModule)
{
assert(hModule != NULL);
OutputDebugStringA("###Call DestroyModule");
if (pUserModule != NULL)
{
delete pUserModule;
}
}
/模块须导出的接口(实现结束)//