2010-02-09 15 views

उत्तर

0

मुझे नहीं लगता कि कम से कम वर्तमान संस्करण के साथ ऐसा करना संभव है। बेशक, यह करने के लिए है कि मुश्किल नहीं होगा, लेकिन यह इस तरह के एक दिलचस्प सुविधा है, के रूप में नहीं है:

  • OpenCV आमतौर पर वेब कैमरा धारा पर काम करता है, जो आरजीबी प्रारूप में हैं, या कोडित फ़ाइलें, जो कर रहे हैं पर प्रदर्शन उद्देश्यों के लिए आरजीबी में सीधे डीकोड किया गया;
  • ओपनसीवी कंप्यूटर विजन को समर्पित है, जहां उदाहरण के लिए कोडिंग समुदाय की तुलना में वाईयूवी कम आम प्रारूप है;
  • बहुत सारे यूयूवी प्रारूप हैं, जो उन्हें लागू करने के लिए बहुत सारे काम का संकेत देंगे।

रूपांतरण अभी भी संभव है, cvCvtColor() का उपयोग करते हुए, जिसका अर्थ यह है कि यह किसी भी रुचि का है। 2: 0 प्लानर छवि फ़ाइल https://github.com/chelyaev/opencv-yuv

मैं कुछ कोड है कि एक एकल YUV 4 पढ़ा जाएगा पोस्टिंग कर रहा हूँ:

3

अद्यतन वहाँ कोड यहाँ के एक नए संस्करण है। आप इसे अधिकतर यूयूवी फाइलों पर सीधे लागू कर सकते हैं (केवल उसी FILE ऑब्जेक्ट से पढ़ते रहें)। अपवाद यह है कि YUV files that have a header से निपटने पर (आमतौर पर, उनके पास *.y4m एक्सटेंशन होता है)। आप इस तरह के फाइलों के साथ सौदा करना चाहते हैं, तो आप दो विकल्प हैं:

  1. अपने खुद के समारोह लिखें * .y4m छवियों से हेडर नीचे
  2. पट्टी कोड उपयोग करने से पहले FILE वस्तु से हैडर डेटा का उपभोग करने के लिए (ffmpeg या इसी तरह के उपकरण का उपयोग कर)। यह विकल्प है जिसे मैं पसंद करता हूं क्योंकि यह सबसे आसान है।

यह वाईयूवी प्रारूप (गैर-प्लानर, विभिन्न क्रोमा decimation) के किसी अन्य रूप के लिए भी काम नहीं करेगा। जैसा कि @ स्टीफन ने इंगित किया है, ऐसे कई प्रारूप हैं (और उनमें से अधिकतर कोई पहचान करने वाले शीर्षलेख नहीं हैं), शायद यही कारण है कि ओपनसीवी बॉक्स के बाहर उनका समर्थन नहीं करता है।

लेकिन उनके साथ काम करने में काफी सरल है: एक छवि के साथ

  • प्रारंभ और यह आयाम है
  • पढ़ें लुमा और 3 अलग छवियों
  • एक उच्च स्तरीय में क्रोमा (जब एक YUV फ़ाइल को पढ़ने के लिए इस की आवश्यकता है) क्रोमा decimation के लिए मुआवजे के लिए 2 के एक कारक द्वारा chroma छवियों। नोट कि वास्तव में कई क्रोमा decimation की क्षतिपूर्ति करने के तरीके हैं। Upsampling बस सबसे सरल
  • वाईयूवी छवि में मिलाएं। यदि आप आरजीबी चाहते हैं, तो आप cvCvtColor का उपयोग कर सकते हैं।

अंत में, कोड:

IplImage * 
cvLoadImageYUV(FILE *fin, int w, int h) 
{ 
    assert(fin); 

    IplImage *py  = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); 
    IplImage *pu  = cvCreateImage(cvSize(w/2,h/2), IPL_DEPTH_8U, 1); 
    IplImage *pv  = cvCreateImage(cvSize(w/2,h/2), IPL_DEPTH_8U, 1); 
    IplImage *pu_big = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); 
    IplImage *pv_big = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); 
    IplImage *image = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 3); 
    IplImage *result = NULL; 

    assert(py); 
    assert(pu); 
    assert(pv); 
    assert(pu_big); 
    assert(pv_big); 
    assert(image); 

    for (int i = 0; i < w*h; ++i) 
    { 
     int j = fgetc(fin); 
     if (j < 0) 
      goto cleanup; 
     py->imageData[i] = (unsigned char) j; 
    } 

    for (int i = 0; i < w*h/4; ++i) 
    { 
     int j = fgetc(fin); 
     if (j < 0) 
      goto cleanup; 
     pu->imageData[i] = (unsigned char) j; 
    } 

    for (int i = 0; i < w*h/4; ++i) 
    { 
     int j = fgetc(fin); 
     if (j < 0) 
      goto cleanup; 
     pv->imageData[i] = (unsigned char) j; 
    } 

    cvResize(pu, pu_big, CV_INTER_NN); 
    cvResize(pv, pv_big, CV_INTER_NN); 
    cvMerge(py, pu_big, pv_big, NULL, image); 

    result = image; 

cleanup: 
    cvReleaseImage(&pu); 
    cvReleaseImage(&pv); 

    cvReleaseImage(&py); 
    cvReleaseImage(&pu_big); 
    cvReleaseImage(&pv_big); 

    if (result == NULL) 
     cvReleaseImage(&image); 

    return result; 
} 
+0

