I am using the affdex SDK to detect emotions and while the detection of emotions I need to display the camera stream to the users to be able to see themselves, I am using the Aforge library and the Affdex SDk. when I wrote both in the main thread the camera stream worked fine but the emotion detection stopped, so I tried threading but still the camera is enabled but the detection doesn't work. any idea how to solve this issue?
Threading part:
Thread camThread = new Thread(camStart);
camThread.Start();
public void camStart()
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
CloseVideoSource();
videoSource.Start();
}
The affdexMe app might give some clues about how to do this as it provides a similar feature that you describe:
https://github.com/Affectiva/affdexme-win
Related
An alternative title could be: What happened to PIN_CATEGORY_STILL?
I am currently comparing images that were captured using DirectShow and PIN_CATEGORY_STILL with images that were captured using UWP MediaCapture.
On the device I am testing/playing around with DirectShow and MediaCapture, DirectShow detects a PIN_CATEGORY_STILL but I am not able to initialize an instance of MediaCapture with anything other than PhotoCaptureSource.VideoPreview.
MediaCaptureInitializationSettings settings = new()
{
VideoDeviceId = someDeviceId,
PhotoCaptureSource = PhotoCaptureSource.Photo
};
MediaCapture capture = new();
// this throws an exception
// "The capture source does not have an independent photo stream."
await capture.InitializeAsync(settings);
At this point I'm not even sure if PhotoCaptureSource.Photo is meant to be used as an equivalent to PIN_CATEGORY_STILL.
Images captured with PIN_CATEGORY_STILL are way brighter in a dark environment and have a much better quality (in file size and resolution) (which is clear to me, since I am using PhotoCaptureSource.VideoPreview for MediaCapture).
Considering this resource Win32 and COM for UWP apps, it seems like UWP MediaCapture does not use DirectShow underneath but MediaFoundation (which is meant to be a successor for DirectShow).
This article led me to this StackOverflow question Media Foundation is incorrectly marking still image capture stream descriptors as video capture, which basically states that MediaFoundation has no PIN_CATEGORY_STILL but returns 1 FPS as video capability for such devices (or profiles).
Since I am not directly using MediaFoundation nor C++, I tried testing this by querying GetAvailableMediaStreamProperties:
private void Foo()
{
var videoPreviewProperties = GetEncodingProperties(MediaStreamType.VideoRecord);
var photoProperties = GetEncodingProperties(MediaStreamType.Photo);
var videoRecordProperties = GetEncodingProperties(MediaStreamType.VideoPreview);
}
private List<VideoEncodingProperties> GetEncodingProperties(MediaStreamType streamType)
{
// MediaCapture was previously initialized with PhotoCaptureSource.VideoPreview
return MediaCapture.VideoDeviceController
.GetAvailableMediaStreamProperties(streamType)
.OfType<VideoEncodingProperties>()
.ToList();
}
None of these returns a VideoEncodingProperties with only 1 FPS.
To test MediaCapture any further I tried some of the sample applications from here UWP sample. I tried CameraAdvancedCapture, CameraOpenCV and CameraManualControls, but the results were not nearly as good as good old PIN_CATEGORY_STILL.
What happened to PIN_CATEGORY_STILL?
Is there any way to capture images without DirectShow/PIN_CATEGORY_STILL and still keeping this level of quality?
Any enlightenment is much appricated.
I am trying to show AR video by connecting the hand tracking camera device (Leap motion: window device manager list: 0) and webcam camera (window device manager list: 1) in Unity.
Leap motion connects using the manufacturer's SDK and package files, so there is no need for additional coding to connect the camera in Unity.
The problem occurs when I connect a webcam camera (window device manager list: 1) in Unity and show AR video.
When the following code is applied to an object, if both Leap motion and webcam camera are connected, leap motion is recognized and output as video, and video output of webcam camera becomes impossible.
If only the webcam is connected after unplugging the leap motion from the PC, the video output of the webcam camera is possible.
I want to output video by selecting webcam camera (window device manager list: 1) on the object with both Leap motion and webcam camera connected to the PC.
Since I am a beginner in Unity, I need to simply modify it in the code below.
Waiting for help.
using UnityEngine;
using System.Collections;
public class WebCam : MonoBehaviour {
// Use this for initialization
void Start () {
WebCamTexture web = new WebCamTexture(1280,720,60);
GetComponent<MeshRenderer>().material.mainTexture = web;
web.Play();
}
// Update is called once per frame
void Update () {
}
}
There is a constructor of WebCamTexture that takes the parameter
deviceName: The name of the video input device to be used.
You can list all available devices via WebCamTexture.devices and get the name like e.g.
var devices = WebCamTexture.devices;
var webcamTexture = new WebCamTexture(devices[1].name);
You might also be able then to filter out the device you need like e.g.
using System.Linq;
...
var device = devices.Select(d => d.name).FirstOrDefault(n => !n.Contains("Leap"));
For finding out how the cameras are called and to be able to filter by name you could print them all like e.g.
Debug.Log(string.Join("\n", devices.Select(d => d.name)));
Theoretically you could even feed them into a dropdown and let the user decide which device to use before creating the WebCamTexture then you wouldn't have to guess the name hardcoded at all ;)
Also note:
Call Application.RequestUserAuthorization before creating a WebCamTexture.
I am developing an app in unity in which the user can take photos using their device camera. This is working great using Unity's webcamtexture. However, there is no flash support for webcamtexture, so I have written my own code to access the device Torch. The code WORKS - However it doesn't work while streaming the webcamtexture (the camera is in use so the java service call returns an error). Does anyone have any suggestions for how to get around this issue? Is there any way to use Unity's WebCamTexture to activate the camera torch? Here is my code for activating the camera torch:
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
// This is an ugly hack to make Unity
// generate Camera permisions
WebCamDevice[] devices = WebCamTexture.devices;
int camID = 0;
camera = cameraClass.CallStatic<AndroidJavaObject>("open", camID);
// I'm pretty sure camera will never be null at this point
// It will either be a valid object or Camera.open would throw an exception
if (camera != null)
{
AndroidJavaObject cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode","torch");
camera.Call("setParameters",cameraParameters);
Active = true;
}
Try checking out camera capture kit for unity. It gives that functionality you want for Android as well as the source code for it.
https://www.assetstore.unity3d.com/en/#!/content/56673
I work on project that capture an images from webcams using C# and Aforge.
When the camera is a 'CyberLink' i get this frame from the camera:
The code that you see here is only part of my code of course, but it demonstrates my use in Aforge.
Get all cams on this PC:
var webCam = new FilterInfoCollection(FilterCategory.VideoInputDevice);
var cams = new List<VideoCaptureDevice>();
foreach (FilterInfo camInfo in webCam)
{
var cam = new VideoCaptureDevice(camInfo.MonikerString);
cam.NewFrame += NewFrameHandler;
cams.Add(cam);
}
I have a timer that every few minutes starts the camera like this:
foreach (var cam in cams)
{
cam.Start();
}
When i get the event 'NewFrame' i call to my function 'NewFrameHandler' to save the frame and close the camera:
var bit = (Bitmap)eventArgs.Frame.Clone();
bit.Save("#c:\Cam_" + DateTime.Now.Ticks + ".png", ImageFormat.Png);
foreach (var cam in cams)
{
cam.SignalToStop();
}
As i say the code works great, only when the camera is CyberLink i have this problem.
I removed the youcam software and now I get the frames properly.
Would love to hear if anyone has a more elegant solution.
The YouCam software may hijack the stream, and removing it may be the only option. You could also check if YouCam offers an API of its own that allows you to interface with the camera. I have used AForge before and it worked great with the Logitech cameras I was using. Your code looks good to me, though it was a year or two ago when I was using AForge.
I'm in dire need of a replacement for a wrapper being used in a C# application. Basically, what we need to do is attach a webcam feed to one of two picture boxes. This will be used to take still images at the push of a button, which may detach the camera feed and attach the still image to that picture box, then reattach the camera feed later. We had previously found some free code to utilize with a CaptureDevice.cs file and Pinvoke.dll to tie it into avicap32.dll. Unfortunately, this seems to have random, intermittent errors that cannot be reliably reproduced. It's just too flaky. At some random point, one of those picture boxes may go black and won't show the feed until the picture is taken, at which point the proper picture is attached to the picture box. Then, even if there's only one webcam attached, it'll keep prompting for the webcam to be selected, something it wouldn't do otherwise.
Quite frankly, I'm surprised and dismayed that Microsoft hasn't included anything in .NET to cover webcam video feeds. I'm looking for something reliable and relatively simple to implement to replace this buggy webcam system.
It is time to use MediaCapture object. Use this sample for MS Windows 10 https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraStarterKit/
And read this article as well http://www.codepool.biz/csharp-camera-api-video-frame.html
May I suggest
http://www.emgu.com/wiki/index.php/Main_Page
I have used OpenCV in many C++ libraries and it seems to work very well for webcams from other things I've tried. Emgu is just a C# wrapper for OpenCV.
Here is a sample project to try it out on. It's very basic and simple, but should work right away.
http://dl.dropbox.com/u/18919663/vs%20samples/OpenCVCSharpTest.zip (just uploaded)
Sample:
using Emgu.CV;
using Emgu.CV.Structure;
...
public partial class Form1 : Form
{
public Capture cvWebCam;
public Form1()
{
InitializeComponent();
try
{
cvWebCam = new Capture();
timer1.Start();
}
catch
{
Console.WriteLine("Default camera not found or could not start");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (cvWebCam != null)
using (Emgu.CV.Image<Bgr, byte> frame = cvWebCam.QueryFrame())
{
pictureBox1.BackgroundImage = frame.ToBitmap();
}
}
}
Try DirectShow.net- it's a free wrapper library to access DirectShow functionality from .NET:
http://directshownet.sourceforge.net
Its code samples contain a sample app for capturing video from webcams, too:
http://sourceforge.net/projects/directshownet/files/DirectShowSamples/