2012-09-15 8 views
0

VideoWriter를 사용하여 캡처 한 비디오를 파일에 쓰려고하는데, emguCV에서 캡처하면 문제가 생깁니다. 방금 녹화 한 비디오가 재생되면 빠르거나 느리게. 어떻게하면 문제를 해결할 수 있습니까? 녹화 한 비디오가 실시간으로 재생/녹화되므로 느려지거나 빨리 움직이지 않습니까?C# emgu cv : 녹화 된 비디오가 빠른/느리게 재생됩니다.


Capture capture = new Capture(); 
    VideoWriter vw; 
    Size ms_hd_cam_5000_resolution = new Size(1280, 720); 
    Label width_label, height_label, recordingTime; 
    Button record; 
    Thread isRecording; 
    Image<Bgr, byte> imageFrame; 

    int seconds; 
    int minutes; 

    public Form1() 
    { 
     InitializeComponent(); 
     InitializeConrols(); 

     //Cam_Properties 
     capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 1280); 
     capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 720); 
     capture.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS, 30); 

     //VideoWriting_Properties 
     vw = new VideoWriter("test.avi", 30, ms_hd_cam_5000_resolution.Width, ms_hd_cam_5000_resolution.Height, true); 


    } 

    private void InitializeConrols() 
    { 
     this.BackColor = Color.Black; 
     this.ClientSize = new Size(ms_hd_cam_5000_resolution.Width + 25, ms_hd_cam_5000_resolution.Height + 75); 
     this.Picture_box.Size = ms_hd_cam_5000_resolution; 

     width_label = new Label(); 
     width_label.Location = new Point(10, ms_hd_cam_5000_resolution.Height + 15); 
     width_label.ForeColor = Color.White; 
     width_label.Text = "width: " + capture.Width.ToString(); 

     height_label = new Label(); 
     height_label.Location = new Point(10, ms_hd_cam_5000_resolution.Height + 40); 
     height_label.ForeColor = Color.White; 
     height_label.Text = "height: " + capture.Height.ToString(); 

     recordingTime = new Label(); 
     recordingTime.Location = new Point(225, ms_hd_cam_5000_resolution.Height + 40); 
     recordingTime.ForeColor = Color.White; 
     recordingTime.Text = "time: 0"; 

     record = new Button(); 
     record.Location = new Point(225, ms_hd_cam_5000_resolution.Height + 15); 
     record.ForeColor = Color.White; 
     record.Text = "record"; 

     Controls.Add(width_label); 
     Controls.Add(height_label); 
     Controls.Add(record); 
     Controls.Add(recordingTime); 

     record.Click += Record_Click; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     captureCamImage(sender, e); 
     Application.Idle += captureCamImage; 
    } 

    private void Record_Click(object sender, EventArgs e) 
    { 
     if (isRecording == null) 
     { 
      recordingTime.Text = "Time: 0"; 
      record.Text = "stop"; 
      isRecording = new Thread(this.Record); 
      isRecording.Start(); 
     } 
     else 
     { 
      record.Text = "record"; 
      isRecording = null; 
     } 
    } 

    private void captureCamImage(object sender, EventArgs e) 
    { 
     imageFrame = capture.QueryFrame(); 
     Picture_box.Image = imageFrame.ToBitmap(); 
     recordTime(); 
    } 

    private void recordTime() 
    { 
     recordingTime.Text = "Time: " + minutes.ToString() + " : " + seconds.ToString(); 
    } 

    private void Record() 
    { 
     Stopwatch stopWatch = new Stopwatch(); 
     stopWatch.Reset(); 
     stopWatch.Start(); 
     while (isRecording != null) 
     { 
      seconds = stopWatch.Elapsed.Seconds; 
      minutes = stopWatch.Elapsed.Minutes; 

      vw.WriteFrame(imageFrame); 
      Thread.Sleep(1000/30); 
     } 
    } 

답변

3

30 프레임/초는 낮은 값을 제공하는 대신 FPS value.In

vw = new VideoWriter("test.avi", 30, ms_hd_cam_5000_resolution.Width, ms_hd_cam_5000_resolution.Height, true); 

을 줄여보십시오 :

이 내 코드입니다.

0

코드가 의미가 없습니다. Application.Idle으로 연결하는 것은 좋은 생각이 아닙니다.

코드를 쓰레기에 버리고 기록 스레드가 capture.QueryFrame() 인 즉시 저장하십시오.
지옥은 타이머를 사용하는 스레드에 신경 쓰지 않고 FPS에 따라 설정합니다. 당신이 지금 가지고있는 것보다 정확하지만 더 낫지는 않을 것입니다.

관련 문제