我面临以下问题。由于我想从相机录制和播放RAW图像数据,我目前正在使用
录制图像VideoWriter outputVideo1("camera1.avi", CV_FOURCC('Y','8','0','0'), frameRate, frameSize, false);
这很好用,我可以使用VLC播放器播放视频文件,例如 MediaInfo还确认,格式为GrayScale,编解码器ID为Y800。
不幸的是,当我尝试使用
在OpenCV中打开此文件时VideoCapture cap1("camera1.avi");
Mat frame1;
for(;;)
{
cap1 >> frame1;
}
程序在for循环内崩溃,异常
cam_interface.exe中0x715f39c2处的未处理异常:0xC0000005:访问冲突读取位置0x010a0040。
当我使用霍夫曼无损编解码器('H','F','Y','U')时,我可以打开AVI文件。但由于我的数据只包含一个频道,我只想保存一个频道。使用霍夫曼编解码器作为单色图像,存储了所有三个通道的相同值,这不是我想要做的。
如果您对如何解决此问题有任何帮助或想法。
非常感谢!
答案 0 :(得分:0)
我在http://answers.opencv.org找到了一个解决方法,其中用户皮埃尔遇到了同样的问题,并自己创建了解决方法。我将重新发布此处找到的原始答案: http://answers.opencv.org/question/2133/videocapture-not-working-with-uncompressed-files/
皮尔回答:问题没有解决但我找到了一个程序来分别阅读图像来解决这个问题。首先,有必要打开序列以获取有关视频文件的FOURCC代码和信息,图像大小,图像数量......然后,如果FOURCC对应于非压缩AVI,则关闭序列并通过经典重新打开C函数fopen并跳转标题,然后使用fread函数获取每个图像。请参阅以下代码:
void CMFC_OpencvDlg::OnBnClickedLitSeqAvi()
{
static CString Filter=_T("Video files (*.avi; *.mpg) |*.avi;*.mpg|All Files (*.*)|*.*||");
CFileDialog Load(TRUE, _T("*.bitmap"), NULL, OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,Filter,NULL);
Load.m_ofn.lpstrTitle= _T("Lecture video");
int value = 0 ;
double Height, Width, Nb_images, Code ;
FILE *Seq_Avi ;
Mat Img ;
if (Load.DoModal() == IDOK)
{
img_path = Load.GetPathName() ;
Nom_de_Sequence = Load.GetPathName() ;
Nom_de_Sequence.Truncate(Nom_de_Sequence.GetLength()-4) ;
VideoCapture Sequence(img_path);
Nb_images = Sequence.get(CV_CAP_PROP_FRAME_COUNT ) ;
Width = Sequence.get(CV_CAP_PROP_FRAME_WIDTH ) ;
Height = Sequence.get(CV_CAP_PROP_FRAME_HEIGHT ) ;
Code = Sequence.get(CV_CAP_PROP_FOURCC ) ;
Nb_Images_Seq = 0 ;
if (Code == CV_FOURCC('Y','8','0','0')|| (Code == 0 ))
{
Sequence.release() ; // Fermeture du fichier
char *tmp, c ;
string Tag = "movi00d" ;
int i =0 ;
fpos_t pos;
BOOLEAN Fin = TRUE ;
tmp = (char *)malloc(Width*Height) ;
fopen_s(&Seq_Avi,img_path.c_str(),"rb") ;
do // Gestion de la taille d'entête variable
{
fread(&c,1,1,Seq_Avi) ;
if (c==Tag[i])
{
i++ ;
if (i==7) Fin = FALSE ;
if (i==4) fgetpos(Seq_Avi,&pos) ;
}
else i = 0 ;
}
while (Fin) ;
fsetpos( Seq_Avi, &pos ) ;
for (i= 0 ; i < Nb_images ;i++)
{
fread(tmp,1,8,Seq_Avi) ; // Saut du séparateur, "00dc"+taille image
fread(tmp,1,Width*Height,Seq_Avi) ;
Img = Mat(Height, Width, CV_8U, tmp) ;
Seq_image[Nb_Images_Seq] = Img.clone() ;
if (Code == 0 ) flip(Seq_image[Nb_Images_Seq],Seq_image[Nb_Images_Seq],0 ) ; // Lorsque le code est 0 les images sont stokées bas en haut
imshow("image", Seq_image[Nb_Images_Seq++]);
// AfxMessageBox(_T("Image suivante"),0,0) ;
}
fclose(Seq_Avi) ;
free(tmp) ;
}
else
{
// Cette partie ne marche pas avec les AVI non compressés !!!!!
while( Sequence.read(src)) //Relecture de out le fichier et traitement associé
{
Seq_image[Nb_Images_Seq++] = src ;
imshow("image", src);
// AfxMessageBox(_T("Image suivante"),0,0) ;
}
}
}
}