2011-11-07 16 views
5

पर यूयूवी 422 सही करें मैं एक सप्ताह के लिए एक आरजीबी रूपांतरण समस्या में एक YUV422 से निपटने की कोशिश कर रहा हूं। मैंने कई अलग-अलग वेबसाइटों का दौरा किया है और प्रत्येक से अलग सूत्र प्राप्त किए हैं। अगर किसी और के पास कोई सुझाव है तो मुझे उनके बारे में सुनकर खुशी होगी। नीचे दिए गए सूत्र मुझे या तो सभी बैंगनी या हरे रंग के रंग के साथ एक छवि देते हैं। इस पल के रूप में मैं एक सूत्र नहीं ढूंढ पाया है जो मुझे उचित आरजीबी छवि वापस पाने की अनुमति देता है। मैंने नीचे दिए गए कोड के मेरे सभी विभिन्न भाग शामिल किए हैं।आरजीबी रूपांतरण

//for(int i = 0; i < 1280 * 720 * 3; i=i+3) 
    //{ 
    // /*m_RGB->imageData[i] = pData[i] + pData[i+2]*((1 - 0.299)/0.615); 
    // m_RGB->imageData[i+1] = pData[i] - pData[i+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[i+2]*((0.299*(1 - 0.299))/(0.615*0.587)); 
    // m_RGB->imageData[i+2] = pData[i] + pData[i+1]*((1 - 0.114)/0.436);*/ 

    // m_RGB->imageData[i] = pData[i] + 1.403 * (pData[i+1] - 128); 
    // m_RGB->imageData[i+1] = pData[i] + 0.344 * (pData[i+1] - 128) - 0.714 * (pData[i+2] - 128); 
    // m_RGB->imageData[i+2] = pData[i] + 1.773 * (pData[i+2] - 128); 
    //} 

    for(int i = 0, j=0; i < 1280 * 720 * 3; i+=6, j+=4) 
    { 
     /*m_RGB->imageData[i] = pData[j] + pData[j+3]*((1 - 0.299)/0.615); 
     m_RGB->imageData[i+1] = pData[j] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587)); 
     m_RGB->imageData[i+2] = pData[j] + pData[j+1]*((1 - 0.114)/0.436); 
     m_RGB->imageData[i+3] = pData[j+2] + pData[j+3]*((1 - 0.299)/0.615); 
     m_RGB->imageData[i+4] = pData[j+2] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587)); 
     m_RGB->imageData[i+5] = pData[j+2] + pData[j+1]*((1 - 0.114)/0.436);*/ 

     /*m_RGB->imageData[i] = pData[j] + 1.403 * (pData[j+3] - 128); 
     m_RGB->imageData[i+1] = pData[j] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128); 
     m_RGB->imageData[i+2] = pData[j] + 1.773 * (pData[j+1] - 128); 
     m_RGB->imageData[i+3] = pData[j+2] + 1.403 * (pData[j+3] - 128); 
     m_RGB->imageData[i+4] = pData[j+2] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128); 
     m_RGB->imageData[i+5] = pData[j+2] + 1.773 * (pData[j+1] - 128);*/ 

     BYTE Cr = pData[j+3] - 128; 
     BYTE Cb = pData[j+1] - 128; 
     /*m_RGB->imageData[i] = pData[j] + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); 
     m_RGB->imageData[i+1] = pData[j] - ((Cb >> 2) + (Cb >> 4) + (Cb >> 5)) - ((Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5)); 
     m_RGB->imageData[i+2] = pData[j] + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); 
     m_RGB->imageData[i+3] = pData[j+2] + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); 
     m_RGB->imageData[i+4] = pData[j+2] - ((Cb >> 2) + (Cb >> 4) + (Cb >> 5)) - ((Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5)); 
     m_RGB->imageData[i+5] = pData[j+2] + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);*/ 

     /*int R1 = clamp(1 * pData[j] + 0 * Cb + 1.4 * Cr, 0, 255), R2 = clamp(1 * pData[j+2] + 0 * Cb + 1.4 * Cr, 0, 255); 
     int G1 = clamp(1 * pData[j] - 0.343 * Cb - 0.711 * Cr, 0, 255), G2 = clamp(1 * pData[j+2] - 0.343 * Cb - 0.711 * Cr, 0, 255); 
     int B1 = clamp(1 * pData[j] + 1.765 * Cb + 0 * Cr, 0, 255), B2 = clamp(1 * pData[j+2] + 1.765 * Cb + 0 * Cr, 0, 255);*/ 

     /*int R1 = clamp(pData[j] + 1.403 * (pData[j+3] - 128), 0, 255), R2 = clamp(pData[j+2] + 1.403 * (pData[j+3] - 128), 0, 255); 
     int G1 = clamp(pData[j] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128), 0, 255), G2 = clamp(pData[j+2] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128), 0, 255); 
     int B1 = clamp(pData[j] + 1.773 * (pData[j+1] - 128), 0, 255), B2 = clamp(pData[j+2] + 1.773 * (pData[j+1] - 128), 0, 255);*/ 

     int R1 = clamp((298 * (pData[j] - 16) + 409 * (pData[j+3] - 128) + 128) >> 8, 0, 255), R2 = clamp((298 * (pData[j+2] - 16) + 409 * (pData[j+3] - 128) + 128) >> 8, 0, 255); 
     int G1 = clamp((298 * (pData[j] - 16) - 100 * (pData[j+1] - 128) - 208 * (pData[j+3] - 128) + 128) >> 8, 0, 255), G2 = clamp((298 * (pData[j+2] - 16) - 100 * (pData[j+1] - 128) - 208 * (pData[j+3] - 128) + 128) >> 8, 0, 255); 
     int B1 = clamp((298 * (pData[j] - 16) + 516 * (pData[j+1] - 128) + 128) >> 8, 0, 255), B2 = clamp((298 * (pData[j+2] - 16) + 516 * (pData[j+1] - 128) + 128) >> 8, 0, 255); 

     //printf("R: %d, G: %d, B: %d, R': %d, G': %d, B': %d \n", R1, G1, B1, R2, G2, B2); 

     m_RGB->imageData[i] = (char)R1; 
     m_RGB->imageData[i+1] = (char)G1; 
     m_RGB->imageData[i+2] = (char)B1; 
     m_RGB->imageData[i+3] = (char)R2; 
     m_RGB->imageData[i+4] = (char)G2; 
     m_RGB->imageData[i+5] = (char)B2; 

     /*m_RGB->imageData[i] = (char)(clamp(1.164 * (pData[j] - 16) + 1.793 * (Cr), 0, 255)); 
     m_RGB->imageData[i+1] = (char)(clamp(1.164 * (pData[j] - 16) - 0.534 * (Cr) - 0.213 * (Cb), 0, 255)); 
     m_RGB->imageData[i+2] = (char)(clamp(1.164 * (pData[j] - 16) + 2.115 * (Cb), 0, 255)); 
     m_RGB->imageData[i+3] = (char)(clamp(1.164 * (pData[j+2] - 16) + 1.793 * (Cr), 0, 255)); 
     m_RGB->imageData[i+4] = (char)(clamp(1.164 * (pData[j+2] - 16) - 0.534 * (Cr) - 0.213 * (Cb), 0, 255)); 
     m_RGB->imageData[i+5] = (char)(clamp(1.164 * (pData[j+2] - 16) + 2.115 * (Cb), 0, 255));*/ 
    } 

