2012-03-30 34 views
6

Tôi cố gắng để sử dụng chức năng người phát hiện trong OpenCV:CGBitmapContextCreate cho CV_8UC3 (để sử dụng trong OpenCV)

cv::HOGDescriptor hog; 
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); 
std::vector<cv::Rect> found; 
hog.detectMultiScale(noMask, found, 0.2, cv::Size(8,8), cv::Size(16,16), 1.05, 2); 

Nhưng tôi nhận được sự khẳng định sau đây:

OpenCV Error: Assertion failed (img.type() == CV_8U || img.type() == CV_8UC3) in computeGradient, file /Users/robin/Projects/OpenCVForiPhone/opencv/opencv/modules/objdetect/src/hog.cpp, line 174

Và nó có ý nghĩa vì Tôi đang chuyển một hình ảnh CV_8UC4.

Vì vậy, tôi đoán tôi nên tạo một cvmat với đặc điểm này. Ngay bây giờ tôi có 2 phương pháp này. mà cho phép tôi để có được màu xám hoặc màu cvmats (CV_8UC1/CV_8UC4)

Đối Màu sắc:

-(cv::Mat)CVMat 
{ 

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage); 
    CGFloat cols = self.size.width; 
    CGFloat rows = self.size.height; 

    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels 

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,     // Pointer to backing data 
                cols,      // Width of bitmap 
                rows,      // Height of bitmap 
                8,       // Bits per component 
                cvMat.step[0],    // Bytes per row 
                colorSpace,     // Colorspace 
                kCGImageAlphaNoneSkipLast | 
                kCGBitmapByteOrderDefault); // Bitmap info flags 

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage); 
    CGContextRelease(contextRef); 

    return cvMat; 
} 

Đối với Grayscale:

-(cv::Mat)CVGrayscaleMat 
{ 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 
    CGFloat cols = self.size.width; 
    CGFloat rows = self.size.height; 

    cv::Mat cvMat = cv::Mat(rows, cols, CV_8UC1); // 8 bits per component, 1 channel 

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,     // Pointer to backing data 
                cols,      // Width of bitmap 
                rows,      // Height of bitmap 
                8,       // Bits per component 
                cvMat.step[0],    // Bytes per row 
                colorSpace,     // Colorspace 
                kCGImageAlphaNone | 
                kCGBitmapByteOrderDefault); // Bitmap info flags 

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage); 
    CGContextRelease(contextRef); 
    CGColorSpaceRelease(colorSpace); 

    return cvMat; 
} 

Và đây là dự đoán của tôi để làm cho 3 kênh:

-(cv::Mat)CVMat3Channels 
{ 

    //CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGFloat cols = self.size.width; 
    CGFloat rows = self.size.height; 

    cv::Mat cvMat(rows, cols, CV_8UC3); // 8 bits per component, 3 channels 

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,    // Pointer to backing data 
                cols,      // Width of bitmap 
                rows,      // Height of bitmap 
                8,       // Bits per component 
                cvMat.step[0],    // Bytes per row 
                colorSpace,     // Colorspace 
                kCGImageAlphaNoneSkipLast | 
                kCGBitmapByteOrderDefault); // Bitmap info flags 

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage); 
    CGContextRelease(contextRef); 
    CGColorSpaceRelease(colorSpace); 

    return cvMat; 
} 

Nhưng tôi nhận được lỗi sau:

<Error>: CGBitmapContextCreate: invalid data bytes/row: should be 
     at least 9792 for 8 integer bits/component, 3 components, 
     kCGImageAlphaNoneSkipLast. 
<Error>: CGContextDrawImage: invalid context 0x0 

Vì vậy, câu hỏi của tôi là, cách chính xác của việc tạo ra một 8UC3 tương thích CGBitmapContext là gì? (Tôi giả sử 8UC3 có nghĩa là 8 bit mỗi pixel với các kênh RGB)

Cảm ơn bạn.

PD: Mã chuyển đổi hình ảnh là từ Robin Summerhill.

