从视频C#中提取帧
发布时间:2020-12-15 23:47:40 所属栏目:百科 来源:网络整理
导读:我正在尝试制作一款使用相机录制视频并处理视频图像的应用.这就是我想要的.首先,我的应用程序使用Torch录制了10秒的视频.其次,我使用一种方法来播放视频以查看我录制的内容. 我坚持三件事. 如何将视频转换为单独的帧(图像)? 是否可以在录制视频时异步转换视
我正在尝试制作一款使用相机录制视频并处理视频图像的应用.这就是我想要的.首先,我的应用程序使用Torch录制了10秒的视频.其次,我使用一种方法来播放视频以查看我录制的内容.
我坚持三件事. >如何将视频转换为单独的帧(图像)? 主要代码: 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,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(); }); } 解决方法
我昨天才知道这件事.
这是一个完整且易于理解的示例,它选择视频文件并在第一秒视频中保存快照. 您可以拍摄适合您项目的部分并更改其中一些部分(即从相机获取视频分辨率) 1)和3) TimeSpan timeOfFrame = new TimeSpan(0,1); //pick mp4 file var picker = new Windows.Storage.Pickers.FileOpenPicker(); picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary; picker.FileTypeFilter.Add(".mp4"); StorageFile pickedFile = await picker.PickSingleFileAsync(); if (pickedFile == null) { return; } /// //Get video resolution List<string> encodingPropertiesToRetrieve = new List<string>(); encodingPropertiesToRetrieve.Add("System.Video.FrameHeight"); encodingPropertiesToRetrieve.Add("System.Video.FrameWidth"); IDictionary<string,object> encodingProperties = await pickedFile.Properties.RetrievePropertiesAsync(encodingPropertiesToRetrieve); uint frameHeight = (uint)encodingProperties["System.Video.FrameHeight"]; uint frameWidth = (uint)encodingProperties["System.Video.FrameWidth"]; /// //Use Windows.Media.Editing to get ImageStream var clip = await MediaClip.CreateFromFileAsync(pickedFile); var composition = new MediaComposition(); composition.Clips.Add(clip); var imageStream = await composition.GetThumbnailAsync(timeOfFrame,(int)frameWidth,(int)frameHeight,VideoFramePrecision.NearestFrame); /// //generate bitmap var writableBitmap = new WriteableBitmap((int)frameWidth,(int)frameHeight); writableBitmap.SetSource(imageStream); //generate some random name for file in PicturesLibrary var saveAsTarget = await KnownFolders.PicturesLibrary.CreateFileAsync("IMG" + Guid.NewGuid().ToString().Substring(0,4) + ".jpg"); //get stream from bitmap Stream stream = writableBitmap.PixelBuffer.AsStream(); byte[] pixels = new byte[(uint)stream.Length]; await stream.ReadAsync(pixels,pixels.Length); using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite)) { var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId,writeStream); encoder.SetPixelData( BitmapPixelFormat.Bgra8,BitmapAlphaMode.Premultiplied,(uint)writableBitmap.PixelWidth,(uint)writableBitmap.PixelHeight,96,pixels); await encoder.FlushAsync(); using (var outputStream = writeStream.GetOutputStreamAt(0)) { await outputStream.FlushAsync(); } } 如果要在xaml Image中显示帧,则应使用imageStream BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(imageStream); XAMLImage.Source = bitmapImage; 如果你想提取更多的帧,还有composition.GetThumbnailsAsync 2)当你的计时器滴答作响时,使用你的mediaCapture (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |