Webcam frame from Aforge always gray image - c#

I am using Aforge .NET framework to get a webcam in my app but I always get an all gray image frame.
this.videoSource = new VideoCaptureDevice(this.Moniker);
this.videoSource.DesiredFrameSize = GetHighestResolution(this.videoSource.VideoCapabilities);
this.videoSource.NewFrame += new NewFrameEventHandler(videoSource_NewFrame);
this.videoSource.Start();
The vent handler:
private void videoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
this.outputBox.Image = (Bitmap)eventArgs.Frame.Clone();
}
This should do the trick. DesiredFrameSize is set to the highest value the cam can support.
Any hints why the image is always gray? Even when writing it do disk...
Edit: To add: The same problem occurs with the sample application SimplePlayer from Aforge samples. My webcam is a Logitech QuickCam Pro 9000.
Edit2: The same goes for small DesiredFramesizes.

maybe the camera isnt wrapped around directshow (some sort of directx stuff).
some camera's come with their own driver, or different inner working.
I have some highspeed industrial camera's, with simmilar issues.
I had to retrieve the raw images from them using diffrent methods, then do aforge stuff on those images.
Maybe check your code using older cheap USB2 camera's

Related

Why is my webcam only taking one frame upon execution via Emgu?

I have some code that takes opens my webcam via Emgu upon loading Form1. The problem I have, though, is that I can only load the first frame.
I have tried to use Webcam() to create a video capture, but it only takes the first frame. If I assign this code to a button, it will take only 1 frame upon each button press. I have tried to create a continuation of the video capture using Webcam2(), but the the picturebox had 1 FPS and would exponentially use more memory overtime.
I know it is not my computer as I was able to use webcam via emgu using its facial recognition viewer (I used the guide at https://www.youtube.com/watch?v=ZSxHyp4OZx0 to test this out). Unfortunately, while I am creating a a similar project, I am using AWS for the facial recognition. Still, I was able to run the Emgu camera viewer without any issues or bad framerates. My Laptop is a 2022 high end gaming laptop.
Here is the code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
showit();
//Application.Idle += Webcam2;
//Webcam();
}
private void Webcam2(object sender, EventArgs e)
{
VideoCapture capture = new VideoCapture();
pictureBox1.Image = capture.QueryFrame().ToBitmap();
}
private void Webcam()
{
VideoCapture capture = new VideoCapture();
pictureBox1.Image = capture.QueryFrame().ToBitmap();
}
}
Any idea what is going on?

C# axWindowsMediaPlayer Change Video Position with Custom Trackbar

I have a axWindowsMediaPlayer on WinForm with uiMode=none. I am using my custom controls to handle playback. I am using this method to associate a trackBar with axWindowsMediaPlayer.
I want to change the video position (jump to specific time) when the user scrolls the trackBar, just like windows media player.
private void trackBar_Scroll(object sender, EventArgs e)
{
if (axWindowsMediaPlayer.playState == WMPLib.WMPPlayState.wmppsPlaying)
{
axWindowsMediaPlayer.Ctlcontrols.currentPosition = trackBar.Value;
}
}
This is not working. I have checked many Stackoverflow answers including this, this, and the Microsoft documentation but none is working.
I have two objectives:
When playing media, the trackBar should show the current position of the media file being played. This is working fine.
When the user scrolls the trackBar, the media player should change the video current position based on the trackBar value. This is not working.
Any help will be highly appreciated.
I solved the issue. The problem was not with the media player, the problem was with the media files being played with the axWindowsMediaPlayer.
axWindowsMediaPlayer plays the files such as MKV fine, but if the proper codecs are not installed, the Ctlcontrols mainly the Trackbar does not work from code or UI. With natively supported formats, this code works perfectly fine.
private void trackBar_Scroll(object sender, EventArgs e)
{
if (axWindowsMediaPlayer.playState == WMPLib.WMPPlayState.wmppsPlaying)
axWindowsMediaPlayer.Ctlcontrols.currentPosition = trackBar.Value;
}
For media files not natively supported, their codecs need to be installed. For details of supported file formats, see this KB article File types supported by Windows Media Player

directshow.net webcam overlay transparent panel

I am trying to use a webcam to take photos for badges. To do this I have used the directshow.net library and examples, this has got me a webcam preview screen in .NET rendered in a picturebox as per DxSnap sample. I now wish to overlay it with a rectangle which is moveable and resizable (locked aspect ratio) so the end user drags this over the person to take an image from the webcam at the appropriate point. So it would look something like this:
To do this I thought no problem, the webcam source is put into a picture box I will just overlay it with a transparent panel or picture frame and use normal .NET code to make a rectangle on there. If I overlay a normal panel it appears above the directshow webcam output as expected. However if I use this trick to implement a transparent panel or picturebox:
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return createParams;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do not paint background.
}
It unfortunately appears underneath the directshow output. Is there an easy way to work around this or an alternative method. I would prefer not to delve too deeply into directshow.net if avoidable, I thought this would be an easy way to avoid it.
I have ended up using the AForge.NET project instead of DirectShow.NET. It has some really great samples and drawing over its video output is as simple as handling its video players OnPaint event since it calls it for each frame. It seems to take a bit more CPU but nothing too taxing.
The problem with overlaying is that video is displayed in a way different from regular GUI graphics, via specific method creating non-RGB surfaces (typically) on the video adapter. As a result of this, you cannot overlap video with windows, or use GDI directly.
You still can modify video on the way, or overlay video using special mixer.
See this question: Showing a semi-transparent Image object over an IVideoWindow in C# using DirectShow.NET as it discusses a similar request.

