【VisionMaster】二次开发之多图像输入

1. 问题引入

在博文【VisionMaster】二次开发之第三方库的使用中介绍了如果使用第三方库来丰富VisionMaster的功能。但是通过生成工具生成的算子框架仅支持单图像的输入,如下:
【VisionMaster】二次开发之多图像输入
而在某些模块中,我们需要输入两张甚至更多张图片,如下:
【VisionMaster】二次开发之多图像输入

2. 问题解决

  • 使用构建工具为自定义算法模块生成模板项目。我不会在这里详细介绍
  • 找到生成工具生成的 CustomedModule 文件夹下的 CustomedModule.xml 文件。
    【VisionMaster】二次开发之多图像输入
  • 原文件内容如下:
    【VisionMaster】二次开发之多图像输入
  • 修改后的文件内容如下:
    【VisionMaster】二次开发之多图像输入
  • 找到生成工具生成的 CustomedModule 文件夹下的 CustomedModuleAlgorithmTab 文件。
    【VisionMaster】二次开发之多图像输入
  • 原文内容如下:
    【VisionMaster】二次开发之多图像输入
  • 修改内容如下:
    【VisionMaster】二次开发之多图像输入
  • 修改算法项目中的源代码文件如下:
// 1.获取图像
HKA_IMAGE			struInputImg1;
HKA_IMAGE			struInputImg2;
HKA_S32             nRet = IMVS_EC_UNKNOWN;
HKA_U32             nImageStatus = 0;
do
{
	nRet = VmModule_GetInputImageByName(hInput, "InImage", "InImageWidth", "InImageHeight", "InImagePixelFormat", &struInputImg1, &nImageStatus);
	HKA_CHECK_BREAK(IMVS_EC_OK != nRet);
} while (0);

do
{
	nRet = VmModule_GetInputImageByName(hInput, "InImage2", "InImageWidth2", "InImageHeight2", "InImagePixelFormat2", &struInputImg2, &nImageStatus);
	HKA_CHECK_BREAK(IMVS_EC_OK != nRet);
} while (0);

// 2. 图像转换
Mat input_image1 = HKAImageToMat(struInputImg1);
Mat input_image2 = HKAImageToMat(struInputImg2);

...

// 5. 算法处理
OutputDebugStringA("###Call CAlgorithmModule::Proces --> do algorighm process\n");

Mat weighted_image;
cv::addWeighted(input_image1, 0.5, input_image2, 0.5, 0, weighted_image, CV_8UC1);


// 6. 输出图像格式转换
HKA_IMAGE output_image = MatToHKAImage(weighted_image);
  • 必须保证参数对应
    【VisionMaster】二次开发之多图像输入
  • 完整代码如下
#include "stdafx.h"
#include "AlgorithmModule.h"
#include <stdlib.h>
#include <fstream>
#include "ErrorCodeDefine.h"
#include "iMVS-6000PixelFormatDefine.h"

#include <opencv2\opencv.hpp>

using namespace cv;

Mat HKAImageToMat(HKA_IMAGE hik_image)
{
	Mat mat;
	if (hik_image.format == HKA_IMG_MONO_08)
	{
		mat = Mat(hik_image.height, hik_image.width, CV_8UC1, hik_image.data[0]);
		int a = mat.cols;
	}
	else if (hik_image.format == HKA_IMG_RGB_RGB24_C3)
	{
		mat = Mat(hik_image.height, hik_image.width, CV_8UC3, hik_image.data[0]);
	}
	return mat;
}

HKA_IMAGE MatToHKAImage(Mat mat)
{
	HKA_IMAGE image;
	if (mat.channels() == 1)
	{
		image = { HKA_IMG_MONO_08, 0 };
		image.width = mat.cols;
		image.height = mat.rows;
		image.format = HKA_IMG_MONO_08;
		image.step[0] = mat.cols;
		image.data[0] = mat.data;
	}
	else if (mat.channels() == 3)
	{
		image = { HKA_IMG_RGB_RGB24_C3, 0 };
		image.width = mat.cols;
		image.height = mat.rows;
		image.format = HKA_IMG_RGB_RGB24_C3;
		image.step[0] = 3 * mat.cols;
		image.data[0] = mat.data;
	}
	return image;
}


int GetInputImage(IN void* hInput, HKA_IMAGE& struInputImg)
{
	HKA_S32             nRet = IMVS_EC_UNKNOWN;
	HKA_U32             nImageStatus = 0;

	do
	{
		nRet = VmModule_GetInputImageByName(hInput, "InImage", "InImageWidth", "InImageHeight", "InImagePixelFormat", &struInputImg, &nImageStatus);
		HKA_CHECK_BREAK(IMVS_EC_OK != nRet);
	} while (0);

	return nRet;
}

CAlgorithmModule::CAlgorithmModule()
{
	m_nRunInt = 50;
}

CAlgorithmModule::~CAlgorithmModule()
{

}

