Obtenir les pixels d'un AVCaptureVideoPreviewLayer, Lors d'une preview vidéo |
Bienvenue invité ( Connexion | Inscription )
Obtenir les pixels d'un AVCaptureVideoPreviewLayer, Lors d'une preview vidéo |
6 Feb 2015, 22:39
Message
#1
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 831 Inscrit : 19 Jul 2001 Lieu : Живим у Греноблу Membre no 519 |
Hello,
j'aimerais pouvoir accéder aux pixels dans une preview vidéo. J'ai pris l'exemple d'Apple AVRecorder et il marche nickel. Le problème, c'est que je n'ai pas compris comment on accède aux pixels de la preview. J'aimerais faire des stats dessus en temps réel (exemple : compter la moyenne de rouge de l'image sur plusieurs frames). J'arrive bien à avoir le AVCaptureVideoPreviewLayer, mais où dois-je aller pour lire les pixels ? Merci -------------------- Хајде Јано коло да играмо
iMac 27 mi 2010 Macbook air mi 2011 Mac Mini M1 |
|
|
7 Feb 2015, 15:07
Message
#2
|
|
Nouveau Membre Groupe : Membres Messages : 39 Inscrit : 21 Mar 2012 Membre no 175 442 |
Bonjour,
Après un rapide coup d'œil sur l'exemple AVRecorder, je pense qu'il te faut plutôt regarder du coté du protocol AVCaptureFileOutputDelegate. Plus spécialement la méthode -captureOutput:didOutputSampleBuffer:fromConnection:. La fonction de CMSampleBufferGetImageBuffer devrait te retourner un CVPixelBufferRef, qui te permettra d'accéder aux pixels de ton image. Soit quelque chose comme ça : Code - (void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *) connection { CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); /* si on a bien un pixelBuffer, "lock" l'accès aux données */ if (pixelBuffer && (CVPixelBufferLockBaseAddress(pixelBuffer, 0) == kCVReturnSuccess)) { void* buffer = CVPixelBufferGetBaseAddress(pixelBuffer); /* Tests tes valeurs selon le format du pixel buffer (cf doc) */ /* Terminé, "unlock" les données */ CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); } } Si tu veux passer par AVCaptureVideoPreviewLayer, qui est une sous classe de CALayer, la seule solution que je vois est de copier le layer dans un "bitmap context" : Code - (void)analyseLayerData:(AVCaptureVideoPreviewLayer *)aLayer { void *buffer; // le buffer pour les pixels CGContextRef bitmapContext = CGBitmapContextCreateWithData(buffer, .......); [aLayer drawInContext:bitmapContext]; /* Analyse les pixels qui ont été copiées dans le buffer */ /* clean */ CGContextRelease(bitmapContext); } Accéder aux datas d'un CALayer n'est pas possible "officiellement" car si tu accèdes à la propriété 'contents' d'un CALayer, selon les test que j'ai fait, il ne te donne pas un CGImageRef ou une {NS,UI}Image, mais une classe privée non documenté : CABackingStore, par exemple : Code NSLog(@"%@", aLayer.contents); // NSLog output : <CABackingStore 0x7181b90 (buffer [640 480] BGRA8888)> J'espère qu' avec ça tu as de quoi trouver la solution à ton problème. A++ Ce message a été modifié par iMobile - 7 Feb 2015, 15:08. |
|
|
7 Feb 2015, 15:57
Message
#3
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 831 Inscrit : 19 Jul 2001 Lieu : Живим у Греноблу Membre no 519 |
C'est parfait, je suis passé par AVCaptureFileOutputDelegate !!!
Ca a l'air nickel, j'ai accès aux infos sur les images et à l'image à priori. J'ai du ajouter le framework coreVideo pour accéder à tout ça. Désolé, la question semblait peut être bête, mais ça fait assez longtemps que j'ai pas touché à du code Cocoa (5-6 ans) et ça a pas mal changé depuis... J'atais un peu paumé dans le doc, et je n'ai pas beaucoup de temps pour tout lire malheureusement. -------------------- Хајде Јано коло да играмо
iMac 27 mi 2010 Macbook air mi 2011 Mac Mini M1 |
|
|
7 Feb 2015, 16:45
Message
#4
|
|
Nouveau Membre Groupe : Membres Messages : 39 Inscrit : 21 Mar 2012 Membre no 175 442 |
Il y a surtout que la documentation n'est pas très explicite. Sans savoir que CVPixelBufferRef existe et que c'est qu'il faut obtenir de l'instance de AVCaptureOutput pour accéder aux pixels, pas évident de faire le lien.
|
|
|
7 Feb 2015, 22:11
Message
#5
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 831 Inscrit : 19 Jul 2001 Lieu : Живим у Греноблу Membre no 519 |
Ok, je comprends mieux pourquoi j'ai pas trouvé tout seul.
Sinon, après avoir regardé le buffer qu'il me ressort, je me retrouve avec du 2vuy ou quelque chose de similaire (pour ça que j'avais 2 octets par pixel...). Bref, pas du bon vieux RGB. Alors, j'ai trouvé une formule pour convertir, mais j'ai l'impression que je peux m'en sortir avec la luminance seule dans mon cas. Le truc, c'est que quelque soit l'image, la luminance a pas l'air de bouger beaucoup, alors que la chrominance semble beaucoup plus varier en fonction de où je mets ma tête... -------------------- Хајде Јано коло да играмо
iMac 27 mi 2010 Macbook air mi 2011 Mac Mini M1 |
|
|
13 Feb 2015, 18:06
Message
#6
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 831 Inscrit : 19 Jul 2001 Lieu : Живим у Греноблу Membre no 519 |
Pour info, la façon dont fonctionne les pixels en 2vuy est assez bizarre.
En gros, il y a un premier pixel ou la luminance est donnée, puis la chrominance rouge (donc 2 cotets), puis le pixel d'après, la luminance et la chrominance verte (2 autres octets). Les 2 chrominances des 2 pixels (rouge et vert) sont combinés pour ces 2 pixel, et la luminance est propre à chaque pixel. L'idée est de dire que l'oeil humain (dans le cas de la vidéo) est assez indifférent à un changement de chrominance sur 2 pixels et qu'il vaut mieux mutualiser cette info pour gagner de la place (un genre de compression). Par contre, l'oeil humain est sensible à la luminance, elle est donc importante sur chaque pixel. On utilise donc en réalité 4 octets pour coder 2 pixels cote à cote. -------------------- Хајде Јано коло да играмо
iMac 27 mi 2010 Macbook air mi 2011 Mac Mini M1 |
|
|
Nous sommes le : 26th April 2024 - 15:18 |