How to draw on an unfilled box on a video stream using the mouse

I am using dshownet(first time) and C#. I have got a sample to take the web cam input and display it on a form. I now need to draw a rectangle on top of the video stream using the mouse. (the intent is to track what is inside the box from there onwards).
I heard that there is something called VMR. So I went to the dshownet samples and went through them. I didnt find any samples that use the mouse to overlay a shape on the video stream. Someone on here suggested to use colorkey. Another person said to use GDI+ and mouse handling. I tried to compile the DXLogo sample but got this error :
Error 1 Cannot create an instance of the abstract class or interface 'System.Drawing.Image' C:\Documents and Settings\TLNA\Desktop\Final Year Project\Libraries\DirectShow library 2\DirectShowSamples-2010-February\Samples\Capture\DxLogo\Capture.cs 128 32 DxLogo-2008
for the code section:
if (fileName.Length > 0)
{
m_Bitmap = new Image(fileName); // error happened here
Rectangle r = new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height);
m_bmdLogo = m_Bitmap.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
}
I know that I must go through the Bitmap9 Interface. But I really dont know where to start. Should I read the Directshow API docs.
btw I also have the book Programming Microsoft Directshow for digital video and television. I started reading that book and stopped after a few pages since the code is mainly in C++. Should I continue to read this is book ? How can I accomplish the certain mentioned tasks in C# ?
Any suggestions as how to draw on the video. Some useful links(tutorials) would be helpful.
Many Thanks
Tlna
I'm not sure why the DirectShow sample doesn't compile, but you may be able to change the problem line:
m_Bitmap = new Image(fileName);
to this:
m_Bitmap = new Bitmap(fileName);
and get it to work.
You're actually facing a pretty difficult problem here. DirectShow renders a video by drawing a series of still frames to a device context (like a PictureBox or a Form, or even the screen) many times a second (depending on whatever the frame rate is). You (as a programmer) can also (easily) render graphics directly to this same device context.
However, in order to make your drawn box appear over top of a running video, your code needs to draw the rectangle immediately after DirectShow draws each frame of the video; otherwise, the next frame will obliterate your rectangle. DirectShow objects probably have some sort of frame rendering event that you can handle, and then inside the event handler you just re-draw your box (based on the initial and current mouse coordinates, which you can get from the MouseDown and MouseMove events of whatever control you're drawing on).
Update: I just took a look at my code from when I was playing around with DirectShow.NET, and it looks like there is an event (DsEvCode.Repaint) that you could hook into and use to draw your box.
I haven't looked at the code sample you're working with, but do a search and see if you can find an OnGraphNotify() method in your code, you should be able to add something like this:
if (code == DsEvCode.Repaint)
{
// draw the box here
}
Presumably, this event is fired after each frame of the video is rendered, so if you redraw your box here every time it will appear as if the box is persisting.

.NET code to record a specific form activity + audio to avi

I am looking for some C# code .. or .NET component to record the activity of a form on my screen (not the whole desktop) along with audio, similar to what programs like Camtasia allow to do.
The video part is actually pretty easy. All you need to have is a timer running 20 times a second that will save form's canvas to a image files as frames. Then create an animation out of these pictures.
To capture image:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
tVideo.Start();
}
int i = 0;
private void tVideo_Tick(object sender, EventArgs e)
{
String lFile = String.Format("c:\\{0}.bmp", i);
SaveAsBitmap(this, lFile);
i++;
}
public void SaveAsBitmap(Control aCtrl, string aFileName)
{
if (File.Exists(aFileName))
File.Delete(aFileName);
Graphics lGraphics = aCtrl.CreateGraphics();
Bitmap lImage = new Bitmap(aCtrl.Width, aCtrl.Height);
aCtrl.DrawToBitmap(lImage, new Rectangle(0, 0, aCtrl.Width, aCtrl.Height));
lImage.Save(aFileName);
lImage.Dispose();
}
}
This is just a light sample, of course you would have to add some compression and try to avoid saving the same image twice. Knowing how many images are the same + knowing about the framerate, you know how long to display the same frame.
To add a cursor you would have to keep some variables with mouse x,y and an event on mouse click. And then just add it to pictures.
Of course, this won't work for 3d games inspite of overlay which is drawn after the win32 paints.
For that you would have to go with DirectX/OpenGl/XNA. I think the idea is the same.
For audio, DirectX also.
My complete source:
http://deathsquad.pl/archiwum/Inne/so/answer-1934452.rar
Some DirectX audio samples:
http://www.codeproject.com/KB/directx/audiosav.aspx
Check out Gallio: It is a great testing framework, and it has built in screen recording API.
This post shows a few examples:
http://blog.bits-in-motion.com/2009/09/announcing-gallio-and-mbunit-v31.html

Categories

Resources