سؤال

أحتاج إلى تحويل iplimage 8 بت إلى iplimage 32 بت. باستخدام الوثائق من جميع أنحاء الويب التي جربتها الأشياء التالية:

// 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.

كما ترى أنني لا أعرف حقا ما أفعله. أحب أن أعرف ذلك، لكنني أحبها أكثر إذا تمكنت من ذلك بشكل صحيح. شكرا لأي مساعدة أحصل عليها!

هل كانت مفيدة؟

المحلول

ربما هذا حلقة الوصل يستطيع مساعدتك؟

يحرر استجابة للتحرير الثاني من OP والتعليق

هل حاولت

float value = 0.5

بدلا من

float value = 0x0000001;

اعتقدت أن نطاق قيمة اللون تعويم يذهب من 0.0 إلى 1.0، حيث 1.0 أبيض.

نصائح أخرى

الوظيفة التي تبحث عنها هي 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.0 إلى 1.0، وتذهب chars من 0 إلى 255. يعمل التعليمات البرمجية التالية على إصلاحه:

// 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;

الكثير، شكرا جزيلا ستيفان شميدت لمساعدتي في إصلاح هذا!

إذا لم تقم بوضع النقطة (.)، فسوف يفهم بعض المبرائح هي كقسمة INT، مما يتيح لك نتيجة كثيرة (صفر في هذه الحالة).

يمكنك إنشاء غلاف iplimage باستخدام دفعة :: Shared_ptr وقوالب Metaprogramming. لقد فعلت ذلك، وأحصل على مجموعة القمامة التلقائية، جنبا إلى جنب مع تحويلات الصور التلقائية من عمق إلى آخر، أو من قناة واحدة إلى صور متعددة القنوات.

لقد اتصلت ب API Blimageapi ويمكن العثور عليها هنا:http://www.barbato.uscoom/2010/10/14/IMAGE-DATA-SIRTEL-BASED-SHARED_PTR-PLIMIGHAGE/

إنه سريع جدا، واجعل الرمز قابل للقراءة للغاية، (جيد للحفاظ على الخوارزميات)

كما يمكن استخدامه بدلا من iplimage في خوارزميات OpenCV دون تغيير أي شيء.

حظا سعيدا واستمتع بخوارزميات الكتابة !!!

iplimage * img8، * img32؛
IMG8 = CVLoDImage ("A.jpg"، 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");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top