I'm trying to capture images from a webcam for one application in WPF/C#
1) I tried WIA but i het the error 0x80210015, I have read that this error occurs when there is no WIA device available. I read that in windows vista/7 WPD is used insted WIA but when i try a simple example
PortableDeviceManager deviceManager = new PortableDeviceManager();
deviceManager.RefreshDeviceList();
uint numberOfDevices = 1;
deviceManager.GetDevices(null, ref numberOfDevices);
if (numberOfDevices == 0)
{
Console.WriteLine("No device");
}
else
{
string[] deviceIds = new string[numberOfDevices];
deviceManager.GetDevices(ref deviceIds[0], ref numberOfDevices);
Console.WriteLine(deviceIds);
}
Console.Read();
i cant detect devices.
2) I triead with http://easywebcam.codeplex.com/ works, but i get randomly the error "An error occured while capturing the video image. The video captu..." and i need select the device always and i need execute webcam.start() several times (2 or 3) for that camera works.
I have two webcams
Chicony Web 2.0 (inbuilt webcam)
Genius FaceCam 2000
here is a simple take a picture kind of program
Image<Bgr, Byte> img;
private Capture capture;
private bool captureInProgress;
private void gumb_kamera_Click(object sender, EventArgs e)
{
}
private void processFunction(object sender, EventArgs e)
{
img = capture.QueryFrame();
// imageBox1.Image = img;
}
private void Form1_Load(object sender, EventArgs e)
{
if (capture == null)
{
try
{
capture = new Capture(0);
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
if (capture != null)
{
if (captureInProgress)
{
Application.Idle -= processFunction;
}
else
{
Application.Idle += processFunction;
}
captureInProgress = !captureInProgress;
}
}
private void button1_Click(object sender, EventArgs e)
{
imageBox1.Image = img;
}
Related
am trying to make streaming video using aforge on visual studio windows forms
in debug mode everything works well but after publishing it the picturebox that is used to show the video still white
Here is the code
if (device != null && cboDevice.Items.Count != 0)
{
if (firstim != null)
{
pictureBox1.Image = firstim;
}
device = new VideoCaptureDevice(filter[cboDevice.SelectedIndex].MonikerString);
device.NewFrame += new NewFrameEventHandler( Device_NewFrame);
device.Start();
private void Form1_Load(object sender, EventArgs e)
{
filter = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach(FilterInfo dev in filter)
cboDevice.Items.Add(dev.Name);
cboDevice.SelectedIndex = 0;
device = new VideoCaptureDevice();
}
private void button4_Click(object sender, EventArgs e)
{
if (device != null && cboDevice.Items.Count != 0)
{
device = new VideoCaptureDevice(filter[cboDevice.SelectedIndex].MonikerString);
device.NewFrame += Device_NewFrame;
device.Start();
}
}
My goal is to use my webcam to capture my face and detect my mood by facial expression. The output should be probabilites like 70 % happy, 10 % sad, ...
My approach: very happy and very sad ( and other states ) faces should be saved in a HaarCascade.
My problems are twofold:
How do I create a HaarCascade to use with HaarObjectDetector for the
HaarObjectDetector object to output percentages instead of
outputting a "true" when a threshold is being surpassed?
How do I create a HaarCascade for HaarCascade? Is it easier to use String path = #"C:\Users\haarcascade-frontalface_alt2.xml"; HaarCascade cascade1 = HaarCascade.FromXml(path); with opencv-xml or generate it using HaarCascade m = new HaarCascade(20,20,HaarCascadeStages);? What would HaarCascadeStages be?
Have others already solved this issue and offer sourcecode for c#?
My current code:
public partial class Form1 : Form
{
private bool DeviceExist = false;
private FilterInfoCollection videoDevices;
private VideoCaptureDevice videoSource = null;
Bitmap picture;
HaarObjectDetector detector;
FaceHaarCascade cascade;
public Form1()
{
InitializeComponent();
}
// get the devices name
private void getCamList()
{
try
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
comboBox1.Items.Clear();
if (videoDevices.Count == 0)
throw new ApplicationException();
DeviceExist = true;
foreach (FilterInfo device in videoDevices)
{
comboBox1.Items.Add(device.Name);
}
comboBox1.SelectedIndex = 0; //make dafault to first cam
}
catch (ApplicationException)
{
DeviceExist = false;
comboBox1.Items.Add("No capture device on your system");
}
}
//toggle start and stop button
private void start_Click(object sender, EventArgs e)
{
}
//eventhandler if new frame is ready
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
picture = (Bitmap)eventArgs.Frame.Clone();
//Rectangle[] objects = detector.ProcessFrame(picture);
//if (objects.Length > 0)
//{
// RectanglesMarker marker = new RectanglesMarker(objects, Color.Fuchsia);
// pictureBox1.Image = marker.Apply(picture);
//}
pictureBox1.Image = picture;
}
//close the device safely
private void CloseVideoSource()
{
if (!(videoSource == null))
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource = null;
}
}
//get total received frame at 1 second tick
private void timer1_Tick(object sender, EventArgs e)
{
label2.Text = "Device running... " + videoSource.FramesReceived.ToString() + " FPS";
}
//prevent sudden close while device is running
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
CloseVideoSource();
}
private void Form1_Load(object sender, EventArgs e)
{
getCamList();
cascade = new FaceHaarCascade();
detector = new HaarObjectDetector(cascade, 30);
detector.SearchMode = ObjectDetectorSearchMode.Average;
detector.ScalingFactor = 1.5f;
detector.ScalingMode = ObjectDetectorScalingMode.GreaterToSmaller;
detector.UseParallelProcessing = false;
detector.Suppression = 2;
}
private void rfsh_Click_1(object sender, EventArgs e)
{
}
private void start_Click_1(object sender, EventArgs e)
{
if (start.Text == "Start")
{
if (DeviceExist)
{
videoSource = new VideoCaptureDevice(videoDevices[comboBox1.SelectedIndex].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
CloseVideoSource();
videoSource.DesiredFrameSize = new Size(640, 480);
//videoSource.DesiredFrameRate = 10;
videoSource.Start();
label2.Text = "Device running...";
start.Text = "Stop";
timer1.Enabled = true;
}
else
{
label2.Text = "Error: No Device selected.";
}
}
else
{
if (videoSource.IsRunning)
{
timer1.Enabled = false;
CloseVideoSource();
label2.Text = "Device stopped.";
start.Text = "Start";
}
}
}
}
i've try the following way to record the video from the Webcam by 25 Frame-rate per sec for 10sec but when i get the out put video it is of 2sec and the frames are played to fast as compare to the video stream.
The code is as follows.
using System;
using System.Drawing;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Threading;
using AForge.Video.FFMPEG;
namespace AforgeTutorial
{
public partial class Form1 : Form
{
private FilterInfoCollection ListOfCams;
private VideoCaptureDevice SelectedCam; //From where we will take image
System.Timers.Timer tim;
Thread t;
bool isNewFrame = false;
VideoFileWriter writer;
public Form1()
{
InitializeComponent();
tim = new System.Timers.Timer(10000);
tim.Elapsed += new System.Timers.ElapsedEventHandler(tim_Elapsed);
t = new Thread(saveVideo);
}
void tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (isRecord)
{
writer.Close();
isRecord = false;
}
}
private void Form1_Load(object sender, EventArgs e)
{
ListOfCams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
if (ListOfCams.Count == 0)
return;
comboBox1.Items.Clear();
foreach (FilterInfo Cam in ListOfCams)
{
comboBox1.Items.Add(Cam.Name);
}
}
private void StopCamera()
{
SelectedCam.SignalToStop();
SelectedCam.Stop();
}
bool isRecord = false;
private void Start_Click(object sender, EventArgs e)
{
if (comboBox1.Text == string.Empty)
return;
SelectedCam = new VideoCaptureDevice(ListOfCams[comboBox1.SelectedIndex].MonikerString);
SelectedCam.NewFrame += new NewFrameEventHandler(SelectedCam_NewFrame);
SelectedCam.Start();
}
Bitmap image;
void SelectedCam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
image = (Bitmap)eventArgs.Frame.Clone();
isNewFrame = true;
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopCamera();
}
private void Stop_Click(object sender, EventArgs e)
{
StopCamera();
}
private void btnRecord_Click(object sender, EventArgs e)
{
tim.Start();
if (!isRecord)
{
writer = new VideoFileWriter();
writer.Open(#"C:/code-bude_test_video.mp4", 640, 480, 25, VideoCodec.MPEG4,10000);
}
isRecord = !isRecord;
if (isRecord)
t.Start();
}
void saveVideo()
{
while (isRecord)
{
if (isNewFrame)
{
writer.WriteVideoFrame(image);
isNewFrame = false;
}
}
}
}
}
You have multi-threading issues in your code. You can't write to shared variables like that and expect it to synchronize.
You have three threads: user interface, streaming and saving. (SelectedCam_NewFrame runs in the AForge streaming thread). Make a list of all variables that are accessed in at least two threads (isRecord, isNewFrame, etc) and add proper synchronization.
You can check this very good reference on threading in C#.
Note that even with synchronization, you may miss frames if your writer thread is busy while several images arrive. What you might want to do is collect the frames produced by the camera in a queue and consume that queue in the writer thread. Check the producer/consumer patterns.
How to save emgu CV camera capture image in folder and retrieve. Whenever I trying to save null reference exception error getting.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.Util;
using Emgu.CV.Structure;
namespace camerapart2
{
public partial class Form1 : Form
{
private Capture capture;
private bool captureinprogress;
public Form1()
{
InitializeComponent();
}
private void ProcessFrame(object sender, EventArgs arg)
Image<Bgr, Byte> ImageFrame = capture.QueryFrame();
cameraimage.Image = ImageFrame;
pictureBox1.Image = ImageFrame.ToBitmap();
ImageFrame.Save(#"E:\MyPic.jpg");
private void btnStart_Click(object sender, EventArgs e)
{
if (capture == null)
{
try
{
capture = new Capture();
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
if (capture != null)
{
if (captureinprogress)
{ //if camera is getting frames then stop the capture and set button Text
// "Start" for resuming capture
btnstart.Text = "Start!"; //
Application.Idle -= ProcessFrame;
}
else
{
//if camera is NOT getting frames then start the capture and set button
// Text to "Stop" for pausing capture
btnstart.Text = "Stop";
Application.Idle += ProcessFrame;
}
captureinprogress = !captureinprogress;
}
}
private void ReleaseData()
{
if (capture != null)
capture.Dispose();
}
}
}
In these two lines I'm getting nullrefference error:
pictureBox1.Image = ImageFrame.ToBitmap();
ImageFrame.Save(#"E:\MyPic.jpg");
I used emguCV's ImageBox instead of native C#'s pictureBox and added a button btnSave on a form
namespace CameraCapture
{
public partial class CameraCapture : Form
{
//declaring global variables
private Capture capture; //takes images from camera as image frames
private bool captureInProgress;
private bool saveToFile;
public CameraCapture()
{
InitializeComponent();
}
//------------------------------------------------------------------------------//
//Process Frame() below is our user defined function in which we will create an EmguCv
//type image called ImageFrame. capture a frame from camera and allocate it to our
//ImageFrame. then show this image in ourEmguCV imageBox
//------------------------------------------------------------------------------//
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> ImageFrame = capture.QueryFrame();
CamImageBox.Image = ImageFrame;
if (saveToFile)
{
ImageFrame.Save(#"D:\MyPic.jpg");
saveToFile = !saveToFile;
}
}
//btnStart_Click() function is the one that handles our "Start!" button' click
//event. it creates a new capture object if its not created already. e.g at first time
//starting. once the capture is created, it checks if the capture is still in progress,
//if so the
private void btnStart_Click(object sender, EventArgs e)
{
#region if capture is not created, create it now
if (capture == null)
{
try
{
capture = new Capture();
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
#endregion
if (capture != null)
{
if (captureInProgress)
{ //if camera is getting frames then stop the capture and set button Text
// "Start" for resuming capture
btnStart.Text = "Start!"; //
Application.Idle -= ProcessFrame;
}
else
{
//if camera is NOT getting frames then start the capture and set button
// Text to "Stop" for pausing capture
btnStart.Text = "Stop";
Application.Idle += ProcessFrame;
}
captureInProgress = !captureInProgress;
}
}
private void ReleaseData()
{
if (capture != null)
capture.Dispose();
}
private void btnSave_Click(object sender, EventArgs e)
{
saveToFile = !saveToFile;
}
}
}
this subject is old but if you wanna use emguCV's ImageBox you can use this code
private void ProcessFrame(object sender, EventArgs arg)
{
Mat frame = new Mat();
capture.Retrieve(frame);
CamImageBox.Image = frame;
}
I make a program in C# windows form I have tons of function in my form including two datagrid view that connected to dabase and including a camera that direcly connected to my PC I use AForge dll reference to connect to the camera device I just found the tutorial on youtube and it works perfecly for me, as I stated earlier I have too many programs in one form including that camera and it went out that the camera was need to be resized to a small resolution, so I decided to make a popup button that must show the wider resolution when I click the button on my form.
this is the code for my camera.
//Camera
// get the devices name
private void getCamList()
{
try
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
comboBox1.Items.Clear();
if (videoDevices.Count == 0)
throw new ApplicationException();
DeviceExist = true;
foreach (FilterInfo device in videoDevices)
{
comboBox1.Items.Add(device.Name);
}
comboBox1.SelectedIndex = 0; //make dafault to first cam
}
catch (ApplicationException)
{
DeviceExist = false;
comboBox1.Items.Add("No capture device on your system");
}
}
//refresh button
private void refresh_Click(object sender, EventArgs e)
{
getCamList();
}
//toggle start and stop button
private void start_Click(object sender, EventArgs e)
{
if (start.Text == "&Start")
{
if (DeviceExist)
{
videoSource = new VideoCaptureDevice(videoDevices[comboBox1.SelectedIndex].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
CloseVideoSource();
videoSource.DesiredFrameSize = new Size(160, 120);
//videoSource.DesiredFrameRate = 10;
videoSource.Start();
lblCam.Text = "Device running...";
start.Text = "&Stop";
}
else
{
lblCam.Text = "Error: No Device selected.";
}
}
else
{
if (videoSource.IsRunning)
{
CloseVideoSource();
lblCam.Text = "Device stopped.";
start.Text = "&Start";
}
}
}
//eventhandler if new frame is ready
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap img = (Bitmap)eventArgs.Frame.Clone();
//do processing here
pictureBox1.Image = img;
}
//close the device safely
private void CloseVideoSource()
{
if (!(videoSource == null))
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource = null;
}
}
//prevent sudden close while device is running
private void Form1_FormClosed(object sender, FormClosingEventArgs e)
{
CloseVideoSource();
}
} }
I also posted a picture so that you have further understanding what I am talking.
as you can see at the lower right corner I have a pop up button there honestly telling you I already tried different methods but nothing works unfotunately I cannot post what I've tried because I created it yesterday and can no longer undo the codes I tried. Any Idea?
Create a new Form
Place a PictureBox on this Form
Add all methods to initialize and get the current frame to the Form (should be refactored to an own class providing an event like FrameChanged giving you the current image)
add a method like to the Form
public void ShowCamPopup(string deviceName)
{
InitializeDevice(string deviceName, int width, int height);
this.Show();
this.BringToTop();
}
You should the really consider to refactor the communication with your cam to an own class which reduces duplicate code and allows you to do performance tweaks (which you will need for sure later) at a single position of your solution.