我不明白为什么从视频接收到的Iplimage和从文件(从这个视频接收到)包含不同的像素值。下面的代码显示了它。
CvCapture* readerAvi = cvCreateFileCapture( "input.avi" );
// Grad first frame from input video stream
if(!cvGrabFrame(readerAvi)) {
std::cerr << "Could not grab AVI frame." << std::endl;
return 0;
}
IplImage* videoFrame = cvRetrieveFrame(readerAvi);
if( !videoFrame )
break;
// Save values of some pixels in file
std::ofstream fout("frame_pixels.txt");
for(int y = 170; y < 270; ++y) {
for(int x = 30; x < 130; ++x) {
CvScalar s = cvGet2D(videoFrame, y, x );
fout << "x=" << x << " y=" << y << " " << s.val[0] << " " << s.val[1] << " " << s.val[2] << std::endl;
}
fout << "n";
}
fout.close();
cvSaveImage("temp.jpg", videoFrame);
// Load saved image
videoFrame = cvLoadImage("temp.jpg");
fout.open("image_pixels.txt");
// Save values of some pixels in file
for(int y = 170; y < 270; ++y) {
for(int x = 30; x < 130; ++x) {
CvScalar s = cvGet2D(videoFrame, y, x );
fout << "x=" << x << " y=" << y << " " << s.val[0] << " " << s.val[1] << " " << s.val[2] << std::endl;
}
fout << "n";
}
fout.close();
那么为什么文件frame_pixel .txt和image_pixel .txt包含接近的数字,但不相同?
在没有看到数据本身的情况下,我不能肯定地说,但这很可能是由于图像所经历的压缩。如果视频来自一组图像,那么在创建视频时,这些图像中的每一个都将经历第二次压缩-例如,MPEG文件的情况下的JPEG压缩(更多细节在这里)。这将导致图像上的伪影。如果图像是取自视频的静止帧,那么在保存时,它很可能经历了压缩。
虽然视频帧和静态图像可能看起来相当,但由于图像被压缩的方式,几乎肯定会有细微的差异。
我猜有损压缩是答案,因为JPEG是一种有损文件格式。也许你可以试着用无损格式拍摄?
当您将帧保存为"temp.jpg"时,JPEG 有损压缩算法将重新编码该帧。像素值将被有损算法稍微改变。
这就是为什么当您读取文件"temp.jpg"返回时,一些的像素值与您从avi文件中的框架中获得的原始像素值不同。
OpenCv使用ffmpeg库进行视频解码,libjpeg库进行图像解码,可能实现细节导致结果不同。