Trả lời

0

Bạn đang tạo hình ảnh 3 kênh chính xác bằng cách sử dụng CV_8UC3. Vì CGBitmapContextCreate mong đợi 9792 byte/hàng, điều đó có nghĩa là phải có 3264 cột (trong số các pixel 3 kênh). Nếu tôi chạy đoạn mã sau,

int cols = 3264; 
int rows = 1960; // assuming a ~1.66 aspect ratio here... 
Mat temp(rows, cols, CV_8UC3); 
cout << temp.step[0] << endl; 

nó ra 9792 như là yêu cầu của CGBitmapContextCreate. Bạn có thể nói những gì cvMat.step[0] đang trở lại trong mã của bạn? Nó có vẻ đúng, nhưng có thể cái gì khác đang xảy ra.

Ngoài ra, lưu ý OpenCV tự lưu trữ dữ liệu ở định dạng BGR nếu bạn đang nhận dữ liệu hình ảnh từ các chức năng OpenCV như imread v.v. Vì vậy, nếu màu sắc trông lạ, hãy chú ý đến điều đó.

+0

Xin chào đây là kết quả: – Pochi

+0

cols: 2448.000000, hàng: 3264.000000, 7344, nhưng tôi không hiểu, chức năng này hoạt động cho các định dạng khác của tôi. Hình ảnh này là từ iphone. – Pochi

+0

Thứ gì đó cá đang diễn ra ở đây ... Bước 7344 chính xác là 2448.0 * 3. Vì vậy, có vẻ như các cột và hàng của bạn đang được đổi chỗ ở đâu đó. Mặc dù, nó không giống như nó từ mã của bạn. Có phải thứ gì đó như độ nghiêng màn hình xảy ra khiến các thứ nguyên chuyển vị? – mevatron

3

Một cách tiếp cận khác nhau có thể được tạo ra một ma trận CV_8UC4 và sau đó tách các kênh, lấy một ma trận BGR, và một ma trận alpha (loại bỏ trong trường hợp này):

cv::Mat CVMat(CGImageRef cgimage) 
{ 

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgimage); 
    CGFloat cols = CGImageGetWidth(cgimage); 
    CGFloat rows = CGImageGetHeight(cgimage); 

    cv::Mat rgba(rows, cols, CV_8UC4, Scalar(1,2,3,4)); // 8 bits per component, 4 channels 

    CGContextRef contextRef = CGBitmapContextCreate(rgba.data,     // Pointer to backing data 
                cols,      // Width of bitmap 
                rows,      // Height of bitmap 
                8,       // Bits per component 
                rgba.step[0],    // Bytes per row 
                colorSpace,     // Colorspace 
                kCGImageAlphaNoneSkipLast | 
                kCGBitmapByteOrderDefault); // Bitmap info flags 

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), cgimage); 
    CGContextRelease(contextRef); 

    Mat bgr(rgba.rows, rgba.cols, CV_8UC3); 
    Mat alpha(rgba.rows, rgba.cols, CV_8UC1); 

    Mat out[] = { bgr, alpha }; 
    // rgba[0] -> bgr[2], rgba[1] -> bgr[1], 
    // rgba[2] -> bgr[0], rgba[3] -> alpha[0] 
    int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; 
    mixChannels(&rgba, 1, out, 2, from_to, 4); 

    return bgr; 
} 
6

tôi đã sử dụng cách pha trộn của bạn, nhưng nó không hoạt động: kết quả là hình ảnh màu RGB, nhưng mất nhiều màu.

Vì vậy, tôi có một cách rất đơn giản để chuyển đổi, và nó thành công

Mã này là trong XCode:

lastImage = [firstImage CVMat]; 
cv::cvtColor(lastImage , lastImage , CV_RGBA2RGB); 

Nó sẽ chuyển đổi lastImage màu RGB, với phong cách CV_8UC3.

Xin lỗi vì đây là lần đầu tiên tôi nhận xét và tôi không biết cách định dạng này.

Các vấn đề liên quan