किसी भी मदद की बहुत सराहना की जाती है।

+1

YUV आंकड़ों का स्रोत क्या है, और क्या स्थान है? उदाहरण के लिए यदि गंतव्य विंडोज है तो आपको आरजीबी के बजाय बीजीआर ऑर्डर का उपयोग करने की आवश्यकता है। –

+0

वाईयूवी एक डेकलिंक तीव्रता प्रो कैप्चर कार्ड से आ रहा है। मैंने बीजीआर/आरजीबी मूल्यों को फ्लिप करने की भी कोशिश की और इससे मदद नहीं मिली। यह विंडोज बॉक्स – Seb

+0

पर किया जा रहा है यदि आप डेकलिंक एसडीके का उपयोग कर रहे हैं, तो आप कन्वर्टफ्रेम विधि का उपयोग क्यों नहीं करते हैं जो एपीआई का हिस्सा है? – ronag

उत्तर

5

कुछ सुराग आपकी मदद करने के साथ:

आप सीबी के साथ सीआर भ्रमित कर रहे हैं।

मान लिया जाये कि UYVY/422

Y1 = data[j+0]; 
Cr = data[j+1]; 
Y2 = data[j+2]; 
Cb = data[j+3]; 

आपकी रूपांतरण गणना अजीब, और HD सही नहीं हैं।

के लिए एसडी

R = max(0, min(255, 1.164(Y - 16) + 1.596(Cr - 128))); 
G = max(0, min(255, 1.164(Y - 16) - 0.813(Cr - 128) - 0.391(Cb - 128))); 
B = max(0, min(255, 1.164(Y - 16) + 2.018(Cr - 128))); 

के लिए HD

R = max(0, min(255, 1.164(Y - 16) + 1.793(Cr - 128))); 
G = max(0, min(255, 1.164(Y - 16) - 0.534(Cr - 128) - 0.213(Cb - 128))); 
B = max(0, min(255, 1.164(Y - 16) + 2.115(Cr - 128))); 

