2016-12-06 2 views
0

Ich versuche, ein RGB-Bild in YUV zu konvertieren. Ich lade Bild mit openCV.Fehler in RGB zu YUV Umwandlung in FFmpeg

Ich rufe die Funktion wie folgt:

//I know IplImage is outdated 
IplImage* im = cvLoadImage("1.jpg", 1); 
//.... 
bgr2yuv(im->imageData, dst, im->width, im->height); 

die Funktion Farbbild zu konvertieren Bild YUV ist unten angegeben. Ich benutze ffmpeg, um das zu tun.

void bgr2yuv(unsigned char *src, unsigned char *dest, int w, int h) 
{ 
    AVFrame *yuvIm = avcodec_alloc_frame(); 
    AVFrame *rgbIm = avcodec_alloc_frame(); 
    avpicture_fill(rgbIm, src, PIX_FMT_BGR24, w, h); 
    avpicture_fill(yuvIm, dest, PIX_FMT_YUV420P, w, h); 
    av_register_all(); 

    struct SwsContext * imgCtx = sws_getCachedContext(imgCtx, 
             w, h,(::PixelFormat)PIX_FMT_BGR24, 
             w, h,(::PixelFormat)PIX_FMT_YUV420P, 
             SWS_BICUBIC, NULL, NULL, NULL); 

    sws_scale(imgCtx, rgbIm->data, rgbIm->linesize,0, h, yuvIm->data, yuvIm->linesize); 
    av_free(yuvIm); 
    av_free(rgbIm); 
} 

Ich bekomme eine falsche Ausgabe nach der Konvertierung. Ich denke, dies liegt an Padding in der IplImage. (Meine Eingabebildbreite ist kein Vielfaches von 4).

Ich habe die Linesize-Variable aktualisiert, auch nachdem ich keine korrekte Ausgabe bekomme. Es funktioniert gut, wenn ich Bilder verwenden, deren Breite ein Vielfaches von 4 ist.

Kann jemand sagen, was das Problem im Code ist.

Antwort

1

Überprüfen Sie IplImage::align oder IplImage::widthStep und verwenden Sie diese, um AVFrame::linesize zu setzen. Für den RGB Rahmen, zum Beispiel, würden Sie ein:

frame->linesize[0] = img->widthStep; 

Das Layout des dst Array sein kann, was Sie wollen, es hängt davon ab, wie Sie es später verwenden.

0

Wir müssen wie folgt vorgehen:

rgbIm->linesize[0] = im->widthStep; 

Aber ich denke, Ausgangsdaten von sws_scale() es nicht so von 4. mehrere machen gepolstert wird, wenn Sie kopieren diese Daten (DEST) wieder IplImage diese wird erstellen Problem bei der Anzeige, etc .. Speichern

Also brauchen wir widthStep=width wie folgt festzulegen:

IplImage* yuvImage = cvCreateImageHeader(cvGetSize(im), 8, 1); 
yuvImage->widthStep = yuvImage->width; 
yuvImage->imageData = dest; 
Verwandte Themen