【VM服务管家】专题_7.3 图像转换

news/2024/7/21 6:55:48 标签: 计算机视觉, 人工智能, 图像处理

目录

  • 3.1 图像转换扫盲篇(CSharp)
  • 3.2 相机采图转流程输入、Group输入、图像源SDK输入、模块输入、算子输入图像
  • 3.3 Bitmap转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出图像
  • 3.4 Mat转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出、脚本图像
  • 3.5 Halcon转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出、脚本图像
  • 3.6 流程图像与算子图像互转
  • 3.7 图像转换扫盲篇(C++)
  • 3.8 相机采图转流程输入、Group输入、图像源SDK输入、模块输入、算子输入图像
  • 3.9 QImage转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、流程输出图像
  • 3.10 Mat与流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出
  • 3.11 Halcon与流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出
  • 3.12 流程图像与算子图像互转
  • 3.13 算法模块图像与Mat、Halcon、算子图像互转的方法

3.1 图像转换扫盲篇(CSharp)

描述
环境:VM4.2 + VS2013及以上
现象:相机、VM脚本、VM SDK、算子SDK、算法模块中的图像类型是什么?
解答

  1. 图像格式一览
    除了Bitmap、Mat和Halcon中的图像类型,在VM和开发(开发包含三种:VM SDK开发(也称VM二次开发)算子SDK开发、自定义算法模块开发)中涉及的图像类型如下:
    相机:图像数据流(此处图像数据流类型是MyCamera.MV_FRAME_OUT,是来自MvCameraControl.Net.dll,即海康机器人工业相机SDK,在MVS SDK和算子SDK中都有这个dll;算子SDK的MVDCamera.Net.dll也可以进行相机取流,它是对MvCameraControl.Net.dll的二次封装,用MVDCamera.Net.dll时,图像数据流类型是CMvdImage);
    VM:脚本输入图像(图像类型是ImageData);
    VM SDK:流程输入图像(ImageBaseData_V2,VM4.2 SDK新增)、Group输入图像(ImageBaseData_V2,VM4.2 SDK新增)、图像源SDK输入图像(ImageBaseData)、模块输入图像(InputImageData)、流程输出图像(区分VM4.0 SDK和VM4.2 SDK的获取输出图像的方式,VM4.2获取流程图像的类型是ImageBaseData_V2) ;
    算子SDK:输入图像(CMvdImage);
    算法模块:输入图像(HKA_IMAGE,是C++中图像类型)。
  2. 图像类型转换(含单通道和三通道图像)三通道的Bitmap、Mat为BGR,三通道的VM和二次开发为RGB,针对常用图像转换场景,列举如下(见3.2~3.6)。篇幅所致,后续每种图像转换用函数表达,函数输入某种图像类型,返回转换后的某种图像类型。

3.2 相机采图转流程输入、Group输入、图像源SDK输入、模块输入、算子输入图像

描述
环境:VM4.2 + VS2013及以上
现象:相机采图转换成其他图像类型
解答
相机采图(MyCamera.MV_FRAME_OUT)转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像。
1 相机采图转流程输入(ImageBaseData_V2)、Group输入(ImageBaseData_V2)

public ImageBaseData_V2 CCDToImageBaseDataV2(MyCamera.MV_FRAME_OUT frameOut)
{
    ImageBaseData_V2 imageBaseDataV2 = new ImageBaseData_V2();
    if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
    {
        imageBaseDataV2 = new ImageBaseData_V2(frameOut.pBufAddr, frameOut.stFrameInfo.nFrameLen, frameOut.stFrameInfo.nWidth, frameOut.stFrameInfo.nHeight, VMPixelFormat.VM_PIXEL_MONO_08);
    }
    else if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
    {
        imageBaseDataV2 = new ImageBaseData_V2(frameOut.pBufAddr, frameOut.stFrameInfo.nFrameLen, frameOut.stFrameInfo.nWidth, frameOut.stFrameInfo.nHeight, VMPixelFormat.VM_PIXEL_RGB24_C3);
    }

    return imageBaseDataV2;
}
var image = CCDToImageBaseDataV2(stFrameOut);
//设置到流程
var procedure = VmSolution.Instance["流程1"] as VmProcedure;
procedure.ModuParams.SetInputImage_V2("ImageData", image);
//设置到Group
var group = VmSolution.Instance["流程1.组合模块1"] as IMVSGroupTool;
group.ModuParams.SetInputImage_V2("ImageData", image);

2 相机采图转图像源SDK输入(ImageBaseData)

public ImageBaseData CCDToImageBaseData(MyCamera.MV_FRAME_OUT frameOut)
{
    ImageBaseData imageBaseData = new ImageBaseData();
    imageBaseData.Width = frameOut.stFrameInfo.nWidth;
    imageBaseData.Height = frameOut.stFrameInfo.nHeight;
    imageBaseData.DataLen = frameOut.stFrameInfo.nFrameLen;
    if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
    {
        imageBaseData.Pixelformat = (int)VMPixelFormat.VM_PIXEL_MONO_08;
    }
    else if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
    {
        imageBaseData.Pixelformat = (int)VMPixelFormat.VM_PIXEL_RGB24_C3;
    }
    imageBaseData.ImageData = new byte[frameOut.stFrameInfo.nFrameLen];
    Marshal.Copy(frameOut.pBufAddr, imageBaseData.ImageData, 0, (int)frameOut.stFrameInfo.nFrameLen);
    return imageBaseData;
}
var image = CCDToImageBaseData(stFrameOut);
//设置到图像源
ImageSourceModuleTool imageSourceModuleTool = (ImageSourceModuleTool)VmSolution.Instance["流程1.图像源1"];
imageSourceModuleTool.SetImageData(image);

3 相机采图转模块输入(InputImageData)

public InputImageData CCDToInputImageData(MyCamera.MV_FRAME_OUT frameOut)
{
    InputImageData inputImageData = new InputImageData();
    inputImageData.Names.DataName = "InImage";//只能使用默认名称InImage
    inputImageData.Names.HeightName = "InImageHeight";//默认InImageHeight
    inputImageData.Names.WidthName = "InImageWidth";//默认InImageWidth
    inputImageData.Names.PixelFormatName = "InImagePixelFormat";//默认InImagePixelFormat
    inputImageData.Width = frameOut.stFrameInfo.nWidth;
    inputImageData.Height = frameOut.stFrameInfo.nHeight;
    inputImageData.DataLen = frameOut.stFrameInfo.nFrameLen;

    if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
    {
        inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_MONO8;

    }
    else if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
    {
        inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_RGB24;
    }
    //申请内存
    inputImageData.Data = Marshal.AllocHGlobal((int)frameOut.stFrameInfo.nFrameLen);
    byte[] imagedataBuffer = new byte[(int)frameOut.stFrameInfo.nFrameLen];
    Marshal.Copy(frameOut.pBufAddr, imagedataBuffer, 0, (int)frameOut.stFrameInfo.nFrameLen);
    Marshal.Copy(imagedataBuffer, 0, inputImageData.Data, (int)frameOut.stFrameInfo.nFrameLen);
    return inputImageData;
}
var image= CCDToInputImageData(stFrameOut);
//设置到模块        
var circlefindTool = VmSolution.Instance["流程1.圆查找1"] as IMVSImageEnhanceModuCs.IMVSImageEnhanceModuTool;
circlefindTool.ModuParams.SetInputImage(image);

4 相机采图转算子输入(CmvdImage)

public CMvdImage CCDToCMvdImage(MyCamera.MV_FRAME_OUT frameOut)
{
    VisionDesigner.CMvdImage cMvdImage = new VisionDesigner.CMvdImage();
    VisionDesigner.MVD_IMAGE_DATA_INFO stImageData = new VisionDesigner.MVD_IMAGE_DATA_INFO();
    stImageData.stDataChannel[0].nLen = (uint)(frameOut.stFrameInfo.nFrameLen);
    stImageData.stDataChannel[0].nSize = (uint)(frameOut.stFrameInfo.nFrameLen);
    byte[] m_BufForDriver1 = new byte[frameOut.stFrameInfo.nFrameLen];
    //数据Copy
    Marshal.Copy(frameOut.pBufAddr, m_BufForDriver1, 0, (int)frameOut.stFrameInfo.nFrameLen);
    stImageData.stDataChannel[0].arrDataBytes = m_BufForDriver1;
    if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
    {
        stImageData.stDataChannel[0].nRowStep = (uint)frameOut.stFrameInfo.nWidth;
        //初始化CMvdImage
        cMvdImage.InitImage((uint)frameOut.stFrameInfo.nWidth, (uint)frameOut.stFrameInfo.nHeight, MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08, stImageData);
    }
    else if (frameOut.stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
    {
        stImageData.stDataChannel[0].nRowStep = (uint)frameOut.stFrameInfo.nWidth * 3;
        //初始化CMvdImage
        cMvdImage.InitImage((uint)frameOut.stFrameInfo.nWidth, (uint)frameOut.stFrameInfo.nHeight, MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3, stImageData);
    }
    return cMvdImage;
}

问题根因
不熟悉相机采图转换为其它类型

3.3 Bitmap转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出图像

描述
环境:VM4.2 + VS2013及以上
现象:Bitmap转换成其他图像类型
解答
Bitmap转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像,流程输出图像转换为Bitmap。
1 Bitmap转流程输入(ImageBaseData_V2)、Group输入(ImageBaseData_V2)

public ImageBaseData_V2 BitmapToImageBaseData_V2(Bitmap bmpInputImg)
{
    ImageBaseData_V2 imageBaseData_V2 = new ImageBaseData_V2();
    System.Drawing.Imaging.PixelFormat bitPixelFormat = bmpInputImg.PixelFormat;
    BitmapData bmData = bmpInputImg.LockBits(new Rectangle(0, 0, bmpInputImg.Width, bmpInputImg.Height), ImageLockMode.ReadOnly, bitPixelFormat);//锁定

    if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height;//imageBaseData_V2图像真正的缓存长度
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex++];
            }
            bitmapIndex += offset;//删除冗余数据
        }
        IntPtr _ImageBaseDataIntptr = Marshal.AllocHGlobal(ImageBaseDataSize);
        Marshal.Copy(_ImageBaseDataBufferBytes, 0, _ImageBaseDataIntptr, ImageBaseDataSize);
        imageBaseData_V2 = new ImageBaseData_V2(_ImageBaseDataIntptr, (uint)ImageBaseDataSize, bmData.Width, bmData.Height, VMPixelFormat.VM_PIXEL_MONO_08);
        Marshal.FreeHGlobal(_ImageBaseDataIntptr);
    }
    else if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width * 3;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height * 3;//imageBaseData_V2图像真正的缓存长度
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 2];//bitmap为BGR,imageBaseData_V2为RGB
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 1];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex];
                bitmapIndex += 3;
            }
            bitmapIndex += offset;
        }
        IntPtr _ImageBaseDataIntptr = Marshal.AllocHGlobal(ImageBaseDataSize);
        Marshal.Copy(_ImageBaseDataBufferBytes, 0, _ImageBaseDataIntptr, ImageBaseDataSize);
        imageBaseData_V2 = new ImageBaseData_V2(_ImageBaseDataIntptr, (uint)ImageBaseDataSize, bmData.Width, bmData.Height, VMPixelFormat.VM_PIXEL_RGB24_C3);
        Marshal.FreeHGlobal(_ImageBaseDataIntptr);
}
bmpInputImg.UnlockBits(bmData);  // 解除锁定
    return imageBaseData_V2;
}

2 Bitmap转图像源SDK输入(ImageBaseData)

public ImageBaseData BitmapToImageBaseData(Bitmap bmpInputImg)
{
    ImageBaseData imageBaseData = new ImageBaseData();
    System.Drawing.Imaging.PixelFormat bitPixelFormat = bmpInputImg.PixelFormat;
    BitmapData bmData = bmpInputImg.LockBits(new Rectangle(0, 0, bmpInputImg.Width, bmpInputImg.Height), ImageLockMode.ReadOnly, bitPixelFormat);//锁定

    if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height;
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex++];
            }
            bitmapIndex += offset;
        }
        imageBaseData = new ImageBaseData(_ImageBaseDataBufferBytes, (uint)ImageBaseDataSize, bmData.Width, bmData.Height, (int)VMPixelFormat.VM_PIXEL_MONO_08);
    }
    else if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width * 3;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height * 3;
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 2];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 1];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex];
                bitmapIndex += 3;
            }
            bitmapIndex += offset;
        }
        imageBaseData = new ImageBaseData(_ImageBaseDataBufferBytes, (uint)ImageBaseDataSize, bmData.Width, bmData.Height, (int)VMPixelFormat.VM_PIXEL_RGB24_C3);
}
bmpInputImg.UnlockBits(bmData);  // 解除锁定
    return imageBaseData;
}

3 Bitmap转模块输入(InputImageData)

public InputImageData BitmapToInputImageData(Bitmap bmpInputImg)
{
    InputImageData inputImageData = new InputImageData();
    System.Drawing.Imaging.PixelFormat bitPixelFormat = bmpInputImg.PixelFormat;
    BitmapData bmData = bmpInputImg.LockBits(new Rectangle(0, 0, bmpInputImg.Width, bmpInputImg.Height), ImageLockMode.ReadOnly, bitPixelFormat);//锁定

    inputImageData.Names.DataName = "InImage";//只能使用默认名称InImage
    inputImageData.Names.HeightName = "InImageHeight";//默认InImageHeight
    inputImageData.Names.WidthName = "InImageWidth";//默认InImageWidth
    inputImageData.Names.PixelFormatName = "InImagePixelFormat";//默认InImagePixelFormat
    inputImageData.Width = bmData.Width;
    inputImageData.Height = bmData.Height;

    if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height;
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex++];
            }
            bitmapIndex += offset;
        }
        inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_MONO8;
        inputImageData.DataLen = (uint)ImageBaseDataSize;
        inputImageData.Data = Marshal.AllocHGlobal(ImageBaseDataSize);//inputImageData.Data需要申请内存;
        Marshal.Copy(_ImageBaseDataBufferBytes, 0, inputImageData.Data, _ImageBaseDataBufferBytes.Length);
    }
    else if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width * 3;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height * 3;
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 2];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 1];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex];
                bitmapIndex += 3;
            }
            bitmapIndex += offset;
        }
        inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_RGB24;
        inputImageData.DataLen = (uint)ImageBaseDataSize;
        inputImageData.Data = Marshal.AllocHGlobal(ImageBaseDataSize);//inputImageData.Data需要申请内存;
        Marshal.Copy(_ImageBaseDataBufferBytes, 0, inputImageData.Data, _ImageBaseDataBufferBytes.Length);
    }
    bmpInputImg.UnlockBits(bmData);  // 解除锁定
    return inputImageData;
}

