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.