Как конвертировать CVPixelBuffer в Mat или UIImage Objective-C
При попытке конвертировать CVPixelBuffer в градациях серого я получаю сообщение об ошибке:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x59b2b0290)
CVPixelBuffer имеет тип kCVPixelFormatType_OneComponent8. Моя mlmodel похожа на стиль передачи моделей ввода и вывода изображения. Это версия Unet. Входные данные представляют собой цветное изображение, а выходные - изображение в градациях серого.
это то, что модель в.h файле показывает ввод:
/// image as color (kCVPixelFormatType_32BGRA) image buffer, 224 pixels wide by 224 pixels high
open var image: CVPixelBuffer
public init(image: CVPixelBuffer)
выход:
/// mask as grayscale (kCVPixelFormatType_OneComponent8) image buffer, 224 pixels wide by 224 pixels high
open var mask: CVPixelBuffer
publicinit(mask: CVPixelBuffer)
Я помещаю изображение из объекта Mat (OpenCV) в модель и пытаюсь вернуть выходные данные в другой объект Mat.
перед подачей изображения в модель я преобразую его Mat -> CVPixelBuffer -> MLMODEL -> CVPixelBuffer -> Mat
Вот как я использую модель, все работает нормально, пока я не попытаюсь преобразовать вывод в Mat (строка 8) Mat toSqeeze = obrazek.clone();
cvtColor(toSqeeze, toSqeeze, CV_BGRA2BGR);
resize(toSqeeze, toSqeeze, cv::Size(224,224));
imageIn = [self matToImageBuffer: toSqeeze];
NSError *error;
output = [self->_squeezU predictionFromImage: imageIn error:&error];
Mat imageOut = [self imageBufferToMat: output.mask];
Я использую следующие методы:
(цвет) Мат -> CVPixelBuffer работает нормально
- (CVImageBufferRef) matToImageBuffer: (cv::Mat) mat
{
cv::cvtColor(mat, mat, CV_BGR2BGRA);
int width = mat.cols;
int height = mat.rows;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
[NSNumber numberWithInt:width], kCVPixelBufferWidthKey,
[NSNumber numberWithInt:height], kCVPixelBufferHeightKey,
nil];
CVPixelBufferRef imageBuffer;
CVReturn status = CVPixelBufferCreate(kCFAllocatorMalloc, width, height, kCVPixelFormatType_32BGRA, (CFDictionaryRef) CFBridgingRetain(options), &imageBuffer) ;
NSParameterAssert(status == kCVReturnSuccess && imageBuffer != NULL);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
void *base = CVPixelBufferGetBaseAddress(imageBuffer) ;
memcpy(base, mat.data, mat.total()*4);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
return imageBuffer;
}
(оттенки серого) CVPixelBuffer -> Мат здесь проблемы (строка 5)
- (cv::Mat) imageBufferToMat: (CVImageBufferRef) buffer
{
cv::Mat mat ;
CVPixelBufferLockBaseAddress(buffer, 0); // I get here <- EXC_BAD_ACCESS (code=1, address=0x59b2b0290)
void *address = CVPixelBufferGetBaseAddress(buffer);
int width = (int) CVPixelBufferGetWidth(buffer);
int height = (int) CVPixelBufferGetHeight(buffer);
mat = cv::Mat(height, width, CV_8UC1, address, 0);
CVPixelBufferUnlockBaseAddress(buffer, 0);
return mat;
}
При попытке запустить код я получаю сообщение об ошибке: Поток 1:
EXC_BAD_ACCESS (code=1, address=0x59b2b0290)
Самым близким, что я сузил, является характер вывода в градациях серого kCVPixelFormatType_OneComponent8.
Я делаю что-то неправильно? Есть ли другой подход, когда вывод модели в градациях серого? Пожалуйста помоги. Заранее спасибо, я был бы рад иметь решение в ObjectiveC или Swift, я могу использовать последнее через мост.