Domanda

So I'm trying to use the webp API to encode images. Right now I'm going to be using openCV to open and manipulate the images, then I want to save them off as webp. Here's the source I'm using:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include <webp/encode.h>

int main(int argc, char *argv[])
{

    IplImage* img = 0;
    int height,width,step,channels;
    uchar *data;
    int i,j,k;
    if (argc<2) {
        printf("Usage:main <image-file-name>\n\7");
    exit(0);
    }
    // load an image
    img=cvLoadImage(argv[1]);

    if(!img){
        printf("could not load image file: %s\n",argv[1]);
        exit(0);
    }

    // get the image data
    height      = img->height;
    width       = img->width;
    step        = img->widthStep;
    channels    = img->nChannels;
    data        = (uchar *)img->imageData;
    printf("processing a %dx%d image with %d channels \n", width, height, channels);

    // create a window
    cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("mainWin",100,100);

    // invert the image
    for (i=0;i<height;i++) {
        for (j=0;j<width;j++) {
            for (k=0;k<channels;k++) {
                data[i*step+j*channels+k] = 255-data[i*step+j*channels+k];
            }
        }
    }

    // show the image
    cvShowImage("mainWin", img);

    // wait for a key
    cvWaitKey(0);
    // release the image
    cvReleaseImage(&img);

    float qualityFactor = .9;
    uint8_t** output;
    FILE *opFile;
    size_t datasize;
    printf("encoding image\n");
    datasize = WebPEncodeRGB((uint8_t*)data,width,height,step,qualityFactor,output);

    printf("writing file out\n");
    opFile=fopen("output.webp","w");
    fwrite(output,1,(int)datasize,opFile);
}

When I execute this, I get this:

nato@ubuntu:~/webp/webp_test$ ./helloWorld ~/Pictures/mars_sunrise.jpg 
processing a 2486x1914 image with 3 channels 
encoding image
Segmentation fault

It displays the image just fine, but segfaults on the encoding. My initial guess was that it's because I'm releasing the img before I try to write out the data, but it doesn't seem to matter whether I release it before or after I try the encoding. Is there something else I'm missing that might cause this problem? Do I have to make a copy of the image data or something?

The WebP api docs are... sparse. Here's what the README says about WebPEncodeRGB:

The main encoding functions are available in the header src/webp/encode.h
The ready-to-use ones are:

size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, 
    int stride, float quality_factor, uint8_t** output);

The docs specifically do not say what the 'stride' is, but I'm assuming that it's the same as the 'step' from opencv. Is that reasonable?

Thanks in advance!

È stato utile?

Soluzione 3

so it looks like the problem was here:

// load an image
img=cvLoadImage(argv[1]);

The function cvLoadImage takes an extra parameter

cvLoadImage(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR)

and when I changed to

img=cvLoadImage(argv[1],1);

the segfault went away.

Altri suggerimenti

First, don't release the image if you use it later. Second, your output argument is pointing to non-initialized address. This is how to use initialized memory for the output address:

uint8_t* output;
datasize = WebPEncodeRGB((uint8_t*)data, width, height, step, qualityFactor, &output);

You release the image with cvReleaseImage before you try to use the pointer to the image data for the encoding. Probably that release function frees the image buffer and your data pointer now doesn't point to valid memory anymore.

This might be the reason for your segfault.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top