Data gambar mentah dari kamera seperti 645 PRO

Beberapa waktu yang lalu saya sudah menanyakan pertanyaan ini dan saya juga mendapat jawaban yang bagus:

Saya telah mencari forum ini ke atas dan ke bawah tetapi saya tidak dapat menemukan apa yang benar-benar saya butuhkan. Saya ingin mendapatkan data gambar mentah dari kamera. Sampai sekarang saya mencoba mengeluarkan data dari imageDataSampleBuffer dari metode captureStillImageAsynchronouslyFromConnection:completionHandler: dan menulisnya ke objek NSData, tetapi tidak berhasil. Mungkin saya berada di jalur yang salah atau mungkin saya hanya melakukan kesalahan. Yang tidak saya inginkan adalah gambarnya dikompresi dengan cara apa pun.

Cara mudahnya adalah dengan menggunakan jpegStillImageNSDataRepresentation: dari AVCaptureStillImageOutput, tapi seperti saya katakan, saya tidak ingin dikompresi.

Terima kasih!

Data gambar mentah dari kamera

Saya pikir saya bisa mengerjakan ini, tapi akhirnya saya menyadari bahwa saya perlu mendapatkan data gambar mentah secara lebih langsung dengan cara yang sama seperti yang dilakukan di "645 PRO".

645 PRO: Redux RAW

Gambar-gambar di situs tersebut menunjukkan bahwa mereka mendapatkan data mentah sebelum kompresi jpeg dilakukan. Itulah yang ingin saya lakukan. Dugaan saya adalah saya perlu mengubah imageDataSampleBuffer tetapi saya tidak melihat cara untuk melakukannya sepenuhnya tanpa kompresi. "645 PRO" juga menyimpan gambarnya di TIFF jadi menurut saya ia menggunakan setidaknya satu perpustakaan tambahan.

Saya tidak ingin membuat aplikasi foto tetapi saya memerlukan kualitas terbaik untuk memeriksa fitur tertentu dalam gambar.

Terima kasih!

Sunting 1: Jadi setelah mencoba dan mencari ke berbagai arah untuk sementara waktu sekarang saya memutuskan untuk memberikan pembaruan status.

Tujuan akhir dari proyek ini adalah untuk memeriksa fitur-fitur tertentu dalam gambar yang akan terjadi dengan bantuan opencv. Namun hingga aplikasi dapat melakukannya di ponsel, saya mencoba mengeluarkan sebagian besar gambar yang tidak terkompresi dari ponsel untuk dianalisis di komputer.

Oleh karena itu saya ingin menyimpan "instance NSData yang berisi byte BGRA terkompresi yang dikembalikan dari kamera" yang dapat saya peroleh dengan kode Brad Larson sebagai file bmp atau TIFF. Seperti yang saya katakan di komentar, saya mencoba menggunakan opencv untuk ini (tetap diperlukan). Tapi hal terbaik yang bisa saya lakukan adalah mengubahnya menjadi UIImage dengan fungsi dari Pembicaraan Visi Komputer.

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 - Pendekatan

Hal lain yang saya coba adalah menggunakan ImageMagick seperti yang disarankan di postingan lain . Namun saya tidak dapat menemukan cara untuk melakukannya tanpa menggunakan sesuatu seperti UIImagePNGRepresentationatau UIImageJPEGRepresentation.

Untuk saat ini saya mencoba melakukan sesuatu dengan libtiff menggunakan tutorial.

Mungkin seseorang punya ide atau mengetahui cara yang lebih mudah untuk mengubah objek buffer saya menjadi gambar yang tidak terkompresi. Terima kasih sebelumnya lagi!

Sunting 2:

Aku menemukan sesuatu! Dan harus saya akui, saya sangat buta.

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);

Saya hanya perlu menggunakan fungsi imwrite dari opencv. Dengan cara ini saya mendapatkan file TIFF sekitar 30 MB langsung setelah beyer-Polarisasi!


