I have an iOS app that analyzes video from the camera using OpenCV.
The video that is being displayed is in BGR.
After upgrading from Xcode 13 to 14, the video has stopped being displayed, and this has appeared in the logs:
CGImageCreate: invalid image byte order info for bitsPerPixel != 32 = 16384
After debugging, it seems that when I change the frames from BGR to Gray and also to RGBA, it works:
cvtColor( frame, frame, COLOR_BGR2GRAY ); // works
cvtColor( frame, frame, COLOR_BGR2RGBA ); // works
But I don’t want to the video to be gray, and the RGBA video didn’t look right.
When I tried displaying in RGB it crashed:
cvtColor( frame, frame, COLOR_BGR2RGB ); // didn't work
What can be the issue? What can be a fix?
2
Answers
I Dont know much about Xcode14, but when you change the color space using
cvtColor
function, it changes the number of channels in the image. The BGR color space has 3 channels (blue, green and red) while Gray has only 1 channel and RGBA has 4 channels (red, green, blue, and alpha).In the current case, changing the color space to Gray or RGBA works because these color spaces have a byte order that is compatible with
CGImageCreate
. However, when you try to change the color space to RGB, the byte order becomes incompatible, which leads to the crash.Some solutions(only my personal opinion):
cv::flip
to change the byte order of the image before displaying it:This will flip the rows of the image vertically, effectively changing the byte order to a compatible format for
CGImageCreate
.cv::cvtColor
withCOLOR_BGR2BGRA
instead ofCOLOR_BGR2RGBA
. This will add an alpha channel to your BGR image while preserving the original byte order:I hope that helps!!
It crashes because the byte order is not compatible with the expected format. Manually rearrange the blue and red channels of each pixel in the BGR image.
Possible solutions:
1- Convert the BGR image to BGRA and then rearrange the channels to match the RGB order. The fromTo array specifies the channel rearrangement from BGR to RGB.
2- Split the BGR channels, swap the blue and red channels, and then merge them to create an RGB image. This approach should work as long as the original image is indeed in the BGR color space. By manually swapping the channels, you can bypass any potential issues related to byte order information.