我无法理解为什么从视频和文件(从此视频接收)收到的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_pixels.txt和image_pixels.txt包含接近数字但不相同?
答案 0 :(得分:4)
如果没有看到数据本身,我无法肯定地说,但很可能是图像所经历的压缩。如果视频来自一组图像,那么当创建视频时,这些图像中的每一个都将经历第二次压缩 - 例如,对于MPEG文件,JPEG compression(更多细节here)。这将导致图像上出现伪影。如果图像是从视频中拍摄的静止帧,则在保存时,它可能已经过压缩。
虽然视频帧和静止图像可能看起来可以通过眼睛进行比较,但由于图像被压缩的方式,几乎肯定会有轻微差异。
答案 1 :(得分:1)
我认为lossy compression是答案,因为JPEG是一种有损文件格式。也许您可以尝试以无损格式捕获?
答案 2 :(得分:0)
将帧保存到“temp.jpg”时,JPEG 有损压缩算法会重新编码帧。 有损算法会略微改变像素值。
这就是为什么当您读取文件“temp.jpg”时,像素值的某些与您从avi文件中的帧中获取的原始像素值不同。
答案 3 :(得分:0)
OpenCv使用ffmpeg库进行视频解码,使用libjpeg进行图像解码, 可能的实现细节有助于使结果不同。