person thomketler    schedule 23.07.2012    source sumber
comment
Saya menemukan jawaban ini dalam 10 detik pencarian: stackoverflow.com/a/10865206/96716   -  person David H    schedule 23.07.2012
comment
Terima kasih Dustin, saya sudah takut akan hal seperti itu, saya hanya berharap ada yang bisa memberi saya petunjuk atau semacamnya. Dan terima kasih kepada David H tetapi saya sudah memeriksanya dan itu tidak terlalu membantu kasus saya atau setidaknya saya tidak tahu caranya. Tapi saya berterima kasih atas setiap petunjuknya!   -  person thomketler    schedule 23.07.2012


Jawaban (4)


Wow, postingan blog itu sesuatu yang istimewa. Banyak kata yang menyatakan bahwa mereka mendapatkan sampel buffer byte yang diberikan Apple kepada Anda dari gambar diam. Tidak ada yang inovatif dalam pendekatan mereka, dan saya tahu sejumlah aplikasi kamera yang melakukan hal ini.

Anda bisa mendapatkan byte mentah yang dikembalikan dari foto yang diambil dengan AVCaptureStillImageOutput menggunakan kode seperti berikut:

[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);
}];

Ini akan memberi Anda instance NSData yang berisi byte BGRA yang tidak terkompresi yang dikembalikan dari kamera. Anda dapat menyimpannya ke disk atau melakukan apa pun yang Anda inginkan dengannya. Jika Anda benar-benar perlu memproses byte itu sendiri, saya akan menghindari overhead pembuatan NSData dan hanya bekerja dengan array byte dari buffer piksel.

person Brad Larson    schedule 23.07.2012
comment
Terima kasih banyak atas bantuan Anda. Senang mengetahui bahwa saya tidak sepenuhnya berada di jalur yang salah. Saya harap saya tidak memaksakan kesabaran Anda, tetapi tahukah Anda cara sederhana untuk mengubahnya menjadi bitmap? Saya sedang berpikir untuk menggunakan openCV dengan cara serupa seperti yang dilakukan di postingan lain link Saya hanya ingin tahu apakah saya melewatkan cara yang lebih mudah. Dan sekali lagi terima kasih. Saya telah menemui jalan buntu dengan ini selama beberapa waktu sekarang. - person thomketler; 24.07.2012

Saya bisa menyelesaikannya dengan OpenCV. Terima kasih kepada semua orang yang membantu saya.

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);

Saya hanya perlu menggunakan fungsi imwrite dari opencv. Dengan cara ini saya mendapatkan file BMP sekitar 24 MB langsung setelah filter bayer!

person thomketler    schedule 03.08.2012

Sedangkan inti jawabannya datang dari Brad di iOS: Dapatkan data piksel demi piksel dari kamera, elemen kuncinya sama sekali tidak jelas dari balasan Brad. Itu tersembunyi di "setelah sesi pengambilan Anda dikonfigurasi...".

Anda perlu menyetel pengaturan keluaran yang benar untuk AVCaptureStillImageOutput Anda.

Misalnya, menyetel kCVPixelBufferPixelFormatTypeKey ke kCVPixelFormatType_420YpCbCr8BiPlanarFullRange akan memberi Anda YCbCr imageDataSampleBuffer di captureStillImageAsynchronouslyFromConnection:completionHandler:, yang kemudian dapat Anda manipulasi sesuka hati.

person Wildaker    schedule 23.07.2012
comment
Satu hal yang perlu diperhatikan: kCVPixelBufferPixelFormatTypeKey adalah int, jadi Anda harus membungkusnya dalam NSNumber saat menambahkan ke kamus Anda. Selain itu, di bawah ARC, Anda harus memberikan nilai sebenarnya secara manual ke id. - person FeifanZ; 02.08.2012

seperti yang disebutkan @Wildaker, agar kode tertentu berfungsi, Anda harus yakin format piksel mana yang dikirimkan kamera kepada Anda. Kode dari @thomketler akan berfungsi jika disetel untuk format RGBA 32-bit.

Berikut ini kode YUV default dari kamera, menggunakan 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 harus memiliki frame BGR penuh. Saya harap itu membantu.

person G. Führ    schedule 13.01.2017