簡體   English   中英

使用cvImageCreate()和灰度圖像的OpenCV失敗,並且調整大小通常會失敗

[英]OpenCV using cvImageCreate() with grayscale image fails, and resizing usually fails

我有這樣的代碼,它從緩沖區1byte,8bits位圖加載灰度圖像。 然后,它將調整此圖像的大小。

int resizeBitmap(const unsigned char *inData, const size_t inDataLength, const size_t inWidth, const size_t inHeight,
                 const int bitDepth, const int noOfChannels, unsigned char **outData, size_t *outDataLength, const size_t outWidth, const size_t outHeight) {

    // create input image
    IplImage *inImage = cvCreateImage(cvSize(inWidth, inHeight), bitDepth, noOfChannels);
    cvSetData(inImage, inData, inImage->widthStep);

      // show input image
        cvNamedWindow("OpenCV Input Image", CV_WINDOW_FREERATIO);
        cvShowImage("OpenCV Input Image", inImage);
        cvWaitKey(0);
        cvDestroyWindow("OpenCV Input Image");
    /* */

    // create output image
    IplImage *outImage = cvCreateImage(cvSize(outWidth, outHeight), inImage->depth, inImage->nChannels);

    // select interpolation type
    double scaleFactor = (((double) outWidth)/inWidth + ((double) outHeight)/inHeight)/2;
    int interpolation = (scaleFactor > 1.0) ? CV_INTER_LINEAR : CV_INTER_AREA;

    // resize from input image to output image
    cvResize(inImage, outImage, interpolation);

    /*  // show output image
        cvNamedWindow("OpenCV Output Image", CV_WINDOW_FREERATIO);
        cvShowImage("OpenCV Output Image", outImage);
        cvWaitKey(0);
        cvDestroyWindow("OpenCV Output Image");
    */

    // get raw data from output image
    int step = 0;
    CvSize size;
    cvGetRawData(outImage, outData, &step, &size);
    *outDataLength = step*size.height;

    cvReleaseImage(&inImage);
    cvReleaseImage(&outImage);

    return 0;
}

我在這里使用bitDepth = 8和noOfChannels =1。加載的圖像是: 在此處輸入圖片說明

輸出為: 在此處輸入圖片說明

由於程序通常會因以下錯誤而失敗,因此此輸出並不總是可以寫入:

OpenCV Error: Bad number of channels (Source image must have 1, 3 or 4 channels) in cvConvertImage, file /tmp/opencv-20160915-26910-go28a5/opencv-2.4.13/modules/highgui/src/utils.cpp, line 611
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv-20160915-26910-go28a5/opencv-2.4.13/modules/highgui/src/utils.cpp:611: error: (-15) Source image must have 1, 3 or 4 channels in function cvConvertImage

我將附加調試器輸出,因為有一個有趣的情況,因為我正在傳遞大小為528480的灰度緩沖區,該緩沖區等於1個字節* 1101 * 480,但是在cvCreateImage之后,里面有imageSize 529920,widthStep為1104! 也許這是此圖像的問題,但是為什么呢?

在此處輸入圖片說明

此問題與IplImage的widthstep和width有關。 Opencv將圖像填充為4個字節的倍數的widthstep。 在這里,opencv使用的寬度為1101,寬度為1104。但是,當從位圖寫入IplImage時,每行寫入的像素很少(注意從左上角到右下角的對角線)。

請注意,圖像沒有傾斜。 只是每隔一行向左移一點(3個像素),從而產生剪切轉換的想法。

您提供的寬度也可能小於Bitmap的寬度。

在此處查看文檔並搜索填充。 您可以嘗試按行復制所有列數據。

為什么崩潰:有時,opencv最終會讀取到位圖緩沖區之外,並且可能會碰到無法觸及的內存地址,從而導致異常。

注意:位圖可能還具有填充,從中您會收到黑色對角線。

基於答案saurabheights,我編寫了將每個位圖行填充到行中任何給定的字節多樣性的過程。

int padBitmap(const unsigned char *data, const size_t dataLength, const size_t width, const size_t height,
              const int bitDepth, const int noOfChannels, unsigned char **paddedData, size_t *paddedDataLength, const size_t row_multiple) {


    size_t row_length = (width*noOfChannels*bitDepth)/CHAR_BIT;
    size_t row_padding_size = row_multiple - row_length % row_multiple;

    if(row_padding_size == 0) return 0;

    size_t new_row_length = row_length + row_padding_size;
    size_t newDataLength = height * new_row_length;
    unsigned char *newData = malloc(sizeof(unsigned char) *newDataLength);

    unsigned char padding[3] = {0, 0, 0};
    for(int i=0; i<height; i++) {
        memcpy(newData + i*new_row_length, data + i*row_length, row_length);
        memcpy(newData + i*new_row_length + row_length, padding, row_padding_size);
    }

    *paddedData = newData;
    *paddedDataLength = newDataLength;

    return row_padding_size;
}

現在,在將位圖傳遞給resizeBitmap()之前,我要進行以下填充:

unsigned char *paddedData = 0;
    size_t paddedDataLength = 0;
    int padding = padBitmap(gData, gDataLength, width, height, PNG_BIT_DEPTH_8, GRAYSCALE_COMPONENTS_PER_PIXEL, &paddedData, &paddedDataLength, 4);
    width += padding;

我使用的是paddedData位圖。 它似乎正常工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM