2008-12-27 16 views
11

मुझे एक 8-बिट IplImage को 32-बिट्स IplImage में कनवर्ट करने की आवश्यकता है। पूरे वेब से दस्तावेज़ीकरण का उपयोग करके मैंने निम्नलिखित चीजों को आजमाया है:एक 8-बिट OpenCV IplImage * को 32-बिट IplImage * में कैसे परिवर्तित करें?

// general code 
img2 = cvCreateImage(cvSize(img->width, img->height), 32, 3); 
int height = img->height; 
int width  = img->width; 
int channels = img->nChannels; 
int step1  = img->widthStep; 
int step2  = img2->widthStep; 
int depth1 = img->depth; 
int depth2 = img2->depth; 
uchar *data1 = (uchar *)img->imageData; 
uchar *data2 = (uchar *)img2->imageData; 

for(h=0;h<height;h++) for(w=0;w<width;w++) for(c=0;c<channels;c++) { 
    // attempt code... 
} 

// attempt one 
// result: white image, two red spots which appear in the original image too. 
// this is the closest result, what's going wrong?! 
// see: http://files.dazjorz.com/cache/conversion.png 
((float*)data2+h*step2+w*channels+c)[0] = data1[h*step1+w*channels+c]; 

// attempt two 
// when I change float to unsigned long in both previous examples, I get a black screen. 

// attempt three 
// result: seemingly random data to the top of the screen. 
data2[h*step2+w*channels*3+c] = data1[h*step1+w*channels+c]; 
data2[h*step2+w*channels*3+c+1] = 0x00; 
data2[h*step2+w*channels*3+c+2] = 0x00; 

// and then some other things. Nothing did what I wanted. I couldn't get an output 
// image which looked the same as the input image. 

जैसा कि आप देखते हैं कि मैं वास्तव में नहीं जानता कि मैं क्या कर रहा हूं। मुझे पता लगाना अच्छा लगेगा, लेकिन अगर मैं इसे सही तरीके से कर सकता हूं तो मैं इसे और अधिक पसंद करूंगा। मुझे प्राप्त होने वाली किसी भी मदद के लिए धन्यवाद!

उत्तर

6

शायद यह link आपकी मदद कर सकता है?

संपादित ओपी के दूसरे संपादित करें और टिप्पणी

आप

float value = 0.5

बजाय

float value = 0x0000001;

की कोशिश की है के जवाब में

मैं सीमा सोचा एक फ्लोट कलर वैल्यू 0.0 से 1.0 तक जाता है, wh ईर 1.0 सफेद है।

+0

उस पृष्ठ पर कुछ रोचक जानकारी नहीं है, कोड के टुकड़े जो समझाने मैं क्या है पहले से ही कोशिश की गई है। परिणाम वही हैं, हालांकि, हर समय गलत क्या है इसके उदाहरण के लिए निम्न लिंक देखें: http://files.dazjorz.com/cache/conversion.png – sgielen

+0

व्हाओ, हाँ, यह एक है अच्छा है, आप सही हैं! तो यह निम्नलिखित सुराग देता है: लाल धब्बे के लिए, आर 1.0 है और जीबी 0.0 है, और सफेद के लिए, सभी तीन 1.0 हैं। इसलिए कनवर्ट करते समय, आरजीबी मूल्यों को शांत करता है डी 0 से 255 से 0.0 से 1.0 में परिवर्तित किया जा सकता है। बी/255 में मूल्य बदलना छवि को काला + लाल बनाता है। – sgielen

+0

समझ गया! int b = ((uchar *) (img-> imageData + h * img-> widthStep)) [w * img-> nChannels + 0]; // बी ((फ्लोट *) (img2-> imageData + h * img2-> widthStep)) [w * img2-> nChannels + 0] = ((float) b)/255.0; – sgielen

2

चल बिन्दु रंग 1.0 करने के लिए 0.0 से जाते हैं, और uchars 255 से 0 से जाना निम्नलिखित कोड यह ठीक करता है:

// h is height, w is width, c is current channel (0 to 2) 
int b = ((uchar *)(img->imageData + h*img->widthStep))[w*img->nChannels + c]; 
((float *)(img2->imageData + h*img2->widthStep))[w*img2->nChannels + c] = ((float)b)/255.0; 

