C# 从视频C中提取帧#
我正在尝试制作一个应用程序,使用摄像头录制视频并处理视频图像。这是我想要的。首先,我的应用程序用Torch录制了一段10秒的视频。其次,我使用一种方法来播放视频,以查看我录制的内容 我被三件事困住了C# 从视频C中提取帧#,c#,video,image-processing,win-universal-app,C#,Video,Image Processing,Win Universal App,我正在尝试制作一个应用程序,使用摄像头录制视频并处理视频图像。这是我想要的。首先,我的应用程序用Torch录制了一段10秒的视频。其次,我使用一种方法来播放视频,以查看我录制的内容 我被三件事困住了 如何将视频转换为单个帧(图像) 是否可以在录制视频时异步转换视频 当我将视频转换为单个帧时,我如何处理它们?它们是JPEG吗?我可以简单地将它们显示为图像吗?等等 主要代码: using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Con
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace App3
{
public sealed partial class MainPage : Page
{
DispatcherTimer D;
double basetimer = 0;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
D = new DispatcherTimer();
D.Interval = new TimeSpan(0, 0, 1);
D.Tick += timer_Tick;
txt.Text = basetimer.ToString();
Play.IsEnabled = false;
}
public Library Library = new Library();
public object PreviewImage { get; private set; }
void timer_Tick(object sender, object e)
{
basetimer = basetimer - 1;
txt.Text = basetimer.ToString();
if (basetimer == 0)
{
D.Stop();
Preview.Source = null;
Library.Stop();
Record.IsEnabled = false;
Play.IsEnabled = true;
Clear.IsEnabled = true;
if (Library._tc.Enabled)
{
Library._tc.Enabled = false;
}
}
}
private void Record_Click(object sender, RoutedEventArgs e)
{
if (Library.Recording)
{
Preview.Source = null;
Library.Stop();
Record.Icon = new SymbolIcon(Symbol.Video);
}
else
{
basetimer = 11;
D.Start();
//D.Tick += timer_Tick;
Display.Source = null;
Library.Record(Preview);
Record.Icon = new SymbolIcon(Symbol.VideoChat);
Record.IsEnabled = false;
Play.IsEnabled = false;
}
}
private async void Play_Click(object sender, RoutedEventArgs e)
{
await Library.Play(Dispatcher, Display);
//Extract_Image_From_Video(Library.buffer);
}
private void Clear_Click(object sender, RoutedEventArgs e)
{
Display.Source = null;
Record.Icon = new SymbolIcon(Symbol.Video);
txt.Text = "0";
basetimer= 0;
Play.IsEnabled = false;
Record.IsEnabled =true;
if (Library.capture != null)
{
D.Stop();
Library.Recording = false;
Preview.Source = null;
Library.capture.Dispose();
Library.capture = null;
basetimer = 11;
}
}
}
}
图书馆类别:
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.Devices;
using Windows.Media.MediaProperties;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Graphics.Imaging;
using Emgu.CV.Structure;
using Emgu.CV;
using System.Collections.Generic;
public class Library
{
private const string videoFilename = "video.mp4";
private string filename;
public MediaCapture capture;
public InMemoryRandomAccessStream buffer;
public static bool Recording;
public TorchControl _tc;
public int basetimer ;
public async Task<bool> init()
{
if (buffer != null)
{
buffer.Dispose();
}
buffer = new InMemoryRandomAccessStream();
if (capture != null)
{
capture.Dispose();
}
try
{
if (capture == null)
{
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
DeviceInformation cameraDevice =
allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null &&
x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
capture = new MediaCapture();
var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
// Initialize
try
{
await capture.InitializeAsync(mediaInitSettings);
var videoDev = capture.VideoDeviceController;
_tc = videoDev.TorchControl;
Recording = false;
_tc.Enabled = false;
}
catch (UnauthorizedAccessException)
{
Debug.WriteLine("UnauthorizedAccessExeption>>");
}
catch (Exception ex)
{
Debug.WriteLine("Exception when initializing MediaCapture with {0}: {1}", cameraDevice.Id, ex.ToString());
}
}
capture.Failed += (MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs) =>
{
Recording = false;
_tc.Enabled = false;
throw new Exception(string.Format("Code: {0}. {1}", errorEventArgs.Code, errorEventArgs.Message));
};
}
catch (Exception ex)
{
if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UnauthorizedAccessException))
{
throw ex.InnerException;
}
throw;
}
return true;
}
public async void Record(CaptureElement preview)
{
await init();
preview.Source = capture;
await capture.StartPreviewAsync();
await capture.StartRecordToStreamAsync(MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), buffer);
if (Recording) throw new InvalidOperationException("cannot excute two records at the same time");
Recording = true;
_tc.Enabled = true;
}
public async void Stop()
{
await capture.StopRecordAsync();
Recording = false;
_tc.Enabled = false;
}
public async Task Play(CoreDispatcher dispatcher, MediaElement playback)
{
IRandomAccessStream video = buffer.CloneStream();
if (video == null) throw new ArgumentNullException("buffer");
StorageFolder storageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
if (!string.IsNullOrEmpty(filename))
{
StorageFile original = await storageFolder.GetFileAsync(filename);
await original.DeleteAsync();
}
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
StorageFile storageFile = await storageFolder.CreateFileAsync(videoFilename, CreationCollisionOption.GenerateUniqueName);
filename = storageFile.Name;
using (IRandomAccessStream fileStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(video.GetInputStreamAt(0), fileStream.GetOutputStreamAt(0));
await video.FlushAsync();
video.Dispose();
}
IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read);
playback.SetSource(stream, storageFile.FileType);
playback.Play();
});
}
使用系统;
使用系统诊断;
使用System.Linq;
使用System.Threading.Tasks;
使用Windows.Devices.Enumeration;
使用Windows.Media.Capture;
使用Windows.Media.Devices;
使用Windows.Media.MediaProperties;
使用Windows.Storage;
使用Windows.Storage.Streams;
使用Windows.UI.Core;
使用Windows.UI.Xaml.Controls;
使用Windows.UI.Xaml.Media.Imaging;
使用Windows.Graphics.Imaging;
使用Emgu.CV.Structure;
使用Emgu.CV;
使用System.Collections.Generic;
公共班级图书馆
{
私有常量字符串videoFilename=“video.mp4”;
私有字符串文件名;
公共媒体捕获;
公共内存随机访问流缓冲区;
公共静态bool记录;
公共火炬控制中心;
公共整数基定时器;
公共异步任务init()
{
if(缓冲区!=null)
{
buffer.Dispose();
}
缓冲区=新的InMemoryRandomAccessStream();
如果(捕获!=null)
{
capture.Dispose();
}
尝试
{
如果(捕获==null)
{
var allVideoDevices=等待设备信息.findalsync(DeviceClass.VideoCapture);
设备信息摄像设备=
allVideoDevices.FirstOrDefault(x=>x.EnclosureLocation!=null&&
x、 EnclosureLocation.Panel==Windows.Devices.Enumeration.Panel.Back);
capture=新媒体捕获();
var medialinitsettings=new mediacaptureininitializationsettings{VideoDeviceId=cameraDevice.Id};
//初始化
尝试
{
等待捕获。初始化同步(mediaInitSettings);
var videoDev=capture.VideoDeviceController;
_tc=视频开发火炬控制;
记录=假;
_tc.Enabled=false;
}
捕获(未经授权的访问例外)
{
Debug.WriteLine(“unauthorizedAccessException>>”;
}
捕获(例外情况除外)
{
WriteLine(“使用{0}:{1}初始化MediaCapture时出现异常”,cameraDevice.Id,ex.ToString());
}
}
capture.Failed+=(MediaCapture发送方、MediaCaptureFailedEventArgs errorEventArgs)=>
{
记录=假;
_tc.Enabled=false;
抛出新异常(string.Format(“代码:{0}.{1}”,errorEventArgs.Code,errorEventArgs.Message));
};
}
捕获(例外情况除外)
{
if(ex.InnerException!=null&&ex.InnerException.GetType()==typeof(UnauthorizedAccessException))
{
抛出ex.InnerException;
}
投掷;
}
返回true;
}
公共异步无效记录(CaptureElement预览)
{
等待初始化();
preview.Source=捕获;
等待捕获。StartPreviewSync();
等待捕获。StartRecordToStreamAsync(MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto),缓冲区);
如果(记录)抛出新的InvalidOperationException(“无法同时执行两条记录”);
记录=真;
_tc.Enabled=true;
}
公共异步无效停止()
{
等待捕获。StopRecordAsync();
记录=假;
_tc.Enabled=false;
}
公共异步任务播放(CoreDispatcher、MediaElement播放)
{
irandomaccesstream video=buffer.CloneStream();
如果(video==null)抛出新的ArgumentNullException(“缓冲区”);
StorageFolder StorageFolder=Windows.ApplicationModel.Package.Current.InstalledLocation;
如果(!string.IsNullOrEmpty(文件名))
{
StorageFile original=等待storageFolder.GetFileAsync(文件名);
等待original.DeleteAsync();
}
等待dispatcher.RunAsync(CoreDispatcherPriority.Normal,async()=>
{
StorageFile StorageFile=Wait storageFolder.CreateFileAsync(videoFilename,CreationCollisionOption.GenerateUniqueName);
filename=storageFile.Name;
使用(irandomaccesstream fileStream=await-storageFile.OpenAsync(FileAccessMode.ReadWrite))
{
等待RandomAccessStream.CopyAndCloseAsync(video.GetInputStreamAt(0),fileStream.GetOutputStreamAt(0));
等待video.FlushAsync();
video.Dispose();
}
irandomaccesstream=wait-storageFile.OpenAsync(FileAccessMode.Read);
playback.SetSource(stream,storageFile.FileType);
playback.Play();
});
}
我昨天才想到这一点
下面是一个完整且易于理解的示例,其中包括拾取视频文件并在视频的第1秒保存快照
您可以选择适合您的项目的部分,并更改其中的一些部分(即从相机获取视频分辨率)
1)和3)
如果要提取更多帧,还可以使用composition.GetThumbnailsAsync
2)当计时器滴答作响时,使用mediaCapture使用并安装
使用(var vfreeader=new VideoFileReader())
{
vfreeader.Open(“video.mp4”);
对于(int i=0;i
在与Accord发生大量问题后,我最终用它解决了一个类似的问题
我需要为视频的每一秒保存一幅图像:
using (var engine = new Engine())
{
var mp4 = new MediaFile { Filename = mp4FilePath };
engine.GetMetadata(mp4);
var i = 0;
while (i < mp4.Metadata.Duration.Seconds)
{
var options = new ConversionOptions { Seek = TimeSpan.FromSeconds(i) };
var outputFile = new MediaFile { Filename = string.Format("{0}\\image-{1}.jpeg", outputPath, i) };
engine.GetThumbnail(mp4, outputFile, options);
i++;
}
}
使用(var引擎=新的E
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(imageStream);
XAMLImage.Source = bitmapImage;
using (var vFReader = new VideoFileReader())
{
vFReader.Open("video.mp4");
for (int i = 0; i < vFReader.FrameCount; i++)
{
Bitmap bmpBaseOriginal = vFReader.ReadVideoFrame();
}
vFReader.Close();
}
using (var engine = new Engine())
{
var mp4 = new MediaFile { Filename = mp4FilePath };
engine.GetMetadata(mp4);
var i = 0;
while (i < mp4.Metadata.Duration.Seconds)
{
var options = new ConversionOptions { Seek = TimeSpan.FromSeconds(i) };
var outputFile = new MediaFile { Filename = string.Format("{0}\\image-{1}.jpeg", outputPath, i) };
engine.GetThumbnail(mp4, outputFile, options);
i++;
}
}
// _env is the injected IWebHostEnvironment
// _tempPath is temporary file storage
var ffmpegPath = Path.Combine(_env.ContentRootPath, "<path-to-ffmpeg.exe>");
var mediaToolkitService = MediaToolkitService.CreateInstance(ffmpegPath);
var metadataTask = new FfTaskGetMetadata(_tempFile);
var metadata = await mediaToolkitService.ExecuteAsync(metadataTask);
var i = 0;
while (i < metadata.Metadata.Streams.First().DurationTs)
{
var outputFile = string.Format("{0}\\image-{1:0000}.jpeg", _imageDir, i);
var thumbTask = new FfTaskSaveThumbnail(_tempFile, outputFile, TimeSpan.FromSeconds(i));
_ = await mediaToolkitService.ExecuteAsync(thumbTask);
i++;
}