4 Bitmap与算子(CmvdImage)互转

public CMvdImage BitmapToCMvdImage(Bitmap bmpInputImg)
{
    CMvdImage cMvdImage = new CMvdImage();
    System.Drawing.Imaging.PixelFormat bitPixelFormat = bmpInputImg.PixelFormat;
    BitmapData bmData = bmpInputImg.LockBits(new Rectangle(0, 0, bmpInputImg.Width, bmpInputImg.Height), ImageLockMode.ReadOnly, bitPixelFormat);//锁定

    if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height;
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex++];
            }
            bitmapIndex += offset;
        }
        MVD_IMAGE_DATA_INFO stImageData = new MVD_IMAGE_DATA_INFO();
        stImageData.stDataChannel[0].nRowStep = (uint)bmData.Width;
        stImageData.stDataChannel[0].nLen = (uint)ImageBaseDataSize;
        stImageData.stDataChannel[0].nSize = (uint)ImageBaseDataSize;
        stImageData.stDataChannel[0].arrDataBytes = _ImageBaseDataBufferBytes;
        cMvdImage.InitImage((uint)bmData.Width, (uint)bmData.Height, MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08, stImageData);
    }
    else if (bitPixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    {
        Int32 bitmapDataSize = bmData.Stride * bmData.Height;//bitmap图像缓存长度
        int offset = bmData.Stride - bmData.Width * 3;
        Int32 ImageBaseDataSize = bmData.Width * bmData.Height * 3;
        byte[] _BitImageBufferBytes = new byte[bitmapDataSize];
        byte[] _ImageBaseDataBufferBytes = new byte[ImageBaseDataSize];
        Marshal.Copy(bmData.Scan0, _BitImageBufferBytes, 0, bitmapDataSize);
        int bitmapIndex = 0;
        int ImageBaseDataIndex = 0;
        for (int i = 0; i < bmData.Height; i++)
        {
            for (int j = 0; j < bmData.Width; j++)
            {
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 2];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex + 1];
                _ImageBaseDataBufferBytes[ImageBaseDataIndex++] = _BitImageBufferBytes[bitmapIndex];
                bitmapIndex += 3;
            }
            bitmapIndex += offset;
        }
        MVD_IMAGE_DATA_INFO stImageData = new MVD_IMAGE_DATA_INFO();
        stImageData.stDataChannel[0].nRowStep = (uint)bmData.Width * 3;
        stImageData.stDataChannel[0].nLen = (uint)ImageBaseDataSize;
        stImageData.stDataChannel[0].nSize = (uint)ImageBaseDataSize;
        stImageData.stDataChannel[0].arrDataBytes = _ImageBaseDataBufferBytes;
        cMvdImage.InitImage((uint)bmData.Width, (uint)bmData.Height, MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3, stImageData);
    }
    bmpInputImg.UnlockBits(bmData);  // 解除锁定
    return cMvdImage;
}
public Bitmap CMvdImageToBitmap(CMvdImage cMvdImage)
{
    Bitmap bmpInputImg= null;
    byte[] buffer = new byte[cMvdImage.GetImageData(0).arrDataBytes.Length];
    buffer = cMvdImage.GetImageData(0).arrDataBytes;

    if (MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08 == cMvdImage.PixelFormat)
    {
        Int32 imageWidth = Convert.ToInt32(cMvdImage.Width);
        Int32 imageHeight = Convert.ToInt32(cMvdImage.Height);
        System.Drawing.Imaging.PixelFormat bitMaPixelFormat = System.Drawing.Imaging.PixelFormat.Format8bppIndexed;
        bmpInputImg = new Bitmap(imageWidth, imageHeight, bitMaPixelFormat);
        int offset = imageWidth % 4 != 0 ? (4 - imageWidth % 4) : 0;//添加冗余位,变成4的倍数
        int strid = imageWidth + offset;
        int bitmapBytesLenth = strid * imageHeight;
        byte[] bitmapDataBytes = new byte[bitmapBytesLenth];
        for (int i = 0; i < imageHeight; i++)
        {
            for (int j = 0; j < strid; j++)
            {
                int bitIndex = i * strid + j;
                int mvdIndex = i * imageWidth + j;
                if (j >= imageWidth)
                {
                    bitmapDataBytes[bitIndex] = 0;//冗余位填充0
                }
                else
                {
                    bitmapDataBytes[bitIndex] = buffer[mvdIndex];
                }
            }
        }
        BitmapData bitmapData = bmpInputImg.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.WriteOnly, bitMaPixelFormat);
        IntPtr imageBufferPtr = bitmapData.Scan0;
        Marshal.Copy(bitmapDataBytes, 0, imageBufferPtr, bitmapBytesLenth);
        bmpInputImg.UnlockBits(bitmapData);

        var colorPalettes = bmpInputImg.Palette;
        for (int j = 0; j < 256; j++)
        {
            colorPalettes.Entries[j] = Color.FromArgb(j, j, j);
        }
        bmpInputImg.Palette = colorPalettes;
    }
    else if (MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3 == cMvdImage.PixelFormat)
    {
        Int32 imageWidth = Convert.ToInt32(cMvdImage.Width);
        Int32 imageHeight = Convert.ToInt32(cMvdImage.Height);
        System.Drawing.Imaging.PixelFormat bitMaPixelFormat = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
        bmpInputImg = new Bitmap(imageWidth, imageHeight, bitMaPixelFormat);
        int offset = imageWidth % 4 != 0 ? (4 - (imageWidth * 3) % 4) : 0;//添加冗余位,变成4的倍数
        int strid = imageWidth * 3 + offset;
        int bitmapBytesLenth = strid * imageHeight;
        byte[] bitmapDataBytes = new byte[bitmapBytesLenth];
        for (int i = 0; i < imageHeight; i++)
        {
            for (int j = 0; j < imageWidth; j++)
            {
                int mvdIndex = i * imageWidth * 3 + j * 3;
                int bitIndex = i * strid + j * 3;
                bitmapDataBytes[bitIndex] = buffer[mvdIndex + 2];
                bitmapDataBytes[bitIndex + 1] = buffer[mvdIndex + 1];
                bitmapDataBytes[bitIndex + 2] = buffer[mvdIndex];
            }
            for (int k = 0; k < offset; k++)
            {
                bitmapDataBytes[i * strid + imageWidth * 3 + k] = 0;
            }
        }
        BitmapData bitmapData = bmpInputImg.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.WriteOnly, bitMaPixelFormat);
        IntPtr imageBufferPtr = bitmapData.Scan0;
        Marshal.Copy(bitmapDataBytes, 0, imageBufferPtr, bitmapBytesLenth);
        bmpInputImg.UnlockBits(bitmapData);
    }  
    return bmpInputImg;
}

5 流程输出(ImageBaseData_V2)转Bitmap

public Bitmap ImageBaseData_V2ToBitmap(ImageBaseData_V2 imageBaseData_V2)
{
    Bitmap bmpInputImg = null;
    byte[] buffer = new byte[imageBaseData_V2.DataLen];
    Marshal.Copy(imageBaseData_V2.ImageData, buffer, 0, buffer.Length);

    if (VMPixelFormat.VM_PIXEL_MONO_08 == imageBaseData_V2.Pixelformat)
    {
        Int32 imageWidth = Convert.ToInt32(imageBaseData_V2.Width);
        Int32 imageHeight = Convert.ToInt32(imageBaseData_V2.Height);
        System.Drawing.Imaging.PixelFormat bitMaPixelFormat = System.Drawing.Imaging.PixelFormat.Format8bppIndexed;
        bmpInputImg = new Bitmap(imageWidth, imageHeight, bitMaPixelFormat);
        int offset = imageWidth % 4 != 0 ? (4 - imageWidth % 4) : 0;//添加冗余位,变成4的倍数
        int strid = imageWidth + offset;
        int bitmapBytesLenth = strid * imageHeight;
        byte[] bitmapDataBytes = new byte[bitmapBytesLenth];
        for (int i = 0; i < imageHeight; i++)
        {
            for (int j = 0; j < strid; j++)
            {
                int bitIndex = i * strid + j;
                int mvdIndex = i * imageWidth + j;
                if (j >= imageWidth)
                {
                    bitmapDataBytes[bitIndex] = 0;//冗余位填充0
                }
                else
                {
                    bitmapDataBytes[bitIndex] = buffer[mvdIndex];
                }
            }
        }
        BitmapData bitmapData = bmpInputImg.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.WriteOnly, bitMaPixelFormat);
        IntPtr imageBufferPtr = bitmapData.Scan0;
        Marshal.Copy(bitmapDataBytes, 0, imageBufferPtr, bitmapBytesLenth);
        bmpInputImg.UnlockBits(bitmapData);

        var colorPalettes = bmpInputImg.Palette;
        for (int j = 0; j < 256; j++)
        {
            colorPalettes.Entries[j] = Color.FromArgb(j, j, j);
        }
        bmpInputImg.Palette = colorPalettes;
    }
    else if (VMPixelFormat.VM_PIXEL_RGB24_C3 == imageBaseData_V2.Pixelformat)
    {
        Int32 imageWidth = Convert.ToInt32(imageBaseData_V2.Width);
        Int32 imageHeight = Convert.ToInt32(imageBaseData_V2.Height);
        System.Drawing.Imaging.PixelFormat bitMaPixelFormat = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
        bmpInputImg = new Bitmap(imageWidth, imageHeight, bitMaPixelFormat);
        int offset = imageWidth % 4 != 0 ? (4 - (imageWidth * 3) % 4) : 0;//添加冗余位,变成4的倍数
        int strid = imageWidth * 3 + offset;
        int bitmapBytesLenth = strid * imageHeight;
        byte[] bitmapDataBytes = new byte[bitmapBytesLenth];
        for (int i = 0; i < imageHeight; i++)
        {
            for (int j = 0; j < imageWidth; j++)
            {
                int mvdIndex = i * imageWidth * 3 + j * 3;
                int bitIndex = i * strid + j * 3;
                bitmapDataBytes[bitIndex] = buffer[mvdIndex + 2];
                bitmapDataBytes[bitIndex + 1] = buffer[mvdIndex + 1];
                bitmapDataBytes[bitIndex + 2] = buffer[mvdIndex];
            }
            for (int k = 0; k < offset; k++)
            {
                bitmapDataBytes[i * strid + imageWidth * 3 + k] = 0;
            }
        }
        BitmapData bitmapData = bmpInputImg.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.WriteOnly, bitMaPixelFormat);
        IntPtr imageBufferPtr = bitmapData.Scan0;
        Marshal.Copy(bitmapDataBytes, 0, imageBufferPtr, bitmapBytesLenth);
        bmpInputImg.UnlockBits(bitmapData);
    }
    return bmpInputImg;
}

问题根因
不熟悉Bitmap转换为其它类型

3.4 Mat转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出、脚本图像

描述
环境:VM4.2 + VS2013及以上
现象:Mat转换成其他图像类型
解答
Mat转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像,算子输出图像转Mat,流程输出图像转换为Mat,Mat与脚本图像互转。
1 Mat转流程输入(ImageBaseData_V2)、Group输入(ImageBaseData_V2)

public ImageBaseData_V2 MatToImageBaseData_V2(Mat matInputImg)
{
    ImageBaseData_V2 imageBaseData_V2 = new ImageBaseData_V2();
    uint dataLen = (uint)(matInputImg.Width * matInputImg.Height * matInputImg.Channels());
    if (1 == matInputImg.Channels())
    {
        imageBaseData_V2 = new ImageBaseData_V2(matInputImg.Ptr(0), dataLen, matInputImg.Width, matInputImg.Height, VMPixelFormat.VM_PIXEL_MONO_08);
    }
    else if (3 == matInputImg.Channels())
    {
        //交换R与B通道
        Cv2.CvtColor(matInputImg, matInputImg, ColorConversionCodes.BGR2RGB);
        imageBaseData_V2 = new ImageBaseData_V2(matInputImg.Ptr(0), dataLen, matInputImg.Width, matInputImg.Height, VMPixelFormat.VM_PIXEL_RGB24_C3);
    }
    return imageBaseData_V2;
}

2 Mat转图像源SDK输入(ImageBaseData)

public ImageBaseData MatToImageBaseData(Mat matInputImg)
{
    ImageBaseData imageBaseData = new ImageBaseData();
    uint dataLen = (uint)(matInputImg.Width * matInputImg.Height * matInputImg.Channels());
    byte[] buffer = new byte[dataLen];
    Marshal.Copy(matInputImg.Ptr(0), buffer, 0, buffer.Length);
    if (1 == matInputImg.Channels())
    {
        imageBaseData = new ImageBaseData(buffer, dataLen, matInputImg.Width, matInputImg.Height, (int)VMPixelFormat.VM_PIXEL_MONO_08);
    }
    else if (3 == matInputImg.Channels())
    {
        //交换R与B通道
        for (int i = 0; i < buffer.Length - 2; i += 3)
        {
            byte temp = buffer[i];
            buffer[i] = buffer[i + 2];
            buffer[i + 2] = temp;
        }
        imageBaseData = new ImageBaseData(buffer, dataLen, matInputImg.Width, matInputImg.Height, (int)VMPixelFormat.VM_PIXEL_RGB24_C3);
    }
    return imageBaseData;
}

3 Mat转模块输入(InputImageData)

public InputImageData MatToInputImageData(Mat matInputImg)
{
    InputImageData inputImageData = new InputImageData();
    uint dataLen = (uint)(matInputImg.Width * matInputImg.Height * matInputImg.Channels());
    byte[] buffer = new byte[dataLen];
    Marshal.Copy(matInputImg.Ptr(0), buffer, 0, buffer.Length);

    inputImageData.Names.DataName = "InImage";//只能使用默认名称InImage
    inputImageData.Names.HeightName = "InImageHeight";//默认InImageHeight
    inputImageData.Names.WidthName = "InImageWidth";//默认InImageWidth
    inputImageData.Names.PixelFormatName = "InImagePixelFormat";//默认InImagePixelFormat
    inputImageData.Width = matInputImg.Width;
    inputImageData.Height = matInputImg.Height;
    inputImageData.DataLen = dataLen;
    //inputImageData.Data需要申请内存
    inputImageData.Data = Marshal.AllocHGlobal((int)dataLen);

    if (1 == matInputImg.Channels())
    {
        inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_MONO8;
        Marshal.Copy(buffer, 0, inputImageData.Data, buffer.Length);
    }
    else if (3 == matInputImg.Channels())
    {
        //交换R与B通道
        for (int i = 0; i < buffer.Length - 2; i += 3)
        {
            byte temp = buffer[i];
            buffer[i] = buffer[i + 2];
            buffer[i + 2] = temp;
        }
        inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_RGB24;
        Marshal.Copy(buffer, 0, inputImageData.Data, buffer.Length);
    }
    return inputImageData;
}