int CAlgorithmModule::Init()
{
	PARAM_VALUE_INFO_LIST stList = { 0 };
	int nRet = VM_M_GetDefaultConfigByFile(m_hModule, UNICODEtoUTF8(VmModule_GetXmlPath().GetBuffer()), &stList);
	if (nRet == IMVS_EC_OK)
	{
		for (int i = 0; i < stList.nNum; i++)
		{
			SetParam(stList.paramValueList[i].byParamName, stList.paramValueList[i].byParamValue, strlen(stList.paramValueList[i].byParamValue));
		}
	}

	return nRet;
}

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.获取图像
	HKA_IMAGE			struInputImg1;
	HKA_IMAGE			struInputImg2;
	HKA_S32             nRet = IMVS_EC_UNKNOWN;
	HKA_U32             nImageStatus = 0;
	do
	{
		nRet = VmModule_GetInputImageByName(hInput, "InImage", "InImageWidth", "InImageHeight", "InImagePixelFormat", &struInputImg1, &nImageStatus);
		HKA_CHECK_BREAK(IMVS_EC_OK != nRet);
	} while (0);

	do
	{
		nRet = VmModule_GetInputImageByName(hInput, "InImage2", "InImageWidth2", "InImageHeight2", "InImagePixelFormat2", &struInputImg2, &nImageStatus);
		HKA_CHECK_BREAK(IMVS_EC_OK != nRet);
	} while (0);

	// 2. 图像转换
	Mat input_image1 = HKAImageToMat(struInputImg1);
	Mat input_image2 = HKAImageToMat(struInputImg2);

	// 3. 获取输入参数
	int count = -1;

	int inputInt = -1;
	nRet = VM_M_GetInt(hInput, "InputInt", 0, &inputInt, &count);

	float inputFloat = 0;
	nRet = VM_M_GetFloat(hInput, "InputFloat", 0, &inputFloat, &count);

	
	int inputString1Length = 100;
	char inputString1[100];
	nRet = VM_M_GetString(hInput, "InputString", 0, inputString1, 100, &inputString1Length, &count);

	// 4. 获取运行参数
	auto runParam1 = this->m_nRunInt;

	// 5. 算法处理
	OutputDebugStringA("###Call CAlgorithmModule::Proces --> do algorighm process\n");

	Mat weighted_image;
	cv::addWeighted(input_image1, 0.5, input_image2, 0.5, 0, weighted_image, CV_8UC1);


	// 6. 输出图像格式转换
	HKA_IMAGE output_image = MatToHKAImage(weighted_image);

	// 7. 输出图像
	if (MVD_PIXEL_MONO_08 == modu_input->pImageInObj->GetPixelFormat())
	{
		VmModule_OutputImageByName_8u_C1R(hOutput, 1, "OutImage", "OutImageWidth", "OutImageHeight", "OutImagePixelFormat", &output_image);
	}
	else if (MVD_PIXEL_RGB_RGB24_C3 == modu_input->pImageInObj->GetPixelFormat())
	{
		VmModule_OutputImageByName_8u_C3R(hOutput, 1, "OutImage", "OutImageWidth", "OutImageHeight", "OutImagePixelFormat", &output_image);
	}

	// 8. 设置自定义输出参数
	VM_M_SetInt(hOutput, "OutputInt", 0, 77);
	VM_M_SetFloat(hOutput, "OutputFloat", 0, 3.1425f);
	VM_M_SetString(hOutput, "OutputString", 0, "OK");

	// 9. 设置模块运行状态
	VM_M_SetInt(hOutput, "ModuStatus", 0, nErrCode == 0 ? 1 : nErrCode);


	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 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("RunInt", szParamName))
	{
		sprintf_s(pBuff, nBuffSize, "%d", m_nRunInt);
	}
	else
	{
		return CVmAlgModuleBase::GetParam(szParamName, pBuff, nBuffSize, pDataLen);
	}
	
	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("RunInt", szParamName))
	{
		sscanf_s(pData, "%d", &m_nRunInt);
	}
	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;
	}

	printf("[ LineModule ] CreateModule, hModule = 0x%x, pUserModule = 0x%x \n", hModule, pUserModule);

	OutputDebugStringA("###Call CreateModule");

	return pUserModule;
}


LINEMODULE_API void __stdcall DestroyModule(void* hModule, CAbstractUserModule* pUserModule)
{
	assert(hModule != NULL);

	printf("\n[ LineModule ] DestroyModule, hModule = 0x%x\n", hModule);

	OutputDebugStringA("###Call DestroyModule");

	if (pUserModule != NULL)
	{
		delete pUserModule;
	}
}
/模块须导出的接口(实现结束)//

3. 效果演示

  • 方案配置
    【VisionMaster】二次开发之多图像输入
  • 图像源1
    【VisionMaster】二次开发之多图像输入
  • 图像源2
    【VisionMaster】二次开发之多图像输入
  • CustomedModule
    【VisionMaster】二次开发之多图像输入
  • 输出图像
    【VisionMaster】二次开发之多图像输入

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年4月13日 下午1:39
下一篇 2022年4月13日 下午2:02

相关推荐