快速的开发

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 1070|回复: 0

使用AForge.NET来拍照和录像

[复制链接]

26

主题

26

帖子

82

积分

版主

Rank: 7Rank: 7Rank: 7

积分
82

热心会员

发表于 2017-3-16 20:32:49 | 显示全部楼层 |阅读模式
AForge.NET的基本信息
AForge.NET是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等领域。
它的官方地址为:http://www.aforgenet.com/aforge/framework/
速度慢的时候访问:https://github.com/andrewkirillov/AForge.NET/
不过更新时间是2013年了。
如何获取所有的摄像头设备

//枚举所有视频输入设备
FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

如何获取摄像头的分辨率

VideoCaptureDevice videoSource = new VideoCaptureDevice(filterInfoDescriptor.MonikerString);
foreach (VideoCapabilities videoCap in videoSource.VideoCapabilities)
{
    string text = string.Format("{0} X {1}", videoCap.FrameSize.Width, videoCap.FrameSize.Height);
}

如何连接设备

        public void Connect(int deviceIndex = 0, int resolutionIndex = 0)
        {
            DisConnect();
            GetAllDevices();
            if (allFilterInfoDescriptors.Count <= deviceIndex) { throw new System.Exception("当前没有指定的视频设备"); } currentDeviceName = allFilterInfoDescriptors[deviceIndex].Name; currentDeviceMoniker = allFilterInfoDescriptors[deviceIndex].MonikerString; currentVideoCaptureDevice = new VideoCaptureDevice(allFilterInfoDescriptors[deviceIndex].MonikerString); if ((currentVideoCaptureDevice.VideoCapabilities == null) || (currentVideoCaptureDevice.VideoCapabilities.Length == 0)) { throw new System.Exception("指定的设备没有合适的分辨率"); } if (resolutionIndex >= currentVideoCaptureDevice.VideoCapabilities.Length)
            {
                resolutionIndex = currentVideoCaptureDevice.VideoCapabilities.Length - 1;
            }

            currentVideoCaptureDevice.VideoResolution = currentVideoCaptureDevice.VideoCapabilities[resolutionIndex];
            /// 使用异步视频源,以便于进行图片等操作
            asyncSource = new AsyncVideoSource(currentVideoCaptureDevice);
            asyncSource.NewFrame -= asyncSource_NewFrame;
            asyncSource.NewFrame += asyncSource_NewFrame;
            allFrameRecived = 0;
            cameraStartDatetime = DateTime.Now;
            lastFrameDatetime = DateTime.Now;

            asyncSource.Start();
            fpsTimer.Elapsed -= fpsTimer_Elapsed;
            fpsTimer.Elapsed += fpsTimer_Elapsed;
            fpsTimer.Start();


            serialographTimer.Elapsed -= serialographTimer_Elapsed;
            serialographTimer.Elapsed += serialographTimer_Elapsed;
            /// serialographTimer.Start();
        }

如何采集照片
如何录制视频

            if (isSaveVideo)
            {
                isSaveVideo = false;
                if (currentVideoWriter != null)
                {
                    currentVideoWriter.Close();
                    currentVideoWriter.Dispose();
                    currentVideoWriter = null;
                }
            }
            if (isCameraVideo && !isCameraVideoSuspend)
            {
                Bitmap image = eventArgs.Frame;
                //Bitmap image = videoSourcePlayer.GetCurrentVideoFrame();
                if (image == null)
                {
                    return;
                }

                if (isDrawDateTime)
                {
                    Graphics g = Graphics.FromImage(image);
                    SolidBrush drawBrush = new SolidBrush(Color.Red);
                    Font drawFont = new Font("Arial", 6, FontStyle.Bold, GraphicsUnit.Millimeter);
                    int xPos = image.Width - (image.Width - 15);
                    int yPos = 15;
                    string drawDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    g.DrawString(drawDate, drawFont, drawBrush, xPos, yPos);
                    g.Dispose();
                }

                if (currentVideoWriter == null)
                {


                    string fileDir = string.Format("{0}{1}Videos{1}{2}",
                  Path.GetDirectoryName(Application.ExecutablePath),
                  Path.AltDirectorySeparatorChar, DateTime.Now.ToString("yyyyMMdd"));
                    if (!Directory.Exists(fileDir))
                    {
                        Directory.CreateDirectory(fileDir);
                    }
                    string videoFileFullPath = string.Format("{0}{1}{2}.avi", fileDir, Path.AltDirectorySeparatorChar, DateTime.Now.Ticks);
                    currentVideoWriter = new VideoFileWriter();
                    currentVideoWriter.Open(videoFileFullPath, image.Width, image.Height,
                        currentVideoFps, VideoCodec.MPEG4
                        , currentVideoBitRate);
                    currentVideoWriter.WriteVideoFrame(image);
                }
                else
                {
                    currentVideoWriter.WriteVideoFrame(image);
                }
            }

