所以我正在尝试使用webp API来编码图像。现在我将使用openCV来打开和操作图像,然后我想将它们保存为webp。这是我正在使用的来源:
#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);
}
当我执行此操作时,我得到了这个:
nato@ubuntu:~/webp/webp_test$ ./helloWorld ~/Pictures/mars_sunrise.jpg
processing a 2486x1914 image with 3 channels
encoding image
Segmentation fault
它显示的图像很好,但在编码上有段错误。我最初的猜测是因为我在尝试写出数据之前发布了img,但是在尝试编码之前或之后我是否发布它并不重要。还有其他我想念的东西会导致这个问题吗?我是否必须制作图像数据的副本?
WebP api文档很稀疏。以下是README关于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);
文档特别没有说'stride'是什么,但我假设它与opencv中的'step'相同。这合理吗?
提前致谢!
答案 0 :(得分:5)
首先,如果稍后再使用,请勿释放图像。其次,输出参数指向非初始化地址。这是如何使用初始化内存作为输出地址:
uint8_t* output;
datasize = WebPEncodeRGB((uint8_t*)data, width, height, step, qualityFactor, &output);
答案 1 :(得分:1)
在尝试使用指向图像数据的指针进行编码之前,使用cvReleaseImage
释放图像。可能释放函数释放图像缓冲区,而你的data
指针现在不再指向有效内存。
此可能是您的段错误的原因。
答案 2 :(得分:0)
所以问题出现在这里:
// load an image
img=cvLoadImage(argv[1]);
函数cvLoadImage需要一个额外的参数
cvLoadImage(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR)
当我改为
时img=cvLoadImage(argv[1],1);
段错误消失了。