将cvImageCreate()与灰度图像一起使用的OpenCV失败,并且调整大小通常会失败 [英] OpenCV using cvImageCreate() with grayscale image fails, and resizing usually fails

查看:526
本文介绍了将cvImageCreate()与灰度图像一起使用的OpenCV失败,并且调整大小通常会失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码,它从缓冲区1byte,8bits位图加载灰度图像.然后,它将调整此图像的大小.

I have such code that is loading grayscale image from buffer 1byte, 8bits bitmap. Then it resizes this image.

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. 加载的图像为:

I am using here bitDepth = 8 and noOfChannels = 1. Loaded image is:

,输出为:

此输出并不总是写的,因为程序通常会因错误而失败:

this output is not always written as program usually fails with error:

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!也许这是这张图片的问题,但是为什么呢?

I am attaching debugger output as there is interesting situation as I am passing grayscale buffer of size 528480 which equals 1 byte * 1101 *480, but after cvCreateImage there is inside imageSize 529920 and widthStep is 1104! Maybe here is the problem with this image, but why it is ?

推荐答案

此问题与IplImage的widthstep和width有关. Opencv将图像填充为4个字节的倍数的widthstep.这里的opencv使用的宽度是1101,宽度步进是1104.但是,当数据从位图写入IplImage时,每行写入的像素很少(请注意从左上角到右下角的对角线).

This issue is related to widthstep and width of IplImage. Opencv pads the image to have a widthstep of multiple of 4 bytes. Here opencv is using width of 1101 and widthstep of 1104. But data when written from bitmap to IplImage, few extra pixels get written per row(note the diagonal line from top-left to bottom-right).

请注意,图像没有倾斜.只是每隔一行向左移一点(3个像素),从而产生剪切变换的想法.

Note, that the image is not tilted. It's just that every next row is shifted a little to left(by 3 pixels), thus giving the idea of shearing transformation.

也有可能您提供的宽度小于位图的宽度.

It could also be possible that you are giving a smaller width than what Bitmap holds.

在此处和文档中查看搜索填充.您可以尝试按行复制所有列数据.

See docs here and search for padding. You can try copying all column data row-wise.

为什么崩溃:有时,opencv最终会读取到位图缓冲区之外,并且可能会碰到无法触及的内存地址,从而导致异常.

Why crash: Sometimes opencv will end up reading beyond Bitmap buffer and may hit untouchable memory addresses, causing exception.

注意:位图可能还带有填充,从中您会收到黑色的对角线.

Note: Bitmap probably also has padding from which you received the black diagonal line.

这篇关于将cvImageCreate()与灰度图像一起使用的OpenCV失败,并且调整大小通常会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