4 Mat与算子图像(CmvdImage)互转

public CMvdImage MatToCMvdImage(Mat matInputImg)
{
    CMvdImage cMvdImage = new CMvdImage();
    uint dataLen = (uint)(matInputImg.Width * matInputImg.Height * matInputImg.Channels());
    byte[] buffer = new byte[dataLen];
    Marshal.Copy(matInputImg.Ptr(0), buffer, 0, buffer.Length);
    if (1 == matInputImg.Channels())
    {
        MVD_IMAGE_DATA_INFO stImageData = new MVD_IMAGE_DATA_INFO();
        stImageData.stDataChannel[0].nRowStep = (uint)matInputImg.Width;
        stImageData.stDataChannel[0].nLen = dataLen;
        stImageData.stDataChannel[0].nSize = dataLen;
        stImageData.stDataChannel[0].arrDataBytes = buffer;
        cMvdImage.InitImage((uint)matInputImg.Width, (uint)matInputImg.Height, MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08, stImageData);
    }
    else if (3 == matInputImg.Channels())
    {
        //交换R与B通道
        for (int i = 0; i < buffer.Length - 2; i += 3)
        {
            byte temp = buffer[i];
            buffer[i] = buffer[i + 2];
            buffer[i + 2] = temp;
        }

        MVD_IMAGE_DATA_INFO stImageData = new MVD_IMAGE_DATA_INFO();
        stImageData.stDataChannel[0].nRowStep = (uint)matInputImg.Width * 3;
        stImageData.stDataChannel[0].nLen = dataLen;
        stImageData.stDataChannel[0].nSize = dataLen;
        stImageData.stDataChannel[0].arrDataBytes = buffer;
        cMvdImage.InitImage((uint)matInputImg.Width, (uint)matInputImg.Height, MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3, stImageData);
    }
    return cMvdImage;
}


public Mat CMvdImageToMat(CMvdImage cMvdImage)
{
    Mat matInputImg = new Mat();
    cMvdImage.InitImage("D:\\2.jpg");
    byte[] buffer = new byte[cMvdImage.GetImageData(0).arrDataBytes.Length];
    buffer = cMvdImage.GetImageData(0).arrDataBytes;

    if (MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08 == cMvdImage.PixelFormat)
    {
        matInputImg.Create((int)cMvdImage.Height, (int)cMvdImage.Width, MatType.CV_8UC1);
        Marshal.Copy(buffer, 0, matInputImg.Ptr(0), buffer.Length);
    }
    else if (MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3 == cMvdImage.PixelFormat)
    {
        matInputImg.Create((int)cMvdImage.Height, (int)cMvdImage.Width, MatType.CV_8UC3);

        //交换R与B通道
        for (int i = 0; i < buffer.Length - 2; i += 3)
        {
            byte temp = buffer[i];
            buffer[i] = buffer[i + 2];
            buffer[i + 2] = temp;
        }
        Marshal.Copy(buffer, 0, matInputImg.Ptr(0), buffer.Length);
    }
    return matInputImg;
}

5 流程输出(ImageBaseData_V2)转Mat

public Mat ImageBaseData_V2ToMat(ImageBaseData_V2 imageBaseData_V2)
{
    Mat matInputImg = new Mat();
    byte[] buffer = new byte[imageBaseData_V2.DataLen];
    Marshal.Copy(imageBaseData_V2.ImageData, buffer, 0, buffer.Length);

    if (VMPixelFormat.VM_PIXEL_MONO_08 == imageBaseData_V2.Pixelformat)
    {
        matInputImg.Create(imageBaseData_V2.Height, imageBaseData_V2.Width, MatType.CV_8UC1);
        Marshal.Copy(buffer, 0, matInputImg.Ptr(0), buffer.Length);
    }
    else if (VMPixelFormat.VM_PIXEL_RGB24_C3 == imageBaseData_V2.Pixelformat)
    {
        matInputImg.Create(imageBaseData_V2.Height, imageBaseData_V2.Width, MatType.CV_8UC3);

        //交换R与B通道
        for (int i = 0; i < buffer.Length - 2; i += 3)
        {
            byte temp = buffer[i];
            buffer[i] = buffer[i + 2];
            buffer[i + 2] = temp;
        }
        Marshal.Copy(buffer, 0, matInputImg.Ptr(0), buffer.Length);
    }
    return matInputImg;
}

6 Mat与脚本图像(ImageData)互转

public ImageData MatToImageData(Mat matImage)
{
    ImageData imgOut = new ImageData();
    byte[] buffer = new Byte[matImage.Width * matImage.Height * matImage.Channels()];
    Marshal.Copy(matImage.Ptr(0), buffer, 0, buffer.Length);
    if (1 == matImage.Channels())
    {
        imgOut.Buffer = buffer;
        imgOut.Width = matImage.Width;
        imgOut.Heigth = matImage.Height;
        imgOut.PixelFormat = ImagePixelFormate.MONO8;
    }
    else if (3 == matImage.Channels())
    {
        //交换R与B通道
        for (int i = 0; i < buffer.Length - 2; i += 3)
        {
            byte temp = buffer[i];
            buffer[i] = buffer[i + 2];
            buffer[i + 2] = temp;
        }

        imgOut.Buffer = buffer;
        imgOut.Width = matImage.Width;
        imgOut.Heigth = matImage.Height;
        imgOut.PixelFormat = ImagePixelFormate.RGB24;
    }
    return imgOut;
}
public Mat ImageDataToMat(ImageData img)
{
    Mat matImage = new Mat();
    if(ImagePixelFormate.MONO8 == img.PixelFormat)
    {
        matImage = Mat.Zeros(img.Heigth, img.Width, MatType.CV_8UC1);
        IntPtr grayPtr = Marshal.AllocHGlobal(img.Width * img.Heigth);
        Marshal.Copy(img.Buffer, 0, matImage.Ptr(0), img.Buffer.Length);

        //用完记得释放指针 
        Marshal.FreeHGlobal(grayPtr);
    }
    else if (ImagePixelFormate.RGB24 == img.PixelFormat)
    {
        matImage = Mat.Zeros(img.Heigth, img.Width, MatType.CV_8UC3);
        IntPtr rgbPtr = Marshal.AllocHGlobal(img.Width * img.Heigth * 3);
        Marshal.Copy(img.Buffer, 0, matImage.Ptr(0), img.Buffer.Length);
        Cv2.CvtColor(matImage, matImage, ColorConversionCodes.RGB2BGR);

        //用完记得释放指针 
        Marshal.FreeHGlobal(rgbPtr);
    }
    return matImage;
}

问题根因
不熟悉Mat转换为其它类型

3.5 Halcon转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出、脚本图像

描述
环境:VM4.2 + VS2013及以上
现象:Halcon转换成其他图像类型
解答
Halcon图像转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像,算子输出图像转Halcon图像,流程输出图像转换为Halcon图像,Halcon图像与脚本图像互转。
1 Halcon图像转流程输入(ImageBaseData_V2)、Group输入(ImageBaseData_V2)

public static ImageBaseData_V2 HalconImageToImageBaseDataV2(HObject hImageObj)
{
    try
    {
        ImageBaseData_V2 imageBaseData = new ImageBaseData_V2();
        HTuple imageWidth = 0;
        HTuple imageHeight = 0;
        HTuple objClass = hImageObj.GetObjClass();
        if (objClass.S.Equals("image"))
        {
            HTuple imageType;
            HOperatorSet.GetImageType(hImageObj, out imageType);
            if (imageType.S.Equals("byte"))
            {
                //获取图像通道数
                HTuple channels = 0;
                HOperatorSet.CountChannels(hImageObj, out channels);
                //如果是单通道
                if (channels.I == 1)
                {
                    HTuple imagePointer;
                    HOperatorSet.GetImagePointer1(hImageObj, out imagePointer, out imageType, out imageWidth, out imageHeight);
                    imageBaseData.Width = imageWidth.I;
                    imageBaseData.Height = imageHeight.I;
                    imageBaseData.Pixelformat = VMPixelFormat.VM_PIXEL_MONO_08;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    imageBaseData.DataLen = (uint)(stride * imageBaseData.Height);
                    imageBaseData.ImageData = imagePointer;
                }
                //如果是三通道
                else if (channels.I == 3)
                {
                    HTuple redChannel;
                    HTuple greenChannel;
                    HTuple blueChannel;
                    HOperatorSet.GetImagePointer3(hImageObj, out redChannel, out greenChannel, out blueChannel, out imageType, out imageWidth, out imageHeight);
                    imageBaseData.Width = imageWidth.I;
                    imageBaseData.Height = imageHeight.I;
                    imageBaseData.Pixelformat = VMPixelFormat.VM_PIXEL_RGB24_C3;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    byte[] imageRedBuffer = new byte[stride * imageHeight.I];
                    byte[] imageGreenBuffer = new byte[stride * imageHeight.I];
                    byte[] imageBlueBuffer = new byte[stride * imageHeight.I];
                    Marshal.Copy(redChannel, imageRedBuffer, 0, imageRedBuffer.Length);
                    Marshal.Copy(greenChannel, imageGreenBuffer, 0, imageGreenBuffer.Length);
                    Marshal.Copy(blueChannel, imageBlueBuffer, 0, imageBlueBuffer.Length);
                    byte[] imageBuffer = new byte[stride * imageHeight.I * 3];
                    for (int row = 0; row < imageHeight.I; row++)
                    {
                        for (int col = 0, index = 0; col < imageWidth.I; col++, index += 3)
                        {
                            imageBuffer[index] = imageRedBuffer[row * imageWidth + col];
                            imageBuffer[index + 1] = imageGreenBuffer[row * imageWidth + col];
                            imageBuffer[index + 2] = imageBlueBuffer[row * imageWidth + col];
                        }
                    }
                    imageBaseData.DataLen = (uint)(stride * imageBaseData.Height * 3);
                    imageBaseData.ImageData = Marshal.UnsafeAddrOfPinnedArrayElement(imageBuffer, 0);
                }
                else
                {
                    hImageObj?.Dispose();
                    throw new Exception("不支持单通道,三通道以外的图像");
                }
            }
            else
            {
                hImageObj?.Dispose();
                throw new Exception("不支持8bit以外的位深度图像");
            }
        }
        else
        {
            hImageObj?.Dispose();
            throw new Exception("HObject非图像类型对象");
        }
        return imageBaseData;
    }
    catch (Exception ex)
    {
        hImageObj?.Dispose();
        throw new Exception(ex.Message);
    }
}

2 Halcon图像转图像源SDK输入(ImageBaseData)

public static ImageBaseData HalconImageToImageBaseData(HObject hImageObj)
{
    try
    {
        ImageBaseData imageBaseData = new ImageBaseData();
        HTuple imageWidth = 0;
        HTuple imageHeight = 0;
        HTuple objClass = hImageObj.GetObjClass();
        if (objClass.S.Equals("image"))
        {
            HTuple imageType;
            HOperatorSet.GetImageType(hImageObj, out imageType);
            if (imageType.S.Equals("byte"))
            {
                //获取图像通道数
                HTuple channels = 0;
                HOperatorSet.CountChannels(hImageObj, out channels);
                //如果是单通道
                if (channels.I == 1)
                {
                    HTuple imagePointer;
                    HOperatorSet.GetImagePointer1(hImageObj, out imagePointer, out imageType, out imageWidth, out imageHeight);
                    imageBaseData.Width = imageWidth.I;
                    imageBaseData.Height = imageHeight.I;
                    imageBaseData.Pixelformat = (int)VMPixelFormat.VM_PIXEL_MONO_08;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    imageBaseData.DataLen = (uint)(stride * imageBaseData.Height);
                    imageBaseData.ImageData = new byte[stride * imageHeight.I];
                    Marshal.Copy(imagePointer, imageBaseData.ImageData, 0, stride * imageHeight.I);
                }
                //如果是三通道
                else if (channels.I == 3)
                {
                    HTuple redChannel;
                    HTuple greenChannel;
                    HTuple blueChannel;
                    HOperatorSet.GetImagePointer3(hImageObj, out redChannel, out greenChannel, out blueChannel, out imageType, out imageWidth, out imageHeight);
                    imageBaseData.Width = imageWidth.I;
                    imageBaseData.Height = imageHeight.I;
                    imageBaseData.Pixelformat = (int)VMPixelFormat.VM_PIXEL_RGB24_C3;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    imageBaseData.DataLen = (uint)(stride * imageBaseData.Height * 3);
                    imageBaseData.ImageData = new byte[stride * imageHeight.I * 3];
                    byte[] imageRedBuffer = new byte[stride * imageHeight.I];
                    byte[] imageGreenBuffer = new byte[stride * imageHeight.I];
                    byte[] imageBlueBuffer = new byte[stride * imageHeight.I];
                    Marshal.Copy(redChannel.IP, imageRedBuffer, 0, imageRedBuffer.Length);
                    Marshal.Copy(greenChannel.IP, imageGreenBuffer, 0, imageGreenBuffer.Length);
                    Marshal.Copy(blueChannel.IP, imageBlueBuffer, 0, imageBlueBuffer.Length);
                    for (int row = 0; row < imageHeight.I; row++)
                    {
                        for (int col = 0, index = 0; col < imageWidth.I; col++, index += 3)
                        {
                            imageBaseData.ImageData[index] = imageRedBuffer[row * imageWidth + col];
                            imageBaseData.ImageData[index + 1] = imageGreenBuffer[row * imageWidth + col];
                            imageBaseData.ImageData[index + 2] = imageBlueBuffer[row * imageWidth + col];
                        }
                    }
                }
                else
                {
                    hImageObj?.Dispose();
                    throw new Exception("不支持单通道,三通道以外的图像");
                }
            }
            else
            {
                hImageObj?.Dispose();
                throw new Exception("不支持8bit以外的位深度图像");
            }
        }
        else
        {
            hImageObj?.Dispose();
            throw new Exception("HObject非图像类型对象");
        }
        return imageBaseData;
    }
    catch (Exception ex)
    {
        hImageObj?.Dispose();
        throw new Exception(ex.Message);
    }
}