कई, कई मुझे इसे ठीक मदद करने के लिए स्टीफन श्मिट करने के लिए धन्यवाद!

28

जो फ़ंक्शन आप ढूंढ रहे हैं वह cvConvertScale() है। यह स्वचालित रूप से आपके लिए किसी प्रकार का रूपांतरण करता है। आपको बस यह निर्दिष्ट करना होगा कि आप 1/255 के कारक द्वारा स्केल करना चाहते हैं (जो सीमा [0 ... 255] से [0 ... 1] तक है)।

उदाहरण:

IplImage *im8 = cvLoadImage(argv[1]); 
IplImage *im32 = cvCreateImage(cvSize(im8->width, im8->height), 32, 3); 

cvConvertScale(im8, im32, 1/255.); 

नोट 1/255. में डॉट - एक डबल विभाजन के लिए मजबूर करने। इसके बिना आपको 0

+0

मैंने कोशिश की, लेकिन यह आउटपुट या इनपुट पैमाने को स्वीकार नहीं किया। या शायद मैंने इसे गलत तरीके से इस्तेमाल किया था। – sgielen

+11

यह महत्वपूर्ण है कि आप स्केलिंग कारक के रूप में दोगुना पास करें (यही कारण है कि 255 के पीछे '।' है। 1/255 पूर्णांक विभाजन के रूप में मूल्यांकन करेगा और 0 के स्केलिंग कारक का नेतृत्व करेगा। आपका कोड वास्तव में क्या है जो cvConvertScale() के साथ काम नहीं करता है? – Martin

+1

मेरी इच्छा है कि मैं अधिक अपवॉट डाल सकता हूं, मैंने आपकी टिप्पणी और आपका जवाब भी बढ़ाया। मैं कम से कम 8 घंटे देवदामित्र के लिए इस पर संघर्ष कर रहा हूं! – Eric

1

यदि आप डॉट (।) नहीं डालते हैं, तो कुछ कंपाइलर्स एक इंट डिवीजन के रूप में समझेंगे, जिससे आपको एक परिणाम मिलेगा (इस मामले में शून्य)।

1

आप boost :: shared_ptr और टेम्पलेट-मेटाप्रोग्रामिंग का उपयोग करके एक IplImage wrapper बना सकते हैं। मैंने यह किया है, और मुझे स्वत: कचरा संग्रह मिलता है, साथ ही स्वचालित छवि रूपांतरण एक गहराई से दूसरे तक, या एक-चैनल से बहु-चैनल छवियों तक।

मैं एपीआई blImageAPI कहा जाता है और यह यहां पाया जा सकता: http://www.barbato.us/2010/10/14/image-data-structure-based-shared_ptr-iplimage/

यह बहुत तेजी से है, और कोड बहुत पठनीय बनाने के लिए, (बनाए रखने एल्गोरिदम के लिए अच्छा)

यह भी इस्तेमाल किया जा सकता है IplImage के बजाय opencv एल्गोरिदम में कुछ भी बदले बिना।

शुभकामनाएं और मजेदार लेखन एल्गोरिदम !!!

0

IplImage * img8, * img32;
img8 = cvLoadImage ("ए।जेपीजी ", 1);

cvNamedWindow("Convert",1); 
    img32 = cvCreateImage(cvGetSize(img8),IPL_DEPTH_32F,3); 
    cvConvertScale(img8,img32,1.0/255.0,0.0); 

// पुष्टि करने के लिए (पिक्सेल मूल्यों की जाँच करें 0 के बीच - 1)

for(int row = 0; row < img32->height; row++){ 
       float* pt = (float*) (img32->imageData + row * img32->widthStep); 
       for (int col = 0; col < width; col++) 
          printf("\n %3.3f , %3.3f , %3.3f ",pt[3*col],pt[3*col+1],pt[3*col+2]);     
      } 

    cvShowImage("Convert",img32); 
    cvWaitKey(0); 
    cvReleaseImage(&img8); 
    cvReleaseImage(&img32); 
    cvDestroyWindow("Convert"); 
संबंधित मुद्दे