Unity控制佳能单反拍照及数据获取 您所在的位置:网站首页 佳能单反相机开关键 Unity控制佳能单反拍照及数据获取

Unity控制佳能单反拍照及数据获取

2024-07-03 12:19| 来源: 网络整理| 查看: 265

市面比较常用佳能单反,其他单反是否也提供SDK没有搜过。

佳能单反一般选用EOS500D,550D,600D,650D,750D这些都是被EDSDK所支持的。

截止2019年年初,佳能官方EDSDK需要在官网申请,不对中国提供。

我是使用的EDSDK的版本是3.5/3.6.1

单反侧面翻盖打开后,一般会看到两个接口,一个是micro usb,一个是mini hdmi。前者是本文章主要介绍的方式所使用的,即通过micro usb 转 usb线连接单反与主机

单反开机,把拨盘拨到M挡

如果觉得原配的usb线太短,可以加一根usb延长线,根据距离考虑是否要自带放大器的

EDSDK的dll和c#脚本导入之后如下

我们主要需要关注的是SDKHander.cs。它定义了变量、事件、连接设备方法和摄像机命令。

STAThread是一个线程管理脚本。

1 初始化 using System.Collections; using System.Collections.Generic; using UnityEngine; using EDSDKLib; using UnityEngine.UI; using EDSDK.NET; public class Main : MonoBehaviour { SDKHandler CameraHandler; EDSDK.NET.Camera myCamera; #region UI变量 public RawImage moviePlane; private Texture2D tt; #endregion #region 设备可用变量 private string avValues = ""; private string tvValues = ""; private string isoValues = ""; #endregion // Use this for initialization void Start () { //实例化单反操控类 CameraHandler = new SDKHandler(); print("EDSDK 初始化成功"); //找到设备 } } 2 找到设备 //找到设备 List ll = CameraHandler.GetCameraList(); foreach (EDSDK.NET.Camera cc in ll) print(cc.Info.szDeviceDescription); if (ll.Count == 0) { print("没有发现佳能单反设备"); return; } myCamera = ll[0]; //设置设备 3 设置设备 //了解设备参数 //拍摄模式,就是主拨盘档位,没有意义,自己在相机上拨就好了 //我试的时候,需要拨到M档,如果需要获取视频流,必须是录像档位 //foreach (int ii in CameraHandler.GetSettingsList(EDSDK.PropID_AEModeSelect)) // print("AEMode = " + ii); //光圈 foreach (int ii in CameraHandler.GetSettingsList(EDSDKLib.EDSDK.PropID_Av)) avValues += ii + "|"; print("Av = " + avValues); //快门 foreach (int ii in CameraHandler.GetSettingsList(EDSDKLib.EDSDK.PropID_Tv)) tvValues += ii + "|"; print("Tv = " + tvValues); //感光度 foreach (int ii in CameraHandler.GetSettingsList(EDSDKLib.EDSDK.PropID_ISOSpeed)) isoValues += ii + "|"; print("ISO = " + isoValues); //以下不重要 //foreach (int ii in CameraHandler.GetSettingsList(EDSDK.PropID_MeteringMode)) // print("Metering = " + ii); //foreach (int ii in CameraHandler.GetSettingsList(EDSDK.PropID_ExposureCompensation)) // print("Exposure = " + ii); //设置设备 CameraHandler.SetSetting(EDSDKLib.EDSDK.PropID_Av, 80);//光圈 CameraHandler.SetSetting(EDSDKLib.EDSDK.PropID_Tv, 61);//快门速度 CameraHandler.SetSetting(EDSDKLib.EDSDK.PropID_ISOSpeed, 104);//ISO //Save To有三种,相机存储卡、本地即电脑、两者都保存。这里选保存到主机,单反没配存储卡 CameraHandler.SetSetting(EDSDKLib.EDSDK.PropID_SaveTo, (uint)EDSDKLib.EDSDK.EdsSaveTo.Host);//图片保存位置 CameraHandler.SetCapacity();//这句必须加,曾经不明白这句的API解释而含累错过 CameraHandler.ImageSaveDirectory = Application.streamingAssetsPath;//把拍到的照片保存到streamingAsset下 //显示输出

数值对应表:

光圈

快门

4 预设实时视频流的显示

            这个纯粹就是准备好一个RawImage组件,准备播放。

tt = new Texture2D(1920, 1080,TextureFormat.RGB24,true); moviePlane.texture = tt; 5 控制与输出 private bool isLiveOn = false; private byte[] tempBytes; // Update is called once per frame void Update () { if (Input.GetKeyDown(KeyCode.S)) { //拍照 CameraHandler.TakePhoto(); } if (Input.GetKeyDown(KeyCode.D)) { //开直播 CameraHandler.StartLiveView(); isLiveOn = true; } if (Input.GetKeyDown(KeyCode.F)) { //退出直播间~~ CameraHandler.StopLiveView(); isLiveOn = false; } if (isLiveOn) { //如果直播在开着,就一帧帧load显示。这里才是有坑的地方。 tempBytes = CameraHandler.GetImageByte(); tt.LoadImage(tempBytes); } } 6 录像视频流的API改造

        佳能的EDSDK提供的cs脚本并没有针对Unity,Unity C#的开发和.net framework的开发最突出的问题就是:C#里面的Bitmap在Unity里面没有,怎么把Bitmap转换成Texture呢?

在SDKHandler.cs里面需要做一些改动

1 新增函数和变量

public byte[] TextureBytes;//byte数组,外部获取 public byte[] GetImageByte() { if (TextureBytes != null && TextureBytes.Length != 0) return TextureBytes; return null; } public Bitmap TextureBitmap;//Bitmap中转变量 private MemoryStream ms;//转换中的关键变量

         2 找到DownloadEvf函数,在函数体内做如下修改

//run live view while (IsLiveViewOn) { //download current live view image err = EDSDKLib.EDSDK.EdsCreateEvfImageRef(stream, out EvfImageRef); if (err == EDSDKLib.EDSDK.EDS_ERR_OK) err = EDSDKLib.EDSDK.EdsDownloadEvfImage(MainCamera.Ref, EvfImageRef); if (err == EDSDKLib.EDSDK.EDS_ERR_OBJECT_NOTREADY) { Thread.Sleep(4); continue; } else Error = err; /* lock (STAThread.ExecLock) { //download current live view image err = EDSDKLib.EDSDK.EdsCreateEvfImageRef(stream, out EvfImageRef); if (err == EDSDKLib.EDSDK.EDS_ERR_OK) err = EDSDKLib.EDSDK.EdsDownloadEvfImage(MainCamera.Ref, EvfImageRef); if (err == EDSDKLib.EDSDK.EDS_ERR_OBJECT_NOTREADY) { Thread.Sleep(4); continue; } else Error = err; } */ //get pointer Error = EDSDKLib.EDSDK.EdsGetPointer(stream, out jpgPointer); Error = EDSDKLib.EDSDK.EdsGetLength(stream, out length); //get some live view image metadata if (!IsCoordSystemSet) { Evf_CoordinateSystem = GetEvfCoord(EvfImageRef); IsCoordSystemSet = true; } Evf_ZoomRect = GetEvfZoomRect(EvfImageRef); Evf_ZoomPosition = GetEvfPoints(EDSDKLib.EDSDK.PropID_Evf_ZoomPosition, EvfImageRef); Evf_ImagePosition = GetEvfPoints(EDSDKLib.EDSDK.PropID_Evf_ImagePosition, EvfImageRef); //release current evf image if (EvfImageRef != IntPtr.Zero) { Error = EDSDKLib.EDSDK.EdsRelease(EvfImageRef); } //create stream to image unsafe { ums = new UnmanagedMemoryStream((byte*)jpgPointer.ToPointer(), (long)length, (long)length, FileAccess.Read); } //把unmanageedMemoryStream类型的ums转成Bitmap TextureBitmap = new Bitmap(ums, true); ms = new MemoryStream(); //用System.Drawing.Bitmap的方法将Bitmap转成MemoryStream TextureBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); //将MemoryStream转成Bytes TextureBytes = ms.GetBuffer(); //fire the LiveViewUpdated event with the live view image stream if (LiveViewUpdated != null) LiveViewUpdated(ums); ums.Close(); }

主要注意这一段:

7 关闭会话 void OnApplicationQuit() { //CameraHandler.StopLiveView(); CameraHandler.Dispose(); }

在这个基础上可以实现拍照,照片会产生在StreamingAssets文件夹下,可以开启实时录像视频流,但是视频流观察下来有0.5秒-1秒的延迟。对于互动应用,如果需要实时画面让用户看到效果,不会影响需求实现,但是如果对实时性要求比较高,这个延迟是不行的,市面上我见过直接使用micro usb接口实现的单反拍照应用不延迟,我目前想应该不是通过unity实现的,还有一点,由于用到了STAThread脚本去管理一个线程,这个线程会在打开实时录像时使用,一旦使用,在exe状态下,关闭应用程序会导致卡死,后续我也会继续去研究怎么改进。

其他方案 视频采集卡

        单反有mini hdmi接口

          

        我们可以用mini hdmi 转hdmi线,连接单反与采集卡

        视频采集卡,无理是pcie内置采集卡,还是外置采集卡都可以

如果是PCIE的内置采集卡,Unity可以通过WebCamDevice去获取到这个“摄像”设备

如果是外置采集卡,则用采集卡另一端的USB3.0接口与主机连接,同样,Unity也是通过WebCamDevice去获取。

这样的技术方案,没有延迟。

缺点是连接了mini hdmi 档位需要在摄像档位,此时连接micro usb无法通过程序进行控制。

这个需求从当初研究到现在已经很长时间,如果有些地方写的不对或者不够好,欢迎您的指正。

工程源码参考:Unity控制佳能单反工程



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有