2011-09-18 15 views
15

मैं एक पीएनजी फ़ाइल से 24 बिट आरजीबी छवि को अपने ओपनसीवी एप्लिकेशन में लोड कर रहा हूं।आरजीबी से ग्रेस्केल से ओपनसीवी छवि रूपांतरण खराब परिणाम देकर इमेड का उपयोग करते हुए

हालांकि छवि को imread का उपयोग करके सीधे ग्रेस्केल के रूप में लोड करना बहुत खराब परिणाम देता है।

Mat src1 = imread(inputImageFilename1.c_str(), 0); 

आरजीबी के रूप में आरजीबी छवि लोड हो रहा है और यह ग्रेस्केल में कनवर्ट एक बेहतर की तलाश में परिणाम देता है।

Mat src1 = imread(inputImageFilename1.c_str(), 1); 
cvtColor(src1, src1Gray, CV_RGB2GRAY); 

मुझे आश्चर्य है कि क्या मैं अपनी छवि प्रकार के लिए imread का उपयोग कर रहा हूं। क्या किसी ने भी इसी तरह के व्यवहार का अनुभव किया है?

छवि imread का उपयोग कर स्केल के लिए परिवर्तित यहाँ दिखाया गया है: Bad result

छवि cvtColor का उपयोग कर स्केल के लिए परिवर्तित यहाँ दिखाया गया है: Good result

+5

ओपनसीवी में "रंग" छवि का अर्थ बीजीआर है। तो आपके कोड का दूसरा संस्करण सही नहीं है। इसे रंग रूपांतरण के लिए 'CV_BGR2GRAY' का उपयोग करना चाहिए। –

+0

टिप्पणी के लिए धन्यवाद। मैंने सीवी_आरजीबी 2GRAY के बजाय छवि को CV_BGR2GRAY का उपयोग करके ग्रेस्केल में कनवर्ट करने का प्रयास किया, लेकिन एक ही परिणाम मिला। – tisch

+0

क्या आप अपनी मूल छवि भी संलग्न कर सकते हैं? –

उत्तर

16

मुझे आज भी यही समस्या थी। अंत में, मैं तीन तरीकों की तुलना में:

//method 1 
cv::Mat gs = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE); 

//method 2 
cv::Mat color = cv::imread(filename, 1); //loads color if it is available 
cv::Mat gs_rgb(color.size(), CV_8UC1); 
cv::cvtColor(color, gs_rgb, CV_RGB2GRAY); 

//method 3 
cv::Mat gs_bgr(color.size(), CV_8UC1); 
cv::cvtColor(color, gs_bgr, CV_BGR2GRAY); 

तरीके 1 (लोड हो रहा है ग्रेस्केल) और 3 (CV_BGR2GRAY) समान परिणाम है, जबकि विधि 2 एक अलग परिणाम पैदा करता है। अपने स्वयं के सिरों के लिए, मैंने CV_BGR2GRAY का उपयोग शुरू कर दिया है।

मेरी इनपुट फ़ाइलें jpg हैं, इसलिए आपके विशेष छवि प्रारूप से संबंधित समस्याएं हो सकती हैं।

+0

ओपनसीवी इमेड बीजीआर प्रारूप में इमेज रिटर्न देता है, इसलिए मुझे लगता है कि ग्रे स्केल में सही रूपांतरण सीवी_BGR2GRAY है जैसा कि आपने तीसरी विधि – evk1206

1

मैं एक बार एक ऐसी ही समस्या पड़ा है, ओपन shaders के साथ काम । ऐसा लगता है कि ओपनसीवी आपकी छवि को पढ़ने वाला पहला कंटेनर रंग की सभी श्रेणियों का समर्थन नहीं करता है और इसलिए आप देखते हैं कि छवि एक खराब ग्रेस्केल परिवर्तन है। हालांकि एक बार जब आप मूल छवि को cvtColor का उपयोग करके ग्रेस्केल में परिवर्तित करते हैं तो कंटेनर पहले से अलग होता है और सभी श्रेणियों का समर्थन करता है। मेरी राय में पहला ग्रेस्केल के लिए 8 बिट से कम का उपयोग करता है या ग्रेस्केल में बदलना एक खराब विधि का उपयोग करता है। लेकिन दूसरा दूसरा ग्रे चैनल में अधिक बिट्स की वजह से चिकनी छवि देता है।

+0

क्या आपको इस तर्क का समर्थन करने के लिए प्रलेखन मिला? इसी तरह की समस्या का सामना करना और मुझे विश्वास है कि यह मामला हो सकता है लेकिन मेरे तर्क – Ani

+0

में डालने के लिए कुछ भी नहीं मिला है, वैसे ही यह मामला है क्योंकि फ्रेम बफर में प्रत्येक रंग के लिए 255 की सीमा और मोनोक्रोम के लिए 255 भी शामिल है स्पेक्ट्रम। बेहतर सीमा का समर्थन करने के लिए आपको फ़्लोटिंग पॉइंट की आवश्यकता है। –

10

सरल उत्तर यह है कि ओपनसीवी फ़ंक्शन बीजीआर प्रारूप का उपयोग करता है। यदि आप imread या VideoCapture वाली छवि में पढ़ते हैं, तो यह हमेशा बीजीआर होगा। यदि आप आरजीबी 2GRAY का उपयोग करते हैं, तो आप हरे रंग के चैनल के साथ हरे रंग के चैनल का आदान-प्रदान करते हैं। चमक प्राप्त करने के लिए सूत्र

y = 0.587*green + 0.299*red + 0.114*blue 

इसलिए यदि आप हरे और नीले रंग को बदलते हैं, तो इससे बड़ी गणना त्रुटि होगी।

ग्रीट

+1

में उल्लेख किया है, क्या यह लाल चैनल को भी बदल नहीं रहा है? इस मामले में दिए गए 'बीजीआर' को' आरजीबी 'के रूप में व्याख्या करना जो उसके बाद (वास्तविक)' बी 'को गलत रूप से' आर 'के रूप में व्याख्या किया जा रहा है, और 'आर'' बी' के रूप में व्याख्या किया जा रहा है? तो आपके उत्तर के मुताबिक फिक्स 'सीवी_आरबीजी 2GRAY' में 'सीवी_आरबीजी 2GRAY'' को' सीवीबीजी 2GRAY' के साथ 'सीवीटीजीओएलआर' कॉल में बदल देगा? –

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