मैं अब एक ही समस्या है, मैं खोलने के लिए और एक वीडियो है कि UYVY है के साथ काम करने की कोशिश कर रहा हूँ (4: 2: 2) यदि आप कोड कोडेक के रूप में, मैं करने की कोशिश की, लेकिन यह काम नहीं किया मैं जानता हूँ कि आपने उल्लेख किया है कि आपके उत्तर में, लेकिन क्या आप बता सकते हैं क्यों ?? आपके लिए अग्रिम धन्यवाद – Engine

+1

मैंने जो कोड पोस्ट किया है वह यूयूवी 4: 2: 0 हैंडल करता है। चूंकि आपका वीडियो YUV 4: 2: 2 में है, तो मेरा कोड निश्चित रूप से आपके वीडियो पर सीधे काम नहीं करेगा। आपको अपने प्रारूप को संभालने के लिए कोड को अनुकूलित करने की आवश्यकता होगी। अधिक जानकारी के लिए, देखें: http://en.wikipedia.org/wiki/Chroma_subsampling#4ss – misha

0

मैं एक ही समस्या का सामना करना पड़ा। मेरा समाधान 1 है।एक युग फ्रेम (जैसे I420) को एक स्ट्रिंग ऑब्जेक्ट "yuv" पर पढ़ें। 2. यूवी फ्रेम को बीजीआर 24 प्रारूप में कनवर्ट करें। मैं इसे करने के लिए libyuv का उपयोग करें। Libyuv कार्यों के लिए एक पाइथन wrapper लिखना आसान है। अब आप बीजीआर 24 प्रारूप के साथ एक और स्ट्रिंग ऑब्जेक्ट "बीजीआर" प्राप्त करते हैं। 3. "bgr" स्ट्रिंग ऑब्जेक्ट से छवि ऑब्जेक्ट प्राप्त करने के लिए numpy.fromstring का उपयोग करें। आपको छवि ऑब्जेक्ट का आकार बदलने की जरूरत है।

नीचे आपके संदर्भ के लिए एक सरल यूव दर्शक है।

http://www.fourcc.org/yuv.php

OpenCV में एक YUV प्रारूप से आरजीबी में बदलने के लिए है बहुत ही सरल:

import cv2 
# below is the extension wrapper for libyuv 
import yuvtorgb 
import numpy as np 

f = open('i420_cif.yuv', 'rb') 

w = 352 
h = 288 
size = 352*288*3/2 

while True: 
    try: 
     yuv = f.read(size) 
    except: 
     break 
    if len(yuv) != size: 
     f.seek(0, 0) 
     continue 

    bgr = yuvtorgb.i420_to_bgr24(yuv, w, h) 

    img = np.fromstring(bgr, dtype=np.uint8) 
    img.shape = h,w,3 

    cv2.imshow('img', img) 

    if cv2.waitKey(50) & 0xFF == ord('q'): 
     break 

cv2.destroyAllWindows() 
4

के रूप में उल्लेख किया है, वहाँ YUV प्रारूपों के कई प्रकार हैं

  1. एक नया खाता बनाएं - उस फ्रेम डेटा के लिए उचित आकार का डिमेंशनल ओपनसीवी मैट
  2. वांछित डी के साथ आरजीबी डेटा के लिए एक खाली मैट बनाएं imension और 3 चैनलों
  3. साथ
  4. अंत में cvtColor का उपयोग YV12 प्रारूप में एक YUV बफर के लिए दो मैट के बीच परिवर्तित करने के लिए, सही रूपांतरण झंडा enum

यहाँ एक उदाहरण उपयोग कर रहा है:

Mat mYUV(height + height/2, width, CV_8UC1, (void*) frameData); 
Mat mRGB(height, width, CV_8UC3); 
cvtColor(mYUV, mRGB, CV_YUV2RGB_YV12, 3); 

कुंजी चाल आपके आरजीबी मैट के आयामों को से पहले कनवर्ट करना है।

+0

यह सही उत्तर है। मैं वाईयूवी की एनवी 12 विविधता को संभालने में कामयाब रहा था और इससे मुझे प्रारूप को समझने में मदद मिली: https://wiki.videolan.org/YUV/#NV12, https://commons.wikimedia.org/wiki/File:Common_chroma_subsampling_ratios .svg – rhardih

2

मैंने बाइनरी फ़ाइल से वाईयूवी एनवी 21 स्ट्रीम पढ़ने के लिए एक बहुत ही सरल पायथन कोड लिखा था।

import cv2 
import numpy as np 

class VideoCaptureYUV: 
    def __init__(self, filename, size): 
     self.height, self.width = size 
     self.frame_len = self.width * self.height * 3/2 
     self.f = open(filename, 'rb') 
     self.shape = (int(self.height*1.5), self.width) 

    def read_raw(self): 
     try: 
      raw = self.f.read(self.frame_len) 
      yuv = np.frombuffer(raw, dtype=np.uint8) 
      yuv = yuv.reshape(self.shape) 
     except Exception as e: 
      print str(e) 
      return False, None 
     return True, yuv 

    def read(self): 
     ret, yuv = self.read_raw() 
     if not ret: 
      return ret, yuv 
     bgr = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_NV21) 
     return ret, bgr 


if __name__ == "__main__": 
    #filename = "data/20171214180916RGB.yuv" 
    filename = "data/20171214180916IR.yuv" 
    size = (480, 640) 
    cap = VideoCaptureYUV(filename, size) 

    while 1: 
     ret, frame = cap.read() 
     if ret: 
      cv2.imshow("frame", frame) 
      cv2.waitKey(30) 
     else: 
      break 
संबंधित मुद्दे