【VisionMaster】二次开发之多图像输入_visionmaster python-CSDN博客

1. 问题引入

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

2. 问题解决

  • 使用生成工具生成自定义算法模块的模板工程。这里就不详细介绍了
  • 找到生成工具生成的CustomedModule文件夹下的CustomedModule.xml文件。
    在这里插入图片描述
  • 原始的文件内容如下:
    在这里插入图片描述
<?xml version="1.0" encoding="UTF-8"?>
<ParamRoot>
    <Categorys>
        <Category Name="Base">...</Category>
        <Category Name="Input">
            <Items>
                <Filter Name="InputInt" ValueType="int" IsForce="true" isShow="true" AccessMode="RW"/>
                <Filter Name="InputFloat" ValueType="float" IsForce="true" isShow="true" AccessMode="RW"/>
                <Filter Name="InputString" ValueType="string" IsForce="true" isShow="true" AccessMode="RW"/>
                
                <Combination Name="InputImage" Style="IMAGE" AccessMode="RW">
                    <Filters>
                        <Filter Name="InImage" ValueType="image" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImageWidth" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImageHeight" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImagePixelFormat" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                    </Filters>
                </Combination>
                
                <Combination Name="InputROI" Style="ROIBOX" AccessMode="RW">...</Combination>
                <Combination Name="Position Correction Info" Style="FIXTURE" AccessMode="RW">...</Combination>
            </Items>
        </Category>
        <Category Name="Output">...</Category>
        <Category Name="TransmitInfo"/>
    </Categorys>
</ParamRoot>
  • 修改后的文件内容如下:
    在这里插入图片描述
<?xml version="1.0" encoding="UTF-8"?>
<ParamRoot>
    <Categorys>
        <Category Name="Base">...</Category>
        <Category Name="Input">
            <Items>
                <Filter Name="InputInt" ValueType="int" IsForce="true" isShow="true" AccessMode="RW"/>
                <Filter Name="InputFloat" ValueType="float" IsForce="true" isShow="true" AccessMode="RW"/>
                <Filter Name="InputString" ValueType="string" IsForce="true" isShow="true" AccessMode="RW"/>
                
                <Combination Name="InputImage" Style="IMAGE" AccessMode="RW">
                    <Filters>
                        <Filter Name="InImage" ValueType="image" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImageWidth" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImageHeight" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImagePixelFormat" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                    </Filters>
                </Combination>
                
                <Combination Name="InputImage2" Style="IMAGE" AccessMode="RW">
                    <Filters>
                        <Filter Name="InImage2" ValueType="image" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImageWidth2" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImageHeight2" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                        <Filter Name="InImagePixelFormat2" ValueType="int" IsForce="true" isShow="true" AccessMode="RO"/>
                    </Filters>
                </Combination>
                
                <Combination Name="InputROI" Style="ROIBOX" AccessMode="RW">...</Combination>
                <Combination Name="Position Correction Info" Style="FIXTURE" AccessMode="RW">...</Combination>
            </Items>
        </Category>
        <Category Name="Output">...</Category>
        <Category Name="TransmitInfo"/>
    </Categorys>
</ParamRoot>
  • 找到生成工具生成的CustomedModule文件夹下的CustomedModuleAlgorithmTab文件。
    在这里插入图片描述
  • 原始内容如下:
    在这里插入图片描述
<?xml version="1.0" encoding="UTF-8"?>
<AlgorithmTabRoot>
    <Tabs>
        <Tab Name="Tab_Basic Params">
            <Categorys>
            
                <GroupLinkItem Name="ImageSourceGroup">
                    <LinkName>ImageSourceGroup</LinkName>
                </GroupLinkItem>
                
                <Category Name="Tab_ROI Area">...</Category>
                <Category Name="Custom Inputs">...</Category>
            </Categorys>
        </Tab>
        <Tab Name="Tab_Run Params">...</Tab>
        <Tab Name="Tab_Result Show">...</Tab>
    </Tabs>
    <BottomExcuteButtonsLeft>...</BottomExcuteButtonsLeft>
    <BottomExcuteButtons>...</BottomExcuteButtons>
</AlgorithmTabRoot>
  • 修改后内容如下:
    在这里插入图片描述
<?xml version="1.0" encoding="UTF-8"?>
<AlgorithmTabRoot>
    <Tabs>
        <Tab Name="Tab_Basic Params">
            <Categorys>
            
                <Category Name="图像输入">
                    <Items>
                        <EnumerationG Name="ImageSource">
                            <Description>Input Source 1</Description>
                            <DisplayName>RunParam_Input Source 1</DisplayName>
                            <Visibility>Beginner</Visibility>
                            <AccessMode>O</AccessMode>
                            <Triggers>
                                <Trigger>
                                    <Property>CurValue</Property>
                                    <Setters>
                                        <Setter>
                                            <OperationName>SetCombinationSourceOperation</OperationName>
                                            <OperationParams>InputImage</OperationParams>
                                        </Setter>
                                    </Setters>
                                </Trigger>
                            </Triggers>
                            <Initers>
                                <Setter>
                                    <TargetName>EnumEntrys</TargetName>
                                    <OperationName>GetFrontParamItemsOperation</OperationName>
                                    <OperationParams>IMAGE</OperationParams>
                                </Setter>
                                <Setter>
                                    <TargetName>CurValue</TargetName>
                                    <OperationName>GetSelectedCombinationOperation</OperationName>
                                    <OperationParams>InputImage</OperationParams>
                                </Setter>
                            </Initers>
                        </EnumerationG>
                        <EnumerationG Name="ImageSource2">
                            <Description>Input Source 2</Description>
                            <DisplayName>RunParam_Input Source 2</DisplayName>
                            <Visibility>Beginner</Visibility>
                            <AccessMode>O</AccessMode>
                            <Triggers>
                                <Trigger>
                                    <Property>CurValue</Property>
                                    <Setters>
                                        <Setter>
                                            <OperationName>SetCombinationSourceOperation</OperationName>
                                            <OperationParams>InputImage2</OperationParams>
                                        </Setter>
                                    </Setters>
                                </Trigger>
                            </Triggers>
                            <Initers>
                                <Setter>
                                    <TargetName>EnumEntrys</TargetName>
                                    <OperationName>GetFrontParamItemsOperation</OperationName>
                                    <OperationParams>IMAGE</OperationParams>
                                </Setter>
                                <Setter>
                                    <TargetName>CurValue</TargetName>
                                    <OperationName>GetSelectedCombinationOperation</OperationName>
                                    <OperationParams>InputImage2</OperationParams>
                                </Setter>
                            </Initers>
                        </EnumerationG>
                    </Items>
                </Category>
                
                <Category Name="Tab_ROI Area">...</Category>
                <Category Name="Custom Inputs">...</Category>
            </Categorys>
        </Tab>
        <Tab Name="Tab_Run Params">...</Tab>
        <Tab Name="Tab_Result Show">...</Tab>
    </Tabs>
    <BottomExcuteButtonsLeft>...</BottomExcuteButtonsLeft>
    <BottomExcuteButtons>...</BottomExcuteButtons>
</AlgorithmTabRoot>

  • 修改算法工程中的源码文件,如下:
// 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);
  • 必须要保证一下参数要对应
    在这里插入图片描述
  • 完整代码如下
#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. 效果演示

  • 方案配置
    在这里插入图片描述
  • 图像源1
    在这里插入图片描述
  • 图像源2
    在这里插入图片描述
  • CustomedModule
    在这里插入图片描述
  • 输出图像
    在这里插入图片描述

原网址: 访问
创建于: 2024-05-24 16:07:42
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论