Подтвердить что ты не робот

Исходные данные изображения с камеры типа "645 PRO"

Некоторое время назад я уже задавал этот вопрос, и у меня также был хороший ответ:

Я искал этот форум вверх и вниз, но я не мог найти то, что я очень нужно. Я хочу получить необработанные данные изображения с камеры. До сих пор Я попытался извлечь данные из imageDataSampleBuffer из этого метод captureStillImageAsynchronouslyFromConnection: completeHandler: и записать его в объект NSData, но это не сработало. Может быть, я нахожусь неправильный трек или, может быть, я просто делаю это неправильно. Я не хочу, чтобы для сжатия изображения каким-либо образом.

Простым способом является использование jpegStillImageNSDataRepresentation: from AVCaptureStillImageOutput, но, как я уже сказал, я не хочу, чтобы это было сжатый.

Спасибо!

Исходные данные изображения с камеры

Я думал, что смогу с этим справиться, но я, наконец, заметил, что мне нужно получить данные необработанного изображения более точно так же, как это сделано в "645 PRO".

645 PRO: RAW Redux

Изображения на этом сайте показывают, что они получают необработанные данные перед выполнением любого jpeg-сжатия. Это то, что я хочу сделать. Я предполагаю, что мне нужно преобразовать imageDataSampleBuffer, но я не вижу способа сделать это полностью без сжатия. "645 PRO" также сохраняет свои снимки в TIFF, поэтому я думаю, что он использует хотя бы одну дополнительную библиотеку.

Я не хочу делать фотоприложение, но мне нужно лучшее качество, которое я могу проверить для некоторых функций на картинке.

Спасибо!

Изменить 1: Поэтому после попытки и поиска в разных направлениях какое-то время я решил дать обновление статуса.

Конечной целью этого проекта является проверка определенных функций на картинке, которая будет происходить с помощью opencv. Но пока приложение не сможет сделать это по телефону, я пытаюсь получить в основном несжатые картинки из телефона, чтобы проанализировать их на компьютере.

Поэтому я хочу сохранить "экземпляр NSData, содержащий несжатые байты BGRA, возвращенные с камеры". Я могу получить код Брэда Ларсона в формате BMP или TIFF. Как я уже сказал в комментарии, я попытался использовать opencv для этого (в любом случае это будет необходимо). Но лучшее, что я мог сделать, это превратить его в UIImage с функцией "Обсуждение компьютерного зрения" .

void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
cv::Mat frame(height, width, CV_8UC4, (void*)baseAddress);
UIImage *testImag = [UIImage imageWithMat:frame andImageOrientation:UIImageOrientationUp];
//imageWithMat... being the function from Computer Vision Talks which I can post if someone wants to see it

ImageMagick - Подход

Еще одна вещь, которую я пробовал, - использовать ImageMagick, как было предложено в другом сообщении. Но я не мог найти способ сделать это, не используя что-то вроде UIImagePNGRepresentation или UIImageJPEGRepresentation.

На данный момент я пытаюсь сделать что-то с libtiff, используя этот учебник.

Возможно, у кого-то есть идея или он знает гораздо более простой способ конвертировать мой буферный объект в несжатое изображение. Спасибо заранее!

Изменить 2:

Я что-то нашел! И я должен сказать, что я был очень слеп.

void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
cv::Mat frame(height, width, CV_8UC4, (void*)baseAddress);

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"ocv%d.TIFF", picNum]];
const char* cPath = [filePath cStringUsingEncoding:NSMacOSRomanStringEncoding];

const cv::string newPaths = (const cv::string)cPath;

cv::imwrite(newPaths, frame);

Мне просто нужно использовать функцию imwrite из opencv. Таким образом, я получаю файлы TIFF около 30 МБ непосредственно после поляризации бейера!

4b9b3361

Ответ 1

Я мог бы решить это с помощью OpenCV. Спасибо всем, кто помог мне.

void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
cv::Mat frame(height, width, CV_8UC4, (void*)baseAddress);

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"ocv%d.BMP", picNum]];
const char* cPath = [filePath cStringUsingEncoding:NSMacOSRomanStringEncoding];

const cv::string newPaths = (const cv::string)cPath;

cv::imwrite(newPaths, frame);

Мне просто нужно использовать функцию imwrite из opencv. Таким образом, я получаю BMP файлы около 24 МБ непосредственно после фильтра bayer!

Ответ 2

Ничего себе, это сообщение в блоге было чем-то особенным. Множество слов, чтобы просто указать, что они получают байты выборки, которые Apple возвращает вам из неподвижного изображения. В их подходе нет ничего особенно инновационного, и я знаю несколько приложений для камер, которые это делают.

Вы можете получить необработанные байты, полученные с фотографии, сделанной с помощью AVCaptureStillImageOutput, используя следующий код:

[photoOutput captureStillImageAsynchronouslyFromConnection:[[photoOutput connections] objectAtIndex:0] completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
    CVImageBufferRef cameraFrame = CMSampleBufferGetImageBuffer(imageSampleBuffer);
    CVPixelBufferLockBaseAddress(cameraFrame, 0);
    GLubyte *rawImageBytes = CVPixelBufferGetBaseAddress(cameraFrame);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(cameraFrame);
    NSData *dataForRawBytes = [NSData dataWithBytes:rawImageBytes length:bytesPerRow * CVPixelBufferGetHeight(cameraFrame)];
    // Do whatever with your bytes

    CVPixelBufferUnlockBaseAddress(cameraFrame, 0);
}];

Это даст вам экземпляр NSData, содержащий несжатые байты BGRA, возвращенные с камеры. Вы можете сохранить их на диск или делать с ними все, что хотите. Если вам действительно нужно обработать сами байты, я бы избегал накладных расходов на создание NSData и просто работал с массивом байтов из буфера пикселей.

Ответ 3

В то время как ядро ​​ответа приходит от Брэда в iOS: Получайте пиксельные данные с камеры, ключевой элемент полностью неясен из ответа Брэда. Он скрыт в "после настройки вашего сеанса захвата...".

Вам нужно установить правильные выходные настройки для AVCaptureStillImageOutput.

Например, установка kCVPixelBufferPixelFormatTypeKey в kCVPixelFormatType_420YpCbCr8BiPlanarFullRange даст вам YCbCr imageDataSampleBuffer в captureStillImageAsynchronouslyFromConnection:completionHandler:, который затем вы можете манипулировать своим сердечным содержимым.

Ответ 4

как упоминал @Wildaker, для конкретного кода для работы вы должны быть уверены, какой формат пикселя отправляет камера. Код из @thomketler будет работать, если он настроен для 32-битного формата RGBA.

Вот код для YUV по умолчанию с камеры, используя OpenCV:

cv::Mat convertImage(CMSampleBufferRef sampleBuffer)
{
    CVImageBufferRef cameraFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(cameraFrame, 0);

    int w = (int)CVPixelBufferGetWidth(cameraFrame);
    int h = (int)CVPixelBufferGetHeight(cameraFrame);
    void *baseAddress = CVPixelBufferGetBaseAddressOfPlane(cameraFrame, 0);

    cv::Mat img_buffer(h+h/2, w, CV_8UC1, (uchar *)baseAddress);
    cv::Mat cam_frame;
    cv::cvtColor(img_buffer, cam_frame, cv::COLOR_YUV2BGR_NV21);
    cam_frame = cam_frame.t();

    //End processing
    CVPixelBufferUnlockBaseAddress( cameraFrame, 0 );

    return cam_frame;
}

cam_frame должен иметь полный кадр BGR. Надеюсь, что это поможет.