0

我正在尝试使用 emguCV 中的 VideoWriter 和 Capture 将捕获的视频写入文件,问题是:如果我播放刚刚录制的视频,它会播放得快或慢。我该如何解决这个问题,所以我录制的视频将被实时播放/录制,所以不要慢或快?

这是我的代码:


    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);
        }
    }

4

2 回答 2

3

尝试降低 FPS 值。在

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

而不是 30 帧/秒,而是提供较低的值。

于 2012-11-10T09:45:16.833 回答
0

代码没有意义。挂钩Application.Idle不是一个好主意。

将代码扔到垃圾中,有 1 个记录线程capture.QueryFrame()并立即保存。
地狱甚至不要打扰线程使用计时器,根据 FPS 设置它。它不会准确,但比你现在拥有的要好。

于 2012-11-10T10:09:50.227 回答