3 Halcon图像转模块输入(InputImageData)

public static InputImageData HalconImageToModuleInputImage(HObject hImageObj)
{
    try
    {
        InputImageData inputImageData = new InputImageData();
        HTuple imageWidth = 0;
        HTuple imageHeight = 0;
        HTuple objClass = hImageObj.GetObjClass();
        if (objClass.S.Equals("image"))
        {
            HTuple imageType;
            HOperatorSet.GetImageType(hImageObj, out imageType);
            if (imageType.S.Equals("byte"))
            {
                //获取图像通道数
                HTuple channels = 0;
                HOperatorSet.CountChannels(hImageObj, out channels);
                //如果是单通道
                if (channels.I == 1)
                {
                    HTuple imagePointer;
                    HOperatorSet.GetImagePointer1(hImageObj, out imagePointer, out imageType, out imageWidth, out imageHeight);
                    inputImageData.Width = imageWidth.I;
                    inputImageData.Height = imageHeight.I;
                    inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_MONO8;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    inputImageData.DataLen = (uint)(stride * inputImageData.Height);
                    inputImageData.Data = imagePointer;
                    inputImageData.Names.DataName = "InImage";
                    inputImageData.Names.WidthName = "InImageWidth";
                    inputImageData.Names.HeightName = "InImageHeight";
                    inputImageData.Names.PixelFormatName = "InImagePixelFormat";
                }
                //如果是三通道
                else if (channels.I == 3)
                {
                    HTuple redChannel;
                    HTuple greenChannel;
                    HTuple blueChannel;
                    HOperatorSet.GetImagePointer3(hImageObj, out redChannel, out greenChannel, out blueChannel, out imageType, out imageWidth, out imageHeight);
                    inputImageData.Width = imageWidth.I;
                    inputImageData.Height = imageHeight.I;
                    inputImageData.Pixelformat = ImagePixelFormat.IMAGE_PIXEL_FORMAT_RGB24;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    byte[] imageRedBuffer = new byte[stride * imageHeight.I];
                    byte[] imageGreenBuffer = new byte[stride * imageHeight.I];
                    byte[] imageBlueBuffer = new byte[stride * imageHeight.I];
                    Marshal.Copy(redChannel.IP, imageRedBuffer, 0, imageRedBuffer.Length);
                    Marshal.Copy(greenChannel.IP, imageGreenBuffer, 0, imageGreenBuffer.Length);
                    Marshal.Copy(blueChannel.IP, imageBlueBuffer, 0, imageBlueBuffer.Length);
                    byte[] imageBuffer = new byte[stride * imageHeight * 3];
                    for (int row = 0; row < imageHeight.I; row++)
                    {
                        for (int col = 0, index = 0; col < imageWidth.I; col++, index += 3)
                        {
                            imageBuffer[index] = imageRedBuffer[row * imageWidth + col];
                            imageBuffer[index + 1] = imageGreenBuffer[row * imageWidth + col];
                            imageBuffer[index + 2] = imageBlueBuffer[row * imageWidth + col];
                        }
                    }
                    inputImageData.DataLen = (uint)(stride * inputImageData.Height * 3);
                    inputImageData.Data = Marshal.UnsafeAddrOfPinnedArrayElement(imageBuffer, 0);
                    inputImageData.Names.DataName = "InImage";
                    inputImageData.Names.WidthName = "InImageWidth";
                    inputImageData.Names.HeightName = "InImageHeight";
                    inputImageData.Names.PixelFormatName = "InImagePixelFormat";
                }
                else
                {
                    hImageObj?.Dispose();
                    throw new Exception("不支持单通道,三通道以外的图像");
                }
            }
            else
            {
                hImageObj?.Dispose();
                throw new Exception("不支持8bit以外的位深度图像");
            }
        }
        else
        {
            hImageObj?.Dispose();
            throw new Exception("HObject非图像类型对象");
        }
        return inputImageData;
    }
    catch (Exception ex)
    {
        hImageObj?.Dispose();
        throw new Exception(ex.Message);
    }
}

4 Halcon图像与算子图像(CmvdImage)互转

public static CMvdImage HalconImageToCMvdImage(HObject hImageObj)
{
    try
    {
        CMvdImage image = new CMvdImage();
        HTuple imageWidth = 0;
        HTuple imageHeight = 0;
        HTuple objClass = hImageObj.GetObjClass();
        if (objClass.S.Equals("image"))
        {
            HTuple imageType;
            HOperatorSet.GetImageType(hImageObj, out imageType);
            if (imageType.S.Equals("byte"))
            {
                //获取图像通道数
                HTuple channels = 0;
                HOperatorSet.CountChannels(hImageObj, out channels);
                //如果是单通道
                if (channels.I == 1)
                {
                    HTuple imagePointer;
                    HOperatorSet.GetImagePointer1(hImageObj, out imagePointer, out imageType, out imageWidth, out imageHeight);
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    MVD_IMAGE_DATA_INFO imageDataInfo = new MVD_IMAGE_DATA_INFO();
                    imageDataInfo.stDataChannel = new MVD_DATA_CHANNEL_INFO[4];
                    imageDataInfo.stDataChannel[0] = new MVD_DATA_CHANNEL_INFO();
                    imageDataInfo.stDataChannel[0].arrDataBytes = new byte[stride * imageHeight.I];
                    imageDataInfo.stDataChannel[0].nRowStep = (uint)stride;
                    imageDataInfo.stDataChannel[0].nSize = (uint)(stride * imageHeight.I);
                    imageDataInfo.stDataChannel[0].nLen = (uint)(imageWidth.I * imageHeight.I);
                    Marshal.Copy(imagePointer, imageDataInfo.stDataChannel[0].arrDataBytes, 0, stride * imageHeight.I);
                    image.InitImage((uint)imageWidth.I, (uint)imageHeight.I, MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08, imageDataInfo);
                }
                //如果是三通道
                else if (channels.I == 3)
                {
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    MVD_IMAGE_DATA_INFO imageDataInfo = new MVD_IMAGE_DATA_INFO();
                    imageDataInfo.stDataChannel = new MVD_DATA_CHANNEL_INFO[4];
                    imageDataInfo.stDataChannel[0] = new MVD_DATA_CHANNEL_INFO();
                    imageDataInfo.stDataChannel[0].arrDataBytes = new byte[stride * imageHeight.I * 3];
                    imageDataInfo.stDataChannel[0].nRowStep = (uint)stride;
                    imageDataInfo.stDataChannel[0].nSize = (uint)(stride * imageHeight.I * 3);
                    imageDataInfo.stDataChannel[0].nLen = (uint)(imageWidth.I * imageHeight.I * 3);
                    HTuple redChannel;
                    HTuple greenChannel;
                    HTuple blueChannel;
                    HOperatorSet.GetImagePointer3(hImageObj, out redChannel, out greenChannel, out blueChannel, out imageType, out imageWidth, out imageHeight);
                    byte[] imageRedBuffer = new byte[stride * imageHeight.I];
                    byte[] imageGreenBuffer = new byte[stride * imageHeight.I];
                    byte[] imageBlueBuffer = new byte[stride * imageHeight.I];
                    Marshal.Copy(redChannel.IP, imageRedBuffer, 0, imageRedBuffer.Length);
                    Marshal.Copy(greenChannel.IP, imageGreenBuffer, 0, imageGreenBuffer.Length);
                    Marshal.Copy(blueChannel.IP, imageBlueBuffer, 0, imageBlueBuffer.Length);
                    for (int row = 0; row < imageHeight.I; row++)
                    {
                        for (int col = 0, index = 0; col < imageWidth.I; col++, index += 3)
                        {
                            imageDataInfo.stDataChannel[0].arrDataBytes[index] = imageRedBuffer[row * imageWidth + col];
                            imageDataInfo.stDataChannel[0].arrDataBytes[index + 1] = imageGreenBuffer[row * imageWidth + col];
                            imageDataInfo.stDataChannel[0].arrDataBytes[index + 2] = imageBlueBuffer[row * imageWidth + col];
                        }
                    }
                    image.InitImage((uint)imageWidth.I, (uint)imageHeight.I, MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3, imageDataInfo);
                }
                else
                {
                    hImageObj?.Dispose();
                    throw new Exception("不支持单通道,三通道以外的图像");
                }
            }
            else
            {
                hImageObj?.Dispose();
                throw new Exception("不支持8bit以外的位深度图像");
            }
        }
        else
        {
            hImageObj?.Dispose();
            throw new Exception("HObject非图像类型对象");
        }
        return image;
    }
    catch (Exception ex)
    {
        hImageObj?.Dispose();
        throw new Exception(ex.Message);
    }
}
public static HObject CMvdImageToHalconImage(CMvdImage image)
{
    IntPtr imagePointer = IntPtr.Zero;
    IntPtr redChannel = IntPtr.Zero;
    IntPtr greenChannel = IntPtr.Zero;
    IntPtr blueChannel = IntPtr.Zero;
    try
    {
        HObject imageObj = new HObject();
        HTuple width = image.Width;
        HTuple height = image.Height;
        if (image.PixelFormat == MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08)
        {
            imagePointer = Marshal.AllocHGlobal(image.GetImageData(0).arrDataBytes.Length);
            Marshal.Copy(image.GetImageData(0).arrDataBytes, 0, imagePointer, image.GetImageData(0).arrDataBytes.Length);
            HOperatorSet.GenImage1(out imageObj, "byte", width, height, imagePointer);
        }
        else if (image.PixelFormat == MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3)
        {
            int stride = width;
            if (stride % 4 != 0)
            {
                stride += 4 - stride % 4;
            }
            byte[] imageRedBuffer = new byte[stride * height.I];
            byte[] imageGreenBuffer = new byte[stride * height.I];
            byte[] imageBlueBuffer = new byte[stride * height.I];
            for (int row = 0; row < height.I; row++)
            {
                for (int col = 0, index = 0; col < width.I; col++, index += 3)
                {
                    imageRedBuffer[row * width.I + col] = image.GetImageData(0).arrDataBytes[index];
                    imageGreenBuffer[row * width.I + col] = image.GetImageData(0).arrDataBytes[index + 1];
                    imageBlueBuffer[row * width.I + col] = image.GetImageData(0).arrDataBytes[index + 2];
                }
            }
            HOperatorSet.GenImage3(
                out imageObj,
                "byte",
                width,
                height,
                Marshal.UnsafeAddrOfPinnedArrayElement(imageRedBuffer, 0),
                Marshal.UnsafeAddrOfPinnedArrayElement(imageGreenBuffer, 0),
                Marshal.UnsafeAddrOfPinnedArrayElement(imageBlueBuffer, 0));
        }
        return imageObj;
    }
    catch (Exception ex)
    {
        Marshal.FreeHGlobal(imagePointer);
        Marshal.FreeHGlobal(redChannel);
        Marshal.FreeHGlobal(greenChannel);
        Marshal.FreeHGlobal(blueChannel);
        throw new Exception(ex.Message);
    }
}

5 流程输出(ImageBaseData_V2)转Halcon图像