आप बस ConvertFrame जो चरम एसडीके का एक हिस्सा है इस्तेमाल कर सकते हैं।

+0

धन्यवाद क्योंकि आपके उत्तर ने मेरी मदद की। प्रश्न: एचडी का अर्थ 1280x720 या 1920x1080 है? 4k के बारे में क्या? btw ऑर्डर Y1CrY2Cb yuy2 के साथ मेरे लिए काम किया! हालांकि एमएसडीएन सीबी पर आधारित 'यू' है और यह वाई 1 सीबीवाई 2 सीआर होना चाहिए, लेकिन ऐसा करने से लाल रंग की जगह नीली दिखाई देती है! क्या आप समझा सकते हैं कि आदेश क्यों मुड़ गया? या msdn cb = 'u' मान्य नहीं है? 1 –

1

पैकिंग 422 मानते हुए मुझे आपके डेटा में से कोई भी सही ढंग से इनपुट डेटा नमूना नहीं दिख रहा है। पैक 422 में इनपुट डेटा Y1U1Y2V1 Y3U2Y4V2 जाएगा जहां समग्र छवि पूर्ण रिज़ॉल्यूशन पर एक वाई (लुमा) छवि होगी और प्रत्येक यू और वी प्रत्येक आधा क्षैतिज रिज़ॉल्यूशन पर होगी।

यहाँ मैं कहाँ शुरू होगा: इनपुट के बारी मूल्यों अनपैक और ग्रेस्केल छवि निकालें:

for (uint i = 0, j = 0; i < 1280 * 720 * 3; i += 3, j += 2) { 
    m_RGB->imageData[i] = pData[j]; 
    m_RGB->imageData[i+1] = pData[j]; 
    m_RGB->imageData[i+2] = pData[j]; 
} 

एक बार जब आप है कि तब ग्रेस्केल छवि बनाने के लिए pData[j+1] और pData[j+3] को देखकर यू और वी परिचय देखते है (या, पिक्सेल पर भी, pData[j-1] और pData[j+1])। सरलीकृत करना यही कारण है कि कुछ एल्गोरिदम एक समय में दो वाईयूवी पिक्सल करते हैं।

जब यू और वी छवियों को निकालने पर विचार करता है और 444 छवि बनाने के लिए उन्हें पूर्ण रिज़ॉल्यूशन में उचित रूप से पुन: लागू करता है। बस आसन्न पिक्सेल के लिए यू और वी डुप्लिकेट करना पिक्सल डुप्लिकेट करके upscaling की तरह है।

(नोट 420 की तरह है कि अन्य व्यवस्थाओं और भी जटिल सह siting है)

+0

यह मुझे एक ग्रेस्केल छवि मिली, लेकिन सबकुछ ऐसा लगता है जैसे गॉसियन ब्लर पर लागू किया गया था। – Seb

0

मैं भी रूपांतरण

// Get the bytes 
var u = bytes[0]; 
var y1 = bytes[1]; 
var v = bytes[2]; 
var y2 = bytes[3]; 

// Convert, cast to signed byte is important! 
var r = y + (1.403 * (sbyte)v); 
var g = y - (0.344 * (sbyte)u) - (0.714 * (sbyte)v); 
var b = y + (1.770 * (sbyte)u); 

if (r < 0) 
    r = 0; 
else if (r > 255) 
    r = 255; 

if (g < 0) 
    g = 0; 
else if (g > 255) 
    g = 255; 

if (b < 0) 
    b = 0; 
else if (b > 255) 
    b = 255; 

return Color.FromArgb((byte)r, (byte)g, (byte)b); 

u और vsbyte हैं के साथ संघर्ष किया, और y सिर्फ एक byte है।

+0

क्या आप कह रहे हैं कि यह सही रूपांतरण है या आप इस रूपांतरण का उपयोग करने की कोशिश कर रहे हैं? –

+0

यह सही संस्करण था –

3

आपकी समस्या यह है कि वहां बहुत से YUV422 प्रारूप हैं। आपको सटीक एक (आपके द्वारा उपयोग किए जा रहे विशिष्ट वीडियो के लिए चार सीसी इंडेक्स) मिलना चाहिए, और उसके बाद इसे डीकोड करने का सही तरीका पता लगाना चाहिए।

आप क्या कर सकते हैं अपने बोर्ड से कुछ वीडियो सहेजना, इसे वीएलसी में खोलना, और सटीक चार सीसीसी का उपयोग करने के लिए कोडेक विवरण देखें।

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

संबंधित मुद्दे