Tuesday, October 25, 2011

Porting OpenCV 2.3.1 to iPhone 3GS/4/4S - 如何將UIImage轉成OpenCV中資料結構Mat的data 當成影像處理之輸入

在Xcode iOS下要調用OpenCV的相關函數還有個難題就是如何將iOS中慣用來處來影像的Buffer - UIImage轉化成OpenCV內部使用Mat型態的資料結構內,下面這段程式紀錄如何達成此一目的的程序:
1. 先將UIImage中的影像資料轉出到資料型態為unsigned char *img中(img中為RGB raw data)

                UIImage *myImage1 = [UIImage imageNamed:@"test.jpg"];
                CGImageRef imageRef = [myImage1 CGImage];
                NSUInteger width = CGImageGetWidth(imageRef);
                NSUInteger height = CGImageGetHeight(imageRef);
                CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
                unsigned char *rawData = (unsigned char *)malloc(height * width * 4);
                NSUInteger bytesPerPixel = 4;
                NSUInteger bytesPerRow = bytesPerPixel * width;
                NSUInteger bitsPerComponent = 8;
                CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                             bitsPerComponent, bytesPerRow, colorSpace,
                                                             kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
                CGColorSpaceRelease(colorSpace);
                
                CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
                CGContextRelease(context);
                unsigned char * img = (unsigned char *)malloc(height * width * 3);
                for(int i=0;i
                    for(int j=0;j
                        img[i*width*3+j*3]=rawData[i*width*4+j*4];
                        img[i*width*3+j*3+1]=rawData[i*width*4+j*4+1];
                        img[i*width*3+j*3+2]=rawData[i*width*4+j*4+2];
                    }
                }
                free(rawData);


2. 呼叫OpenCV函式庫前先製作符合需求的Mat型態的資料結構full_img如下
        int refcount=1;
        Mat full_img;
        full_img.dims=2;
        full_img.rows=img_height;
        full_img.cols=img_width;
        full_img.flags|=0x00000010;
        full_img.refcount=&refcount;
        full_img.data=img;
        full_img.datastart=full_img.data;
        full_img.dataend=full_img.data+full_img.rows*full_img.cols*3;
        full_img.datalimit=full_img.data+full_img.rows*full_img.cols*3;
        full_img.size[0] = full_img.rows;
        full_img.size[1] = full_img.cols;
        full_img.step[0] = full_img.cols*3;
        full_img.step[1] = 3;

3. 需要使用到Mat型態的資料結構的函數呼叫,就可以傳入full_img當引數了


No comments:

Post a Comment