public static HObject ImageBaseDataV2ToHalconImage(ImageBaseData_V2 image)
{
    try
    {
        HObject imageObj = new HObject();
        HTuple width = image.Width;
        HTuple height = image.Height;
        if (image.Pixelformat == VMPixelFormat.VM_PIXEL_MONO_08)
        {
            HOperatorSet.GenImage1(out imageObj, "byte", width, height, image.ImageData);
        }
        else if (image.Pixelformat == VMPixelFormat.VM_PIXEL_RGB24_C3)
        {
            int stride = width.I;
            if (stride % 4 != 0)
            {
                stride += 4 - stride % 4;
            }
            byte[] imageRedBuffer = new byte[stride * height.I];
            byte[] imageGreenBuffer = new byte[stride * height.I];
            byte[] imageBlueBuffer = new byte[stride * height.I];
            byte[] imageBuffer = new byte[stride * height.I * 3];
            Marshal.Copy(image.ImageData, imageBuffer, 0, imageBuffer.Length);
            for (int row = 0; row < height.I; row++)
            {
                for (int col = 0, index = 0; col < width.I; col++, index += 3)
                {
                    imageRedBuffer[row * width.I + col] = imageBuffer[index];
                    imageGreenBuffer[row * width.I + col] = imageBuffer[index + 1];
                    imageBlueBuffer[row * width.I + col] = imageBuffer[index + 2];
                }
            }
            HOperatorSet.GenImage3(
                out imageObj,
                "byte",
                width,
                height,
                Marshal.UnsafeAddrOfPinnedArrayElement(imageRedBuffer, 0),
                Marshal.UnsafeAddrOfPinnedArrayElement(imageGreenBuffer, 0),
                Marshal.UnsafeAddrOfPinnedArrayElement(imageBlueBuffer, 0));
        }
        return imageObj;
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}

6 halcon图像与脚本图像(ImageData)互转

public static ImageData HalconImageToImageData(HObject hImageObj)
{
    try
    {
        ImageData imageData = new ImageData();
        HTuple imageWidth = 0;
        HTuple imageHeight = 0;
        HTuple objClass = hImageObj.GetObjClass();
        if (objClass.S.Equals("image"))
        {
            HTuple imageType;
            HOperatorSet.GetImageType(hImageObj, out imageType);
            if (imageType.S.Equals("byte"))
            {
                //获取图像通道数
                HTuple channels = 0;
                HOperatorSet.CountChannels(hImageObj, out channels);
                //如果是单通道
                if (channels.I == 1)
                {
                    HTuple imagePointer;
                    HOperatorSet.GetImagePointer1(hImageObj, out imagePointer, out imageType, out imageWidth, out imageHeight);
                    imageData.Width = imageWidth.I;
                    imageData.Heigth = imageHeight.I;
                    imageData.PixelFormat = ImagePixelFormate.MONO8;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    imageData.Buffer = new byte[stride * imageHeight.I];
                    Marshal.Copy(imagePointer, imageData.Buffer, 0, stride * imageHeight.I);
                }
                //如果是三通道
                else if (channels.I == 3)
                {
                    HTuple redChannel;
                    HTuple greenChannel;
                    HTuple blueChannel;
                    HOperatorSet.GetImagePointer3(hImageObj, out redChannel, out greenChannel, out blueChannel, out imageType, out imageWidth, out imageHeight);
                    imageData.Width = imageWidth.I;
                    imageData.Heigth = imageHeight.I;
                    imageData.PixelFormat = ImagePixelFormate.RGB24;
                    int stride = imageWidth.I;
                    if (stride % 4 != 0)
                    {
                        stride += 4 - stride % 4;
                    }
                    imageData.Buffer = new byte[stride * imageHeight.I * 3];
                    byte[] imageRedBuffer = new byte[stride * imageHeight.I];
                    byte[] imageGreenBuffer = new byte[stride * imageHeight.I];
                    byte[] imageBlueBuffer = new byte[stride * imageHeight.I];
                    Marshal.Copy(redChannel.IP, imageRedBuffer, 0, imageRedBuffer.Length);
                    Marshal.Copy(greenChannel.IP, imageGreenBuffer, 0, imageGreenBuffer.Length);
                    Marshal.Copy(blueChannel.IP, imageBlueBuffer, 0, imageBlueBuffer.Length);
                    for (int row = 0; row < imageHeight.I; row++)
                    {
                        for (int col = 0, index = 0; col < imageWidth.I; col++, index += 3)
                        {
                            imageData.Buffer[index] = imageRedBuffer[row * imageWidth + col];
                            imageData.Buffer[index + 1] = imageGreenBuffer[row * imageWidth + col];
                            imageData.Buffer[index + 2] = imageBlueBuffer[row * imageWidth + col];
                        }
                    }
                }
                else
                {
                    hImageObj?.Dispose();
                    throw new Exception("不支持单通道,三通道以外的图像");
                }
            }
            else
            {
                hImageObj?.Dispose();
                throw new Exception("不支持8bit以外的位深度图像");
            }
        }
        else
        {
            hImageObj?.Dispose();
            throw new Exception("HObject非图像类型对象");
        }
        return imageData;
    }
    catch (Exception ex)
    {
        hImageObj?.Dispose();
        throw new Exception(ex.Message);
    }
}
public static HObject ImageDataToHalconImage(ImageData image)
{
    IntPtr imagePointer = IntPtr.Zero;
    IntPtr redChannel = IntPtr.Zero;
    IntPtr greenChannel = IntPtr.Zero;
    IntPtr blueChannel = IntPtr.Zero;
    try
    {
        HObject imageObj = new HObject();
        HTuple width = image.Width;
        HTuple height = image.Heigth;
        if (image.PixelFormat == ImagePixelFormate.MONO8)
        {
            imagePointer = Marshal.AllocHGlobal(image.Buffer.Length);
            Marshal.Copy(image.Buffer, 0, imagePointer, image.Buffer.Length);
            HOperatorSet.GenImage1(out imageObj, "byte", width, height, imagePointer);
        }
        else if (image.PixelFormat == ImagePixelFormate.RGB24)
        {
            byte[] imageRedBuffer = new byte[image.Buffer.Length / 3];
            byte[] imageGreBuffer = new byte[image.Buffer.Length / 3];
            byte[] imageBluBuffer = new byte[image.Buffer.Length / 3];
            int index = 0;
            for (int i = 0; i < image.Buffer.Length; index++, i += 3)
            {
                imageRedBuffer[index] = image.Buffer[i];
                imageGreBuffer[index] = image.Buffer[i + 1];
                imageBluBuffer[index] = image.Buffer[i + 2];
            }
            redChannel = Marshal.AllocHGlobal(imageRedBuffer.Length);
            greenChannel = Marshal.AllocHGlobal(imageGreBuffer.Length);
            blueChannel = Marshal.AllocHGlobal(imageBluBuffer.Length);
            Marshal.Copy(imageRedBuffer, 0, redChannel, imageRedBuffer.Length);
            Marshal.Copy(imageGreBuffer, 0, greenChannel, imageGreBuffer.Length);
            Marshal.Copy(imageBluBuffer, 0, blueChannel, imageBluBuffer.Length);
            HOperatorSet.GenImage3(out imageObj, "byte", width, height, redChannel, greenChannel, blueChannel);
        }
        return imageObj;
    }
    catch (Exception ex)
    {
        Marshal.FreeHGlobal(imagePointer);
        Marshal.FreeHGlobal(redChannel);
        Marshal.FreeHGlobal(greenChannel);
        Marshal.FreeHGlobal(blueChannel);
        throw new Exception(ex.Message);
    }
}

问题根因
不熟悉Halcon图像转换为其它类型

3.6 流程图像与算子图像互转

描述
环境:VM4.2 + VS2013及以上
现象:流程图像与算子图像互转
解答
VM SDK开发中流程输入输出图像都是ImageBaseData_V2,算子SDK开发中算子输入输出图像都是CmvdImage,两者可以实现互转。
1 流程图像转算子图像

public CMvdImage ImageBaseData_V2ToCMvdImage(ImageBaseData_V2 ImageBaseDataV2)
{
    VisionDesigner.CMvdImage cmvdImage = new VisionDesigner.CMvdImage();
    VisionDesigner.MVD_IMAGE_DATA_INFO stImageData = new VisionDesigner.MVD_IMAGE_DATA_INFO();
    if (VMPixelFormat.VM_PIXEL_MONO_08 == ImageBaseDataV2.Pixelformat)
    {
        stImageData.stDataChannel[0].nRowStep = (uint)ImageBaseDataV2.Width;
        stImageData.stDataChannel[0].nLen = (uint)(ImageBaseDataV2.Width * ImageBaseDataV2.Height);
        stImageData.stDataChannel[0].nSize = (uint)(ImageBaseDataV2.Width * ImageBaseDataV2.Height);
        byte[] m_BufForDriver1 = new byte[ImageBaseDataV2.Width * ImageBaseDataV2.Height];
        //数据Copy
        Marshal.Copy(ImageBaseDataV2.ImageData, m_BufForDriver1, 0, ((int)ImageBaseDataV2.Width * ImageBaseDataV2.Height));
        stImageData.stDataChannel[0].arrDataBytes = m_BufForDriver1;
        //初始化CMvdImage
        cmvdImage.InitImage((uint)ImageBaseDataV2.Width, (uint)ImageBaseDataV2.Height, MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08, stImageData);
    }
    else if (VMPixelFormat.VM_PIXEL_RGB24_C3 == ImageBaseDataV2.Pixelformat)
    {
        stImageData.stDataChannel[0].nRowStep = (uint)ImageBaseDataV2.Width * 3;
        stImageData.stDataChannel[0].nLen = (uint)(ImageBaseDataV2.Width * ImageBaseDataV2.Height * 3);
        stImageData.stDataChannel[0].nSize = (uint)(ImageBaseDataV2.Width * ImageBaseDataV2.Height * 3);
        byte[] m_BufForDriver1 = new byte[3 * (ImageBaseDataV2.Width * ImageBaseDataV2.Height)];
        //数据Copy
        Marshal.Copy(ImageBaseDataV2.ImageData, m_BufForDriver1, 0, ((int)(ImageBaseDataV2.Width * ImageBaseDataV2.Height) * 3));
        stImageData.stDataChannel[0].arrDataBytes = m_BufForDriver1;
        //初始化CMvdImage
        cmvdImage.InitImage((uint)ImageBaseDataV2.Width, (uint)ImageBaseDataV2.Height, MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3, stImageData);
    }
    return cmvdImage;
}

2 算子图像转流程图像

public ImageBaseData_V2 CMvdImageToImageBaseData_V2(CMvdImage cmvdImage)
{
    VM.PlatformSDKCS.ImageBaseData_V2 ImageBaseDataV2 = null;
    if (MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08 == cmvdImage.PixelFormat)
    {
        var cmvdImageData = cmvdImage.GetImageData();
        IntPtr imagedata = Marshal.AllocHGlobal(cmvdImageData.stDataChannel[0].arrDataBytes.Length);
        Marshal.Copy(cmvdImageData.stDataChannel[0].arrDataBytes, 0, imagedata, cmvdImageData.stDataChannel[0].arrDataBytes.Length);
        ImageBaseDataV2 = new ImageBaseData_V2(imagedata, (uint)cmvdImageData.stDataChannel[0].arrDataBytes.Length, (int)cmvdImage.Width, (int)cmvdImage.Height, VMPixelFormat.VM_PIXEL_MONO_08);
        //使用结束后需要手动释放
        //Marshal.FreeHGlobal(imagedata);
        //imagedata = IntPtr.Zero;
    }
    else if (MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3 == cmvdImage.PixelFormat)
    {

        var cmvdImageData = cmvdImage.GetImageData();
        IntPtr imagedata = Marshal.AllocHGlobal(cmvdImageData.stDataChannel[0].arrDataBytes.Length);
        Marshal.Copy(cmvdImageData.stDataChannel[0].arrDataBytes, 0, imagedata, cmvdImageData.stDataChannel[0].arrDataBytes.Length);
        ImageBaseDataV2 = new ImageBaseData_V2(imagedata, (uint)cmvdImageData.stDataChannel[0].arrDataBytes.Length, (int)cmvdImage.Width, (int)cmvdImage.Height, VMPixelFormat.VM_PIXEL_RGB24_C3);
        //使用结束后需要手动释放
        //Marshal.FreeHGlobal(imagedata);
        //imagedata = IntPtr.Zero;
    }
    return ImageBaseDataV2;
}

问题根因
不熟悉流程图像与算子图像互转

3.7 图像转换扫盲篇(C++)

描述
环境:VM4.2 + VS2013及以上
现象:有哪些图像类型可以进行转换?
解答
1 图像格式一览
除了QImage、Mat和Halcon中的图像类型,在VM和开发(二次开发包含三种:VM SDK开发、算子SDK开发、算法模块开发)中涉及的图像类型如下:
相机:图像数据流(此处图像数据流类型是MyCamera.MV_FRAME_OUT,是来自MvCameraControl.Net.dll,即海康机器人工业相机SDK,在MVS SDK和算子SDK中都有这个dll;算子SDK的MVDCamera.Net.dll也可以进行相机取流,它是对MvCameraControl.Net.dll的二次封装,用MVDCamera.Net.dll时,图像数据流类型是IMvdImage);
VM:脚本输入图像(图像类型是ImageData,是C#中图像类型);
VM SDK:流程输入图像(IoImage)、Group输入图像(IoImage)、图像源SDK输入图像(ImageBaseData)、模块输入图像(ImageBaseData);
算子SDK:输入图像(IMvdImage);
算法模块:输入图像(HKA_IMAGE)。
2 图像类型转换(含单通道和三通道图像)三通道的Mat为BGR,三通道QImage、VM和二次开发为RGB,针对常用图像转换场景,列举如下(见3.8-3.13)。篇幅所致,后续每种转换用函数表达,函数输入某种图像类型,返回某种图像类型。

3.8 相机采图转流程输入、Group输入、图像源SDK输入、模块输入、算子输入图像

描述
环境:VM4.2 + VS2013及以上
现象:相机采图转换成其他图像类型
解答
相机采图(MyCamera.MV_FRAME_OUT)转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像。
1相机采图转流程输入(IoImage)、Group输入(IoImage)

IoImage MV_FRAME_OUTToProcedureIoImage(MV_FRAME_OUT stImageInfo)
{
	// TODO: 在此处添加实现代码.
	IoImage ioImage{};
	unsigned char* m_pSaveImageBuf = NULL;//建议在头文件声明,控制释放时机防止内存泄漏,写在此处为了方便参考
	m_pSaveImageBuf = (unsigned char*)malloc(sizeof(unsigned char) * stImageInfo.stFrameInfo.nFrameLen);
	memcpy(m_pSaveImageBuf, stImageInfo.pBufAddr, stImageInfo.stFrameInfo.nFrameLen);

	ioImage.stImage.Width = stImageInfo.stFrameInfo.nWidth;
	ioImage.stImage.Height = stImageInfo.stFrameInfo.nHeight;
	ioImage.stImage.DataLen = stImageInfo.stFrameInfo.nFrameLen;
	ioImage.stImage.ImageData = m_pSaveImageBuf;
	if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_Mono8)
	{
		ioImage.stImage.Pixelformat = MvdPixelFormat::MVD_PIXEL_MONO_08;
	}
	else if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_RGB8_Packed)
	{
		ioImage.stImage.Pixelformat = MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3;
	}
	return ioImage;
}

2相机采图转图像源SDK输入(ImageBaseData)、模块输入(ImageBaseData)

ImageBaseData MV_FRAME_OUTToImageBaseData(MV_FRAME_OUT stImageInfo)
{
	// TODO: 在此处添加实现代码.
	ImageBaseData imageBaseData{};
	unsigned char* m_pSaveImageBuf = NULL;//建议在头文件声明,控制释放时机防止内存泄漏,写在此处为了方便参考
	m_pSaveImageBuf = (unsigned char*)malloc(sizeof(unsigned char) * stImageInfo.stFrameInfo.nFrameLen);
	memcpy(m_pSaveImageBuf, stImageInfo.pBufAddr, stImageInfo.stFrameInfo.nFrameLen);

	imageBaseData.Width = stImageInfo.stFrameInfo.nWidth;
	imageBaseData.Height = stImageInfo.stFrameInfo.nHeight;
	imageBaseData.DataLen = stImageInfo.stFrameInfo.nFrameLen;
	imageBaseData.ImageData = m_pSaveImageBuf;
	if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_Mono8)
	{
		imageBaseData.Pixelformat = MvdPixelFormat::MVD_PIXEL_MONO_08;
	}
	else if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_RGB8_Packed)
	{
		imageBaseData.Pixelformat = MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3;
	}

	return imageBaseData;
}

3相机采图转算子输入(IMvdImage)

