Convert cv::Mat to dwImageCPU

Hello,

for a demo application we receive OpenCV Mat objects (CV_8UC3) and want to convert them to dwImageCPU images. Unfortunately I couldn’t find much information or code samples that show how this can be done. Could you help me out with that?

Thank you very much,
Lucas

Dear lucas.heer,
You can use dwImageCPU_create function to create a dwImageCPU object using a unit_8 buffer. As CV_8UC3 stands for unsigned RGB image, you can use DW_IMAGE_RGB in dwImagePixelformat. Can you please grep for dwImageCPU_create function to know how to use this function. Could you also Driveworks documentation to know more details about this API(/usr/local/driveworks/doc/nvdwx_html/group__image__group.html#structdwImageCPU)

Hi SivaRamaKrishna,
thank you very much for your answer. I could not find a way to pass the pixel data directly to the dwImageCPU_create function, but was able to convert the image by simply copying the cv::Mat.data into dwImageCPU.data[0] using memcpy.

Best regards,
Lucas

Dear Lucas,
Yes. If you already have dwImageCPU object, you can copy the data into data array directly. The dwImageCPU_create function is to allocate dwImageCPU object if you do not have any.

Hi SivaRamaKrishna,

I can copy data to dwImageCPU.data[0]. But if I want to have a 3-plane RGB dwImageCPU, how can I copy data to dwImageCPU.data[1]? I try to use memcpy to copy data, but segamentfault.

Dear dengqi,
Could you please share your code snippet

Hi SivaRamaKrishna,

Here is my code snippet. I manually create a dwImageCPU object. And use OpenCV’s function to split one plane Mat to 3 plane Mat. Then use memcpy to copy data from Mat object to dwImageCPU.data…

dwImageCPU *nextFrameCPU;
dwImage_getCPU(&nextFrameCPU, m_imageCPU);
cv::Mat planes[3];
cv::split(opencv_image, planes);
mempcpy(nextFrameCPU->data[0], planes[0].data, planes[0].total() * planes[0].elemSize()); // yes
mempcpy(nextFrameCPU->data[1], planes[1].data, planes[1].total() * planes[1].elemSize()); // segementfault...
mempcpy(nextFrameCPU->data[2], planes[2].data, planes[2].total() * planes[2].elemSize());

Dear dengqi,
COuld you share the used dwImageFormat value for dwImageCPU object

Hi SivaRamaKrishna,

Here is my Format code:

m_opencv_prop.format = DW_IMAGE_FORMAT_RGB_UINT8;
 m_opencv_prop.width = FLAGS_width;
 m_opencv_prop.height = FLAGS_height;
 m_opencv_prop.type = DW_IMAGE_CPU;
 m_opencv_prop.memoryLayout = DW_IMAGE_MEMORY_TYPE_DEFAULT;
 CHECK_DW_ERROR(dwImage_create(&m_imageCPU, m_opencv_prop, m_sdk));

Should I change the format to DW_IMAGE_FORMAT_RGB_UINT8_PLANAR?

Thanks!

Dear denguqi,
Make use you use DW_IMAGE_FORMAT_RGB_UINT8_PLANAR format. I quickly tested the below code with CPU malloc buffers. I don’t see any segmentation faults.

cpuProp2 = cpuProp;
cpuProp2.format = DW_IMAGE_FORMAT_RGB_UINT8_PLANAR; // This makes it planar image
 status = dwImage_create(&m_rgbCPU2, cpuProp2, m_context);
char* a = (char*)malloc(sizeof(char)*imageWidth*imageHeight*3);
    char* b = (char*)malloc(sizeof(char)*imageWidth*imageHeight*3);
    char* c = (char*)malloc(sizeof(char)*imageWidth*imageHeight*3);
    dwImageCPU *cpu_a;
    status = dwImage_getCPU(&cpu_a,m_rgbCPU2);
    if (status != DW_SUCCESS) {
        logError("Cannot get dwImageCPU object %s\n", dwGetStatusName(status));
        return false;
    }
    else
    {
    std::cout << " dwImageCPU object success" << std::endl;
    }

    memcpy(cpu_a->data[0],a,sizeof(char)*imageWidth*imageHeight);
    memcpy(cpu_a->data[1],b,sizeof(char)*imageWidth*imageHeight);
    memcpy(cpu_a->data[2],c,sizeof(char)*imageWidth*imageHeight);

Thanks, it works!