如何解决图片质量问题,

        public void SaveBitMapToFile(Bitmap bitmap, string resultFileName,
            ImageFormat imageFormat, long quality = 90)
        {
            ImageCodecInfo jpgEncoder = GetEncoder(imageFormat);
            /// 设置图片质量参数
            System.Drawing.Imaging.Encoder qualityEncoder = System.Drawing.Imaging.Encoder.Quality;
            EncoderParameters encoderParameters = new EncoderParameters(1);
            EncoderParameter myEncoderParameter = new EncoderParameter(qualityEncoder, quality);
            encoderParameters.Param[0] = myEncoderParameter;
            bitmap.Save(resultFileName, jpgEncoder, encoderParameters);
        }
        private ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }

如何解决视频帧的问题,
创建视频的文件的时候,会设置帧率,
但是实际通过NewFrame得到的帧率会不一致,如果差别比较大,播放的时候就会出现问题,
这个问题有2中办法来解决,一种是保存好总的录制时间,根据总帧数重新生成一个新的视频文件,
或者是使用定时器,定时读取照片,这样也可以保证播放不会出问题(那可能就会出现丢帧和重帧的问题)。
根据照片,生成avi文件

        public void ExportImages(string aviFile = "", string resultPath = "")
        {
            if (string.IsNullOrEmpty(aviFile))
            {
                OpenFileDialog ofd = new OpenFileDialog();
                if (ofd.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
                aviFile = ofd.FileName;
            }
            VideoFileReader videoFileReader = new VideoFileReader();
            videoFileReader.Open(aviFile);

            long totalCount = videoFileReader.FrameCount;
            string tmpStr = videoFileReader.FrameRate.ToString();
            string aviFileName = Path.GetFileNameWithoutExtension(aviFile);
            if (string.IsNullOrEmpty(resultPath))
            {
                resultPath = string.Format("{0}{1}Images{1}{2}",
                      Path.GetDirectoryName(Application.ExecutablePath),
                      Path.DirectorySeparatorChar, aviFileName);
            }
            else
            {
                resultPath = string.Format("{0}{1}{2}{1}", resultPath.TrimEnd(Path.DirectorySeparatorChar),
                    Path.DirectorySeparatorChar, aviFileName);
            }
            resultPath = Path.GetFullPath(resultPath);
            if (!Directory.Exists(resultPath))
            {
                Directory.CreateDirectory(resultPath);
            }

            for (int i = 0; i < totalCount; i++)
            {
                Bitmap image = videoFileReader.ReadVideoFrame();
                if (image != null)
                {
                    string picFileName = string.Format("{0}{1}{2}.jpg", resultPath, Path.DirectorySeparatorChar, i);
                    image.Save(picFileName, ImageFormat.Jpeg);
                }
                image.Dispose();
            }
            videoFileReader.Close();
            videoFileReader.Dispose();
            ShowExplorer(resultPath);
        }

如何获得当前的帧率
由于VideoCaptureDevice的FramesReceived只要一读取,就自动归零,
所以最好使用计时器,定时读取FramesReceived属性,来获取帧率。注意事项,在拍摄或者拍照过程中,
最好不要进行多余的操作,比如查看视频,查看照片,
否则会由于cpu的处理性能不足,影响视频的实际帧率。
遇到的问题:
AForge.NET获取usb摄像头的图像,
在台式机上可以达到 30fps,
但是同样的分辨率在笔记本上只能达到10多帧,
但是如果用操作系统本身的 照相程序,在笔记本上可以30fps,

回复

使用道具 举报

QQ|Archiver|手机版|小黑屋|业务快速构建平台 ( 鄂ICP备15010001号

鄂公网安备 42011502000533号

GMT+8, 2019-8-20 11:30 , Processed in 0.096387 second(s), 33 queries .

Powered by Discuz! X3.3

© 2016-2036 Comsenz Inc.

快速回复 返回顶部 返回列表