IMvdImage* MV_FRAME_OUTToIMvdImage(MV_FRAME_OUT stImageInfo)
{
	// TODO: 在此处添加实现代码.
	IMvdImage* iMvdImage = NULL;
	unsigned char* m_pSaveImageBuf = NULL;//建议在头文件声明,控制释放时机防止内存泄漏,写在此处为了方便参考
	m_pSaveImageBuf = (unsigned char*)malloc(sizeof(unsigned char) * stImageInfo.stFrameInfo.nFrameLen);
	memcpy(m_pSaveImageBuf, stImageInfo.pBufAddr, stImageInfo.stFrameInfo.nFrameLen);
	MVD_IMAGE_DATA_INFO stImageData{ };

	if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_Mono8)
	{
		stImageData.stDataChannel[0].nRowStep = stImageInfo.stFrameInfo.nWidth;
		stImageData.stDataChannel[0].nLen = stImageInfo.stFrameInfo.nFrameLen;
		stImageData.stDataChannel[0].nSize = stImageInfo.stFrameInfo.nFrameLen;
		stImageData.stDataChannel[0].pData = m_pSaveImageBuf;
		iMvdImage->InitImage(stImageInfo.stFrameInfo.nWidth, stImageInfo.stFrameInfo.nHeight, VisionDesigner::_MVD_PIXEL_FORMAT_::MVD_PIXEL_MONO_08, stImageData);
	}
	else if (stImageInfo.stFrameInfo.enPixelType == PixelType_Gvsp_RGB8_Packed)
	{
		stImageData.stDataChannel[0].nRowStep = stImageInfo.stFrameInfo.nWidth*3;
		stImageData.stDataChannel[0].nLen = stImageInfo.stFrameInfo.nFrameLen;
		stImageData.stDataChannel[0].nSize = stImageInfo.stFrameInfo.nFrameLen;
		stImageData.stDataChannel[0].pData = m_pSaveImageBuf;
		iMvdImage->InitImage(stImageInfo.stFrameInfo.nWidth, stImageInfo.stFrameInfo.nHeight, VisionDesigner::_MVD_PIXEL_FORMAT_::MVD_PIXEL_BGR_BGR24_C3, stImageData);
	}

	return iMvdImage;
}

问题根因
不熟悉相机采图转换为其它类型

3.9 QImage转流程输入、Group输入、图像源SDK输入、模块输入、算子输入、流程输出图像

描述
环境:VM4.2 + VS2013及以上
现象:QImage转换成其他图像类型
解答
QImage转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像,流程输出图像转换为Bitmap。
1 QImage转流程输入(IoImage)、Group输入(IoImage)

IoImage QImageToIoImage(QImage qImage)
{
    QString strReMsg = "";
    IoImage ioImage;
    switch (qImage.format())
    {
    case QImage::Format_Indexed8:
        ioImage.stImage.Width=qImage.width();
        ioImage.stImage.Height=qImage.height();
        ioImage.stImage.DataLen=qImage.sizeInBytes();
        ioImage.stImage.Pixelformat=_MvdPixelFormat_::MVD_PIXEL_MONO_08;
        ioImage.stImage.ImageData=(void *)qImage.constBits();
        //ioImage.stImage.ImageData=qImage.data_ptr();
        //QImage(ioImage.stImage.ImageData,ioImage.stImage.Width,ioImage.stImage.Width,QImage::Format_RGB888);
        break;       
    case QImage::Format_RGB888:
        ioImage.stImage.Width=qImage.width();
        ioImage.stImage.Height=qImage.height();
        ioImage.stImage.DataLen=qImage.sizeInBytes();
        ioImage.stImage.Pixelformat=_MvdPixelFormat_::MVD_PIXEL_RGB_RGB24_C3;
        ioImage.stImage.ImageData=(void *)qImage.constBits();
        break;
    }
    strReMsg = "QImageToIoImage s uccess.";
    ui->textEdit->append(strReMsg);
    return ioImage;
}

2 QImage转图像源SDK输入(ImageBaseData)、模块输入(ImageBaseData)

ImageBaseData QImageToImageBaseData(QImage qImage)
{
    ImageBaseData  imageBaseData;
    switch (qImage.format())
    {
    case QImage::Format_Indexed8:
        imageBaseData.Width=qImage.width();
        imageBaseData.Height=qImage.height();
        imageBaseData.DataLen=qImage.sizeInBytes();
        imageBaseData.Pixelformat=_MvdPixelFormat_::MVD_PIXEL_MONO_08;
        imageBaseData.ImageData=(void *)qImage.constBits();
        //ioImage.stImage.ImageData=qImage.data_ptr();
        break;
    case QImage::Format_RGB888:
        imageBaseData.Width=qImage.width();
        imageBaseData.Height=qImage.height();
        imageBaseData.DataLen=qImage.sizeInBytes();
        imageBaseData.Pixelformat=_MvdPixelFormat_::MVD_PIXEL_RGB_RGB24_C3;
        imageBaseData.ImageData=(void *)qImage.constBits();
        break;
    }
    return imageBaseData;
}

3 Qimage与算子图像(IMvdImage)互转

IMvdImage* QImageToIMvdImage(QImage qImage)
{
    IMvdImage* iMvdImage;
    CreateImageInstance(&iMvdImage);
    MVD_IMAGE_DATA_INFO stImageData;
    switch (qImage.format())
    {
    case QImage::Format_Indexed8:
        stImageData.stDataChannel[0].nRowStep = qImage.width();
        stImageData.stDataChannel[0].nLen = qImage.sizeInBytes();
        stImageData.stDataChannel[0].nSize = qImage.sizeInBytes();
        stImageData.stDataChannel[0].pData = (unsigned char*)qImage.constBits();
        iMvdImage->InitImage(qImage.width(), qImage.height(),MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08, stImageData);
        break;
    case QImage::Format_RGB888:
        stImageData.stDataChannel[0].nRowStep = qImage.width()*3;
        stImageData.stDataChannel[0].nLen = qImage.sizeInBytes();
        stImageData.stDataChannel[0].nSize = qImage.sizeInBytes();
        stImageData.stDataChannel[0].pData = (unsigned char*)qImage.constBits();
        iMvdImage->InitImage(qImage.width(), qImage.height(),MVD_PIXEL_FORMAT::MVD_PIXEL_RGB_RGB24_C3, stImageData);
        break;
    }
    return iMvdImage;
}

//算子转QImage
QImage IMvdImageToQImage(IMvdImage * iMvdImage)
{
    if(iMvdImage->GetPixelFormat() == MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08)
    {
        //QImage qImage((const uchar*)iMvdImage->GetImageData(0)->pData,iMvdImage->GetWidth(),iMvdImage->GetHeight(),iMvdImage->GetImageData(0)->nLen/iMvdImage->GetHeight(),QImage::Format_Indexed8);
        //QImage qImage(iMvdImage->GetImageData(0)->pData,iMvdImage->GetWidth(),iMvdImage->GetHeight(),iMvdImage->GetImageData(0)->nLen/iMvdImage->GetHeight(),QImage::Format_Indexed8);
        QImage qImage((const uchar*)iMvdImage->GetImageData(0)->pData,iMvdImage->GetWidth(),iMvdImage->GetHeight(),QImage::Format_Grayscale8);//Format_Indexed8
        return qImage;
    }
    if(iMvdImage->GetPixelFormat() == MVD_PIXEL_FORMAT::MVD_PIXEL_RGB_RGB24_C3)
    {
        QImage qImage((const uchar*)iMvdImage->GetImageData(0)->pData,iMvdImage->GetWidth(),iMvdImage->GetHeight(),QImage::Format_RGB888);
        return qImage;
    }
}

4 流程输出(IoImage)转QImage

QImage IoImageToQImage(IoImage inIoImage)
{
    if(inIoImage.stImage.Pixelformat == _MvdPixelFormat_::MVD_PIXEL_MONO_08)
    {
        QImage qImage((const uchar*)inIoImage.stImage.ImageData,inIoImage.stImage.Width,inIoImage.stImage.Height,QImage::Format_Grayscale8);
        return qImage;
    }
    if(inIoImage.stImage.Pixelformat == _MvdPixelFormat_::MVD_PIXEL_RGB_RGB24_C3)
    {
        QImage qImage((const uchar*)inIoImage.stImage.ImageData,inIoImage.stImage.Width,inIoImage.stImage.Height,QImage::Format_RGB888);
        return qImage;
    }
}

问题根因
不熟悉QImage转换为其它类型

3.10 Mat与流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出

描述
环境:VM4.2 + VS2013及以上
现象:Mat转换成其他图像类型
解答
Mat转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像,算子输出图像转Mat,流程输出图像转换为Mat。
1 Mat转流程输入(IoImage)、Group输入(IoImage)

IoImage MatToProcedureInputImage(Mat matInputImg)
{
	if (matInputImg.empty())
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_PARAMETER_ILLEGAL);
	}
	if ((CV_8UC1 != matInputImg.type()) && (CV_8UC3 != matInputImg.type()))
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_SUPPORT);
	}

	IoImage  m_pIoImage{};
	uint dataLen = (uint)(matInputImg.cols * matInputImg.rows * matInputImg.channels());
	CString strReMsg = _T("");
	try
	{
		if (CV_8UC1 == matInputImg.type())
		{
			m_pIoImage.stImage.Width = matInputImg.cols;
			m_pIoImage.stImage.Width = matInputImg.cols;
			m_pIoImage.stImage.Height = matInputImg.rows;
			m_pIoImage.stImage.DataLen = dataLen;
			m_pIoImage.stImage.Pixelformat = _MvdPixelFormat_::MVD_PIXEL_MONO_08;
			m_pIoImage.stImage.ImageData = matInputImg.ptr(0);
		}
		else if (CV_8UC3 == matInputImg.type())
		{
			cv::cvtColor(matInputImg, matInputImg, CV_BGR2RGB);
			m_pIoImage.stImage.Width = matInputImg.cols;
			m_pIoImage.stImage.Height = matInputImg.rows;
			m_pIoImage.stImage.DataLen = dataLen;
			m_pIoImage.stImage.Pixelformat = _MvdPixelFormat_::MVD_PIXEL_RGB_RGB24_C3;
			m_pIoImage.stImage.ImageData = matInputImg.ptr(0);
		}
	}
	catch (CVmException e)
	{
		strReMsg.Format(_T("%x"), e.GetErrorCode());
		strReMsg = _T("0x") + strReMsg + _T(" == SaveProcedureToFile()");
	}

	return m_pIoImage;
}

2 Mat转图像源SDK输入(ImageBaseData)、模块输出(ImageBaseData)

ImageBaseData MatToImageBaseData(Mat matInputImg)
{
	if (matInputImg.empty())
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_PARAMETER_ILLEGAL);
	}
	if ((CV_8UC1 != matInputImg.type()) && (CV_8UC3 != matInputImg.type()))
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_SUPPORT);
	}

	ImageBaseData  m_pImageBaseData{};
	uint dataLen = (uint)(matInputImg.cols * matInputImg.rows * matInputImg.channels());
	CString strReMsg = _T("");
	try
	{
		if (CV_8UC1 == matInputImg.type())
		{
			m_pImageBaseData.Width = matInputImg.cols;
			m_pImageBaseData.Height = matInputImg.rows;
			m_pImageBaseData.DataLen = dataLen;
			m_pImageBaseData.Pixelformat = _MvdPixelFormat_::MVD_PIXEL_MONO_08;
			m_pImageBaseData.ImageData = matInputImg.ptr(0);
		}
		else if (CV_8UC3 == matInputImg.type())
		{
			cv::cvtColor(matInputImg, matInputImg, CV_BGR2RGB);
			m_pImageBaseData.Width = matInputImg.cols;
			m_pImageBaseData.Height = matInputImg.rows;
			m_pImageBaseData.DataLen = dataLen;
			m_pImageBaseData.Pixelformat = _MvdPixelFormat_::MVD_PIXEL_RGB_RGB24_C3;
			m_pImageBaseData.ImageData = matInputImg.ptr(0);
		}
	}
	catch (CVmException e)
	{
		strReMsg.Format(_T("%x"), e.GetErrorCode());
		strReMsg = _T("0x") + strReMsg + _T(" == SaveProcedureToFile()");
	}

	return m_pImageBaseData;
}

3 Mat与算子图像(IMvdImage)互转

IMvdImage* MatToIMvdImage(Mat& matInputImg)
{
	if (matInputImg.empty())
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_PARAMETER_ILLEGAL);
	}
	if ((CV_8UC1 != matInputImg.type()) && (CV_8UC3 != matInputImg.type()))
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_SUPPORT);
	}

	IMvdImage* pMvdImg = NULL;
	uint dataLen = (uint)(matInputImg.cols * matInputImg.rows * matInputImg.channels());
	try
	{
		int nRet = CreateImageInstance(&pMvdImg);
		if (MVD_OK != nRet)
		{
			throw IMVDException(MVD_MODUL_IMAGE, nRet, "Failed to create image instance.");
		}
		if (CV_8UC1 == matInputImg.type())
		{
			MVD_IMAGE_DATA_INFO stImageData{ };
			stImageData.stDataChannel[0].nRowStep = (uint)matInputImg.cols;
			stImageData.stDataChannel[0].nLen = dataLen;
			stImageData.stDataChannel[0].nSize = dataLen;
			stImageData.stDataChannel[0].pData = matInputImg.ptr(0);
			pMvdImg->InitImage((uint)matInputImg.cols, (uint)matInputImg.rows, VisionDesigner::_MVD_PIXEL_FORMAT_::MVD_PIXEL_MONO_08, stImageData);

		}
		else if (CV_8UC3 == matInputImg.type())
		{
			cv::cvtColor(matInputImg, matInputImg, CV_BGR2RGB);
			MVD_IMAGE_DATA_INFO stImageData{ };
			stImageData.stDataChannel[0].nRowStep = (uint)matInputImg.cols*matInputImg.channels();
			stImageData.stDataChannel[0].nLen = dataLen;
			stImageData.stDataChannel[0].nSize = dataLen;
			stImageData.stDataChannel[0].pData = matInputImg.ptr(0);
			pMvdImg->InitImage((uint)matInputImg.cols, (uint)matInputImg.rows, VisionDesigner::_MVD_PIXEL_FORMAT_::MVD_PIXEL_RGB_RGB24_C3, stImageData);
		}
	}
	catch (IMVDException &ex)
	{
		if (NULL != pMvdImg)
		{
			DestroyImageInstance(pMvdImg);
			pMvdImg = NULL;
		}
		throw ex;
	}

	return pMvdImg;
}

