Home > OS >  Is it possible to convert a UTexture2D to an OpenCV::Mat
Is it possible to convert a UTexture2D to an OpenCV::Mat

Time:10-05

I am an developer that works with plugin development for unreal (C ), and I have been tasked with integrating openCV into unreal engine for a project. I was able to handle getting the std:: issues solved, but I am stuck and frustrated with trying to get a UTexture2D to be converted into an opencv::Mat. I have a C function that takes in a UTexture2D* and needs to use openCV to manipulate it. To do this, it must be converted to an opencv::Mat. I tried doing pixel-to-pixel conversion, but it crashes every time or hangs. Any guide on how to do this necessary conversion is greatly appreciated, thanks!

I have tried a few versions of this code with no success, but this is my latest failure:

//obtain all the pixel information from the mipmaps
FTexture2DMipMap* MyMipMap = &MyTexture2D->PlatformData->Mips[0];
FByteBulkData* RawImageData = &MyMipMap->BulkData;

//store in fcolor array
uint8* Pixels = static_cast<uint8*>(RawImageData->Lock(LOCK_READ_ONLY));

//trying via constructor
cv::Mat myImg = cv::Mat( 3000, 1100, CV_8UC3);

//trying to map the pixels individually
for (int32 y = 0; y < height; y  )
{
    for (int32 x = 0; x < width; x  )
    {
        int32 curPixelIndex = ((y * width)   x);
        myImg.at<cv::Vec3b>(x, y)[0] = Pixels[4 * curPixelIndex];
        myImg.at<cv::Vec3b>(x, y)[1] = Pixels[4 * curPixelIndex   1];
        myImg.at<cv::Vec3b>(x, y)[2] = Pixels[4 * curPixelIndex   2];
    }
};

//unlock thread
RawImageData->Unlock();

CodePudding user response:

Use correct constructor of cv::Mat that takes a data pointer. That Mat object will not allocate or free its own memory. It will use the memory it was given. Such a Mat will not be resizable and it will only be valid as long as the given memory is okay to access.

https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html#a51615ebf17a64c968df0bf49b4de6a3a

...
uint8* Pixels = ...;

cv::Mat myImg { height, width, CV_8UC4, Pixels };
// myImg is now usable

// access pixels like so: myImg.at<Vec4b>(y,x)

...

This example uses uniform initialization. "Old" styles are okay too.

  • Related