Mat IMvdImageToMat(IMvdImage* pMvdImg)
{
	Mat stMatImg;

	if (NULL == pMvdImg)
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_PARAMETER_ILLEGAL);
	}
	MVD_PIXEL_FORMAT enSrcPixelFormat = pMvdImg->GetPixelFormat();
	if ((VisionDesigner::MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08 != enSrcPixelFormat) && (VisionDesigner::MVD_PIXEL_FORMAT::MVD_PIXEL_RGB_RGB24_C3 != enSrcPixelFormat))
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_SUPPORT);
	}

	// 根据传入的ImvdImage图像初始化mat
	if (VisionDesigner::MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08 == enSrcPixelFormat)
	{
		stMatImg.create((int)pMvdImg->GetHeight(), (int)pMvdImg->GetWidth(), CV_8UC1);
	}
	else if (VisionDesigner::MVD_PIXEL_FORMAT::MVD_PIXEL_RGB_RGB24_C3 == enSrcPixelFormat)
	{
		stMatImg.create((int)pMvdImg->GetHeight(), (int)pMvdImg->GetWidth(), CV_8UC3);
	}
	if (stMatImg.empty())
	{
		throw IMVDException(MVD_MODUL_APP, MVD_E_RESOURCE);
	}

	// 上述方式为mat分配的内存一定是连续的
	uchar* pdata = stMatImg.ptr<uchar>(0);
	memcpy(pdata, pMvdImg->GetImageData(0)->pData, pMvdImg->GetImageData(0)->nLen);
	if (CV_8UC3 == stMatImg.type())
	{
		cvtColor(stMatImg, stMatImg, CV_RGB2BGR);
	}

	return stMatImg;
}

4 流程输出(IoImage)转Mat

Mat IoImageToMat(IoImage m_pIoImage)
{
	Mat stMatImg;
	CString strReMsg = _T("");
	try
	{
		MvdPixelFormat srcPixelFormat = m_pIoImage.stImage.Pixelformat;
		if ((VisionMasterSDK::MvdPixelFormat::MVD_PIXEL_MONO_08 != srcPixelFormat) && (VisionMasterSDK::MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3 != srcPixelFormat))
		{
			throw CVmException(0xE0000503);
		}
		// 根据传入的IoImage图像初始化mat
		if (VisionMasterSDK::MvdPixelFormat::MVD_PIXEL_MONO_08 == srcPixelFormat)
		{
			stMatImg.create((int)m_pIoImage.stImage.Height, (int)m_pIoImage.stImage.Width, CV_8UC1);
		}
		else if (VisionMasterSDK::MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3 == srcPixelFormat)
		{
			stMatImg.create((int)m_pIoImage.stImage.Height, (int)m_pIoImage.stImage.Width, CV_8UC3);
		}
		if (stMatImg.empty())
		{
			throw IMVDException(MVD_MODUL_APP, MVD_E_RESOURCE);
		}
		// 上述方式为mat分配的内存一定是连续的
		uchar* pdata = stMatImg.ptr<uchar>(0);
		memcpy(pdata, m_pIoImage.stImage.ImageData, m_pIoImage.stImage.DataLen);
		if (CV_8UC3 == stMatImg.type())
		{
			cvtColor(stMatImg, stMatImg, CV_RGB2BGR);
		}
	}
	catch (CVmException e)
	{
		strReMsg.Format(_T("%x"), e.GetErrorCode());
		strReMsg = _T("0x") + strReMsg + _T(" == SaveProcedureToFile()");
	}

	return stMatImg;
}

问题根因
不熟悉Mat转换为其它类型

3.11 Halcon与流程输入、Group输入、图像源SDK输入、模块输入、算子输入、算子输出、流程输出

描述
环境:VM4.2 + VS2013及以上
现象:Halcon转换成其他图像类型
解答
Halcon图像转换为流程输入图像、Group输入图像、图像源SDK输入图像、模块输入图像、算子输入图像,算子输出图像转Halcon图像,流程输出图像转换为Halcon图像。
1 Halcon图像转流程输入(IoImage)、Group输入(IoImage),HImageToImageBaseData函数的实现见“2 Halcon图像转ImageBaseData“

IoImage HImageToIoImage(HImage image)
{
	IoImage ioImage{};
	ImageBaseData imageBaseData = HImageToImageBaseData(image);
	ioImage.stImage = imageBaseData;
	return ioImage;
}

2 Halcon图像转图像源SDK输入(ImageBaseData)、模块输入(ImageBaseData)

ImageBaseData HImageToImageBaseData(HImage image)
{
	ImageBaseData imageBaseData{};
	//获取图像通道位深度信息
	HString bitdepth = image.GetChannelInfo("type", 1);
	assert(!strcmp(bitdepth.Text(), "byte"));
	int channels = image.CountChannels();
	assert(channels == 1 || channels == 3);
	HString type;
	Hlong width, height;
	//单通道
	if (channels == 1)
	{
		void* imagePtr = image.GetImagePointer1(&type, &width, &height);
		imageBaseData.DataLen = width * height;
		imageBaseData.Width = width;
		imageBaseData.Height = height;
		imageBaseData.Pixelformat = MvdPixelFormat::MVD_PIXEL_MONO_08;
		imageBaseData.ImageData = imagePtr;
	}
	//3通道
	if (channels == 3)
	{
		void* imageRedPtr;
		void* imageGreenPtr;
		void* imageBluePtr;
		image.GetImagePointer3(&imageRedPtr, &imageGreenPtr, &imageBluePtr, &type, &width, &height);
		byte* imageRedBuf = new byte[width * height];
		byte* imageGreenBuf = new byte[width * height];
		byte* imageBlueBuf = new byte[width * height];
		memcpy(imageRedBuf, imageRedPtr, width * height);
		memcpy(imageGreenBuf, imageGreenPtr, width * height);
		memcpy(imageBlueBuf, imageBluePtr, width * height);
		byte* imageBuf = new byte[width * height * 3];
		int index = 0;
		for (int row = 0; row < height; row++)
		{
			for (int col = 0; col < width; col++, index += 3)
			{
				imageBuf[index] = imageRedBuf[row * width + col];
				imageBuf[index + 1] = imageGreenBuf[row * width + col];
				imageBuf[index + 2] = imageBlueBuf[row * width + col];
			}
		}
		delete[] imageRedBuf;
		delete[] imageGreenBuf;
		delete[] imageBlueBuf;
		imageBaseData.DataLen = width * height * 3;
		imageBaseData.Width = width;
		imageBaseData.Height = height;
		imageBaseData.Pixelformat = MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3;
		imageBaseData.ImageData = imageBuf;
	}
	return imageBaseData;
}

3 Halcon图像与算子图像(IMvdImage)互转

IMvdImage* HImageToMvdImage(HImage image)
{
	//获取图像通道位深度信息
	HString bitdepth = image.GetChannelInfo("type", 1);
	assert(!strcmp(bitdepth.Text(), "byte"));
	int channels = image.CountChannels();
	assert(channels == 1 || channels == 3);
	HString type;
	Hlong width, height;
	//单通道
	if (channels == 1)
	{
		IMvdImage* pMvdImage;
		CreateImageInstance(&pMvdImage);
		void* imagePtr = image.GetImagePointer1(&type, &width, &height);
		MVD_IMAGE_DATA_INFO imageDataInfo;
		imageDataInfo.stDataChannel[0].nLen = width * height;
		imageDataInfo.stDataChannel[0].nRowStep = width;
		imageDataInfo.stDataChannel[0].nSize = width * height;
		imageDataInfo.stDataChannel[0].pData = (byte*)imagePtr;
		pMvdImage->InitImage(width, height, MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08, imageDataInfo);
		return pMvdImage;
	}
	//3通道
	else if (channels == 3)
	{
		IMvdImage* pMvdImage;
		CreateImageInstance(&pMvdImage);
		void* imageRedPtr;
		void* imageGreenPtr;
		void* imageBluePtr;
		image.GetImagePointer3(&imageRedPtr, &imageGreenPtr, &imageBluePtr, &type, &width, &height);
		long size = width * height * 3;
		byte* imageRedBuf = new byte[width * height];
		byte* imageGreenBuf = new byte[width * height];
		byte* imageBlueBuf = new byte[width * height];
		memcpy(imageRedBuf, imageRedPtr, width * height);
		memcpy(imageGreenBuf, imageGreenPtr, width * height);
		memcpy(imageBlueBuf, imageBluePtr, width * height);
		byte* imageBuffer = new byte[size];
		int index = 0;
		for (int row = 0; row < height; row++)
		{
			for (int col = 0; col < width; col++, index += 3)
			{
				imageBuffer[index] = imageRedBuf[row * width + col];
				imageBuffer[index + 1] = imageGreenBuf[row * width + col];
				imageBuffer[index + 2] = imageBlueBuf[row * width + col];
			}
		}
		delete[] imageRedBuf;
		delete[] imageGreenBuf;
		delete[] imageBlueBuf;
		MVD_IMAGE_DATA_INFO imageDataInfo{};
		imageDataInfo.stDataChannel[0].nLen = width * height * 3;
		imageDataInfo.stDataChannel[0].nRowStep = width * 3;
		imageDataInfo.stDataChannel[0].nSize = width * height * 3;
		imageDataInfo.stDataChannel[0].pData = imageBuffer;
		try {
			pMvdImage->InitImage(width, height, MVD_PIXEL_FORMAT::MVD_PIXEL_RGB_RGB24_C3, imageDataInfo);
		}
		catch (IMVDException* ex)
		{
			cout << ex->GetDescription() << ex->GetErrorCode() << endl;
		}
		return pMvdImage;
	}
	else
	{
		return nullptr;
	}
}

HImage MvdImageToHImage(IMvdImage* pMvdImage)
{
	HImage image;
	MVD_IMAGE_DATA_INFO* imageDataInfo = pMvdImage->GetImageData();
	if (pMvdImage->GetPixelFormat() == MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08)
	{
		image.GenImage1(
			"byte",
			pMvdImage->GetWidth(),
			pMvdImage->GetHeight(),
			imageDataInfo->stDataChannel[0].pData);
	}
	else if (pMvdImage->GetPixelFormat() == MVD_PIXEL_FORMAT::MVD_PIXEL_RGB_RGB24_C3)
	{
		int width = pMvdImage->GetWidth();
		int height = pMvdImage->GetHeight();
		long size = width * height * 3;
		byte* imageRedBuf = new byte[(long)(width * height)];
		byte* imageGreenBuf = new byte[(long)(width * height)];
		byte* imageBlueBuf = new byte[(long)(width * height)];
		byte* imageBuffer = new byte[size];
		memcpy(imageBuffer, pMvdImage->GetImageData()->stDataChannel[0].pData, size);
		int index = 0;
		for (int row = 0; row < height; row++)
		{
			for (int col = 0; col < width; col++, index += 3)
			{
				imageRedBuf[row * width + col] = imageBuffer[index];
				imageGreenBuf[row * width + col] = imageBuffer[index + 1];
				imageBlueBuf[row * width + col] = imageBuffer[index + 2];
			}
		}
		delete[] imageBuffer;
		image.GenImage3(
			"byte",
			pMvdImage->GetWidth(),
			pMvdImage->GetHeight(),
			imageRedBuf,
			imageGreenBuf,
			imageBlueBuf);
	}
	return image;
}

4 流程输出(IoImage)转Halcon图像

HImage IoImageToHImage(IoImage ioImage)
{
	HImage image;
	if (ioImage.stImage.Pixelformat == MvdPixelFormat::MVD_PIXEL_MONO_08)
	{
		image.GenImage1("byte", ioImage.stImage.Width, ioImage.stImage.Height, ioImage.stImage.ImageData);
	}
	if (ioImage.stImage.Pixelformat == MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3)
	{
		int width = ioImage.stImage.Width;
		int height = ioImage.stImage.Height;
		long size = width * height * 3;
		byte* imageRedBuf = new byte[(long)width * height];
		byte* imageGreenBuf = new byte[(long)width * height];
		byte* imageBlueBuf = new byte[(long)width * height];
		byte* imageBuffer = new byte[size];
		memcpy(imageBuffer, ioImage.stImage.ImageData, size);
		int index = 0;
		for (int row = 0; row < height; row++)
		{
			for (int col = 0; col < width; col++, index += 3)
			{
				imageRedBuf[row * width + col] = imageBuffer[index];
				imageGreenBuf[row * width + col] = imageBuffer[index + 1];
				imageBlueBuf[row * width + col] = imageBuffer[index + 2];
			}
		}
		delete[] imageBuffer;
		image.GenImage3("byte", width, height, imageRedBuf, imageGreenBuf, imageBlueBuf);
	}
	return image;
}

问题根因
不熟悉Halcon图像转换为其它类型

3.12 流程图像与算子图像互转

描述
环境:VM4.2 + VS2013及以上
现象:流程图像与算子图像互转
解答
VM SDK开发中流程输入输出图像都是IoImage,算子SDK开发中算子输入输出图像都是ImvdImage,两者可以实现互转。
1 流程图像转算子图像

IMvdImage* ImageConvert::IoImageToIMvdImage(IoImage ioImage)
{
	// TODO: 在此处添加实现代码.
	IMvdImage* iMvdImage = NULL;
	MVD_IMAGE_DATA_INFO stImageData{ };

	if (ioImage.stImage.Pixelformat == MvdPixelFormat::MVD_PIXEL_MONO_08)
	{
		stImageData.stDataChannel[0].nRowStep = ioImage.stImage.Width;
		stImageData.stDataChannel[0].nLen = ioImage.stImage.DataLen;
		stImageData.stDataChannel[0].nSize = ioImage.stImage.DataLen;
		stImageData.stDataChannel[0].pData = (unsigned char*)ioImage.stImage.ImageData;
		iMvdImage->InitImage(ioImage.stImage.Width, ioImage.stImage.Height, VisionDesigner::_MVD_PIXEL_FORMAT_::MVD_PIXEL_MONO_08, stImageData);
	}
	else if (ioImage.stImage.Pixelformat == MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3)
	{
		stImageData.stDataChannel[0].nRowStep = ioImage.stImage.Width*3;
		stImageData.stDataChannel[0].nLen = ioImage.stImage.DataLen;
		stImageData.stDataChannel[0].nSize = ioImage.stImage.DataLen;
		stImageData.stDataChannel[0].pData = (unsigned char*)ioImage.stImage.ImageData;
		iMvdImage->InitImage(ioImage.stImage.Width, ioImage.stImage.Height, VisionDesigner::_MVD_PIXEL_FORMAT_::MVD_PIXEL_BGR_BGR24_C3, stImageData);
	}

	return iMvdImage;
}

2 算子图像转流程图像

IoImage ImageConvert::IMvdImageToIoImage(IMvdImage* iMvdImage)
{
	// TODO: 在此处添加实现代码.
	IoImage ioImage{};

	ioImage.stImage.Width = iMvdImage->GetWidth();
	ioImage.stImage.Height = iMvdImage->GetHeight();
	
	ioImage.stImage.ImageData = iMvdImage->GetImageData(0)->pData;//图像数据内存地址是连续的
	if (iMvdImage->GetPixelFormat() == MVD_PIXEL_FORMAT::MVD_PIXEL_MONO_08)
	{
		ioImage.stImage.DataLen = iMvdImage->GetImageData(0)->nLen;
		ioImage.stImage.Pixelformat = MvdPixelFormat::MVD_PIXEL_MONO_08;
	}
	else if (iMvdImage->GetPixelFormat() == MVD_PIXEL_FORMAT::MVD_PIXEL_BGR_BGR24_C3)
	{
		ioImage.stImage.Pixelformat = MvdPixelFormat::MVD_PIXEL_RGB_RGB24_C3;
	}
	return ioImage;
}

问题根因
不熟悉流程图像与算子图像互转

3.13 算法模块图像与Mat、Halcon、算子图像互转的方法

描述
环境:VM4.2 + VS2013及以上
现象:算法模块图像转换成其它类型
解答
算法模块图像与Mat、Halcon图像、算子图像实现互转,自定义算法模块开发时,在C++工程中,算法的图像类型为HKA_IMAGE。
1 HKA_IMAGE与Mat互转

Mat CAlgorithmModule::HKAImageToMat(HKA_IMAGE inputimage)
{
    Mat mat, mat1;
    if (inputimage.format == HKA_IMG_MONO_08)
    {
        mat = Mat(inputimage.height, inputimage.width, CV_8UC1, inputimage.data[0]);
    }
    else if (inputimage.format == HKA_IMG_RGB_RGB24_C3)
    {
        mat1 = Mat(inputimage.height, inputimage.width, CV_8UC3, inputimage.data[0]);
        cvtColor(mat1, mat, COLOR_RGB2BGR);
    }
    return mat;
}



HKA_IMAGE CAlgorithmModule::MatToHKAImage(Mat mat)
{	
	HKA_IMAGE inputimage;
	if (mat.channels() == 1)
	{
		inputimage = { HKA_IMG_MONO_08, 0 };
		inputimage.width = mat.cols;
		inputimage.height = mat.rows;
		inputimage.format = HKA_IMG_MONO_08;
		inputimage.step[0] = mat.cols;
		inputimage.data[0] = (char*)malloc(inputimage.width * inputimage.height);
		if (inputimage.data[0] != NULL)
		{
			memset(inputimage.data[0], 0, inputimage.width * inputimage.height);
			memcpy_s(inputimage.data[0], inputimage.width * inputimage.height, mat.data, inputimage.width * inputimage.height);
		}
	}
	else if (mat.channels() == 3)
	{
		cvtColor(mat, mat, COLOR_BGR2RGB);
		inputimage = { HKA_IMG_RGB_RGB24_C3, 0 };
		inputimage.width = mat.cols;
		inputimage.height = mat.rows;
		inputimage.format = HKA_IMG_RGB_RGB24_C3;
		inputimage.step[0] = mat.cols * 3;
		inputimage.data[0] = (char*)malloc(inputimage.width * inputimage.height * 3);
		if (inputimage.data[0] != NULL)
		{
			memset(inputimage.data[0], 0, inputimage.width * inputimage.height * 3);
			memcpy_s(inputimage.data[0], inputimage.width * inputimage.height * 3, mat.data, inputimage.width * inputimage.height * 3);
		}
	}
	return inputimage;
}

2 HKA_IMAGE与Halcon图像互转

HImage CAlgorithmModule::HKAImageToHImage(HKA_IMAGE inputimage)
{
	HImage himage;
	if (HKA_IMG_MONO_08 == inputimage.format)
	{
		himage.GenImage1("byte", inputimage.width, inputimage.height, inputimage.data[0]);
	}
	if (HKA_IMG_RGB_RGB24_C3 == inputimage.format)
	{
		int width = inputimage.width;
		int height = inputimage.height;
		long size = width * height * 3;
		byte* imageRedBuf = new byte[(long)width * height];
		byte* imageGreenBuf = new byte[(long)width * height];
		byte* imageBlueBuf = new byte[(long)width * height];
		byte* imageBuffer = new byte[size];
		memcpy(imageBuffer, inputimage.data[0], size);
		int index = 0;
		for (int row = 0; row < height; row++)
		{
			for (int col = 0; col < width; col++, index += 3)
			{
				imageRedBuf[row * width + col] = imageBuffer[index];
				imageGreenBuf[row * width + col] = imageBuffer[index + 1];
				imageBlueBuf[row * width + col] = imageBuffer[index + 2];
			}
		}
		delete[] imageBuffer;
		himage.GenImage3("byte", width, height, imageRedBuf, imageGreenBuf, imageBlueBuf);
	}
	return himage;
}


HKA_IMAGE CAlgorithmModule::HImageToHKAIMAGE(HImage himage)
{
	HKA_IMAGE inputimage;
	HString type;
	Hlong width, height;
	if (himage.CountChannels() == 1)
	{
		inputimage = { HKA_IMG_MONO_08, 0 };
		void* imagePtr = himage.GetImagePointer1(&type, &width, &height);
		inputimage.width = width;
		inputimage.height = height;
		inputimage.format = HKA_IMG_MONO_08;
		inputimage.step[0] = width;
		inputimage.data[0] = (char*)malloc(inputimage.width * inputimage.height);
		if (inputimage.data[0] != NULL)
		{
			memset(inputimage.data[0], 0, inputimage.width * inputimage.height);
			memcpy_s(inputimage.data[0], inputimage.width * inputimage.height, imagePtr, inputimage.width * inputimage.height);
		}
	}
	else if (himage.CountChannels() == 3)
	{
		inputimage = { HKA_IMG_RGB_RGB24_C3, 0 };
		void* imageRedPtr;
		void* imageGreenPtr;
		void* imageBluePtr;
		himage.GetImagePointer3(&imageRedPtr, &imageGreenPtr, &imageBluePtr, &type, &width, &height);		
		long size = width * height * 3;
		byte* imageRedBuf = new byte[width * height];
		byte* imageGreenBuf = new byte[width * height];
		byte* imageBlueBuf = new byte[width * height];
		memcpy_s(imageRedBuf, imageRedPtr, width * height);
		memcpy_s(imageGreenBuf, imageGreenPtr, width * height);
		memcpy_s(imageBlueBuf, imageBluePtr, width * height);
		byte* imageBuffer = new byte[size];
		int index = 0;
		for (int row = 0; row < height; row++)
		{
			for (int col = 0; col < width; col++, index += 3)
			{
				imageBuffer[index] = imageRedBuf[row * width + col];
				imageBuffer[index + 1] = imageGreenBuf[row * width + col];
				imageBuffer[index + 2] = imageBlueBuf[row * width + col];
			}
		}
		delete[] imageRedBuf;
		delete[] imageGreenBuf;
		delete[] imageBlueBuf;
		inputimage.width = width;
		inputimage.height = height;
		inputimage.format = HKA_IMG_RGB_RGB24_C3;
		inputimage.step[0] = width * 3;
		inputimage.data[0] = (char*)malloc(inputimage.width * inputimage.height * 3);
		if (inputimage.data[0] != NULL)
		{
			memset(inputimage.data[0], 0, inputimage.width * inputimage.height * 3);
			memcpy_s(inputimage.data[0], inputimage.width * inputimage.height * 3, imageBuffer, inputimage.width * inputimage.height * 3);
		}
		delete[] imageBuffer;      
	}
	return inputimage;
}

3 HKA_IMAGE与算子图像(CmvdImage)互转

IMvdImage* CAlgorithmModule::HKAImageToIMvdImage(HKA_IMAGE inputimage)
{
    IMvdImage* iMvdImage = NULL;
    CreateImageInstance(&iMvdImage);
    MVD_IMAGE_DATA_INFO stImageData;

    if (inputimage.format == HKA_IMG_MONO_08)
    {
        uint dataLen = (uint)(inputimage.width * inputimage.height);
        stImageData.stDataChannel[0].nRowStep = inputimage.width;
        stImageData.stDataChannel[0].nLen = dataLen;
        stImageData.stDataChannel[0].nSize = dataLen;
        stImageData.stDataChannel[0].pData = (unsigned char*)malloc(inputimage.width * inputimage.height);
        memset(stImageData.stDataChannel[0].pData, 0, inputimage.width * inputimage.height);
        stImageData.stDataChannel[0].pData = (unsigned char*)inputimage.data[0];
        iMvdImage->InitImage(inputimage.width, inputimage.height, MVD_PIXEL_MONO_08, stImageData);
    }
    else if (inputimage.format == HKA_IMG_RGB_RGB24_C3)
    {
        uint dataLen = (uint)(inputimage.width * inputimage.height * 3);
        stImageData.stDataChannel[0].nRowStep = inputimage.width * 3;
        stImageData.stDataChannel[0].nLen = dataLen;
        stImageData.stDataChannel[0].nSize = dataLen;
        stImageData.stDataChannel[0].pData = (unsigned char*)malloc(inputimage.width * inputimage.height * 3);
        memset(stImageData.stDataChannel[0].pData, 0, inputimage.width * inputimage.height);
        stImageData.stDataChannel[0].pData = (unsigned char*)inputimage.data[0];
        iMvdImage->InitImage(inputimage.width, inputimage.height, MVD_PIXEL_RGB_RGB24_C3, stImageData);

    }
    return iMvdImage;
}


HKA_IMAGE CAlgorithmModule::IMvdImageToHKA_IMAGE(IMvdImage* iMvdImage)
{
    HKA_IMAGE inputimage;
    if (iMvdImage->GetPixelFormat() == MVD_PIXEL_MONO_08)
    {
        inputimage = { HKA_IMG_MONO_08, 0 };
        inputimage.width = iMvdImage->GetWidth();
        inputimage.height = iMvdImage->GetHeight();
        inputimage.format = HKA_IMG_MONO_08;
        inputimage.step[0] = iMvdImage->GetWidth();
        inputimage.data[0] = (char*)malloc(inputimage.width * inputimage.height);
        if (inputimage.data[0] != NULL)
        {
            memset(inputimage.data[0], 0, inputimage.width * inputimage.height);
            memcpy_s(inputimage.data[0], inputimage.width * inputimage.height, iMvdImage->GetImageData()->stDataChannel[0].pData, inputimage.width * inputimage.height);
        }
    }
    else if (iMvdImage->GetPixelFormat() == MVD_PIXEL_RGB_RGB24_C3)
    {
        inputimage = { HKA_IMG_RGB_RGB24_C3, 0 };
        inputimage.width = iMvdImage->GetWidth();
        inputimage.height = iMvdImage->GetHeight();
        inputimage.format = HKA_IMG_RGB_RGB24_C3;
        inputimage.step[0] = iMvdImage->GetWidth() * 3;
        inputimage.data[0] = (char*)malloc(inputimage.width * inputimage.height * 3);
        if (inputimage.data[0] != NULL)
        {
            memset(inputimage.data[0], 0, inputimage.width * inputimage.height * 3);
            memcpy_s(inputimage.data[0], inputimage.width * inputimage.height * 3, iMvdImage->GetImageData()->stDataChannel[0].pData, inputimage.width * inputimage.height * 3);
        }
    }
    return inputimage;
}

问题根因
不熟悉算法模块图像转其它类型


http://www.niftyadmin.cn/n/285215.html

相关文章

JavaSE基础(二)—— 类型转换、运算符、键盘录入

目录 一、类型转换 1. 自动类型转换 1.1 自动类型转换的底层原理&#xff1a; ​1.2 自动类型转换的其他形式​编辑 2. 表达式的自动类型转换 3. 强制类型转换 3.1 强制类型转换底层原理​编辑 3.2 注意事项 二、运算符 1. 算数运算符 1.1 案例&#xff1a;数值拆分…

7万字水利数字孪生工程解决方案(word可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 1.1 系统开发方案 1.1.1 系统设计开发思路 &#xff08;1&#xff09;基于层次分解的设计 xxx水利数字孪生工程将采用基于层次分解的系统模型,系统采用这种方式进行层次划…

Java SE 20 新增特性

Java SE 20 新增特性 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;Java SE 20 新增特性 CSDN&#xff1a;Java SE 20 新增特性 源码 源仓库: Github&#xff1a;java_new_features 镜像仓库: GitCode&#xff1a;java_new_features Switch类型匹配(第…

KALI入门到高级【第六章】

预计更新第一章 入门 1.1 什么是Kali Linux&#xff1f; 1.2 安装Kali Linux 1.3 Kali Linux桌面环境介绍 1.4 基本命令和工具 第二章 信息收集 1.1 网络扫描 1.2 端口扫描 1.3 漏洞扫描 1.4 社交工程学 第三章 攻击和渗透测试 1.1 密码破解 1.2 暴力破解 1.3 漏洞利用 1.4 特…

Docker consul服务注册与发现

目录 一、服务注册与发现 1、什么是服务注册与发现 2、什么是consul 3、consul提供的一些关键特性 4、容器更新与发现 二、基于nginx与consul构建自动发现即高可用的Docker服务架构 consul服务器部署 1、建立consul 2、查看集群信息 3、通过http获取集群信息 regist…

Windows环境安装Elasticsearch和Kibana

文章目录 1 Elasticsearch1.1 下载1.2 解压并添加环境变量1.3 访问1.4 cmd命令1.5 中文分词器1.5.1 下载1.5.2 安装1.5.2.1 命令安装1.5.2.2 手动安装1.5.2.3 验证分词 1.6 使用curl批量导入 2 安装 kibana2.1 下载kibana2.2 中文界面2.3 操作索引2.3.1 增加索引2.3.1.1 单条新…

Qt面试常见问题

qt元对象系统 qt的元对象编译系统MOC是一个预处理器&#xff0c;当qt读取源文件时检测到类中包含有Q_OBJECT宏时&#xff0c;则会创建一个新的文件&#xff0c;将源码转换为C编译器可以识别的代码写入moc开头的文件&#xff0c;然后C编译器对其进行编译。使用moc系统的方法&am…

二十个最美棒球场·棒球1号位

二十个最美的棒球场及其特点&#xff1a; 1. 密尔沃基小鸟队主场美国家庭保险球场&#xff08;American Family Field&#xff09;&#xff0c;位于威斯康星州密尔沃基市&#xff0c;是一座拥有色彩丰富的外观和舒适座位的球场。 2. 圣路易斯红雀队主场布什球场&#xff08;Bu…