Sending Images from Webcam to WinForm?

I am working on a custom dashboard style app for a simulated environment. I've got a webcam in the environment, and I'd like to display the image from the camera in the dashboard form. I know that copying bitmaps is an expensive operation, and I'm not all that familiar with C# libraries. I'm wondering what the ideal way to do this would be. This is what I'm doing right now:

Code Snippet

private void NotifyCameraNewFrame(webcam.QueryFrameResponse response)
{
Bitmap frame = null;

using (MemoryStream stream = new MemoryStream(response.Frame, false))
{
Bitmap tempframe = new Bitmap(stream);
frame = new Bitmap(tempframe);
tempframe.Dispose();
}

Invoke(delegate()
{
_form.updateWebCam(frame);
});
}

Code Snippet

public void updateWebCam(Image image)
{
webcam.Image = image;
}


[1200 byte] By [JoshdeLeeuw] at [2008-2-22]
# 1
Best example of this is the new samples\misc\BlobTrackerCalibrate service. It does everything you need
GeorgeChrysanthakopoulos at 2007-9-26 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Community...
# 2
Thanks George, that was exactly what I was hoping for. It works wonderfully. I do have another problem related to this, which could be a bug, but it is much more likely a problem on my end.

I'm using the Pioneer model in the simulator. The webcam wasn't refreshing regularly on its own, so I modified the UpdateInterval field before the camera is inserted into the simulation:

Code Snippet

private CameraEntity CreateCamera()
{
// low resolution, wide Field of View
CameraEntity cam = new CameraEntity(320, 240);
cam.State.Name = "robocam";
// just on top of the bot
cam.State.Pose.Position = new Vector3(0.0f, 0.5f, 0.0f);
// camera renders in an offline buffer at each frame
// required for service
cam.IsRealTimeCamera = true;
cam.UpdateInterval = 50;

// Start simulated webcam service
simwebcam.Contract.CreateService(
ConstructorPort,
Microsoft.Robotics.Simulation.Partners.CreateEntityPartner(
"http://localhost/" + cam.State.Name)
);

return cam;
}

If I try to get 20fps, as shown above, it crashes very quickly, and the debugger brings up the SimulatedWebcam.cs file and says that the object is already in use. Even at 5fps, or an interval of 200ms this still happens. It seems to run okay at about 4fps. Is this just because of computational limitations, or am I going about setting frame rate in the wrong way?

Thanks

JoshdeLeeuw at 2007-9-26 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Community...
# 3

It might be a bug on our side, althought we have never observed this crash, with the simulationTutorial2 (or MobileRobots simulation) manifests. Does this happen when you just run our manifests/services, with no modifications? It could be that on a slower machine, this happen, but somehow we have not run into it ( we do test on alot of slow machine though Smile

can you also include the exception details? line number in simwebcam.cs, etc?

thanx

g

GeorgeChrysanthakopoulos at 2007-9-26 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Community...
# 4
For the record, I had this same crash at least once last week on my dual core box. I don't recall that I did anything specific to fix it and I haven't seen it since. If it comes up again I'll post the details.
RobSim--Braintech at 2007-9-26 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Community...
# 5
Hi George. Here's the details:

The exception thrown is IvalidOperationException, message "Object is currently in use elsewhere."

Line 301 in SimulatedWebcam.cs (bolded below)

Code Snippet

[ServiceHandler(ServiceHandlerBehavior.Concurrent)]
public IEnumerator<ITask> QueryFrameHandler(webcam.QueryFrame query)
{
if (_state.Image == null)
{
query.ResponsePort.Post(new webcam.QueryFrameResponse());
yield break;
}

Size size = new Size((int)query.Body.Size.X, (int)query.Body.Size.Y);

if (query.Body.Format == Guid.Empty)
{
// raw image requested;
BitmapData raw = null;

// size not specified
if(size.Width == 0)
size = _state.Image.Size;

try
{
raw = _state.Image.LockBits(new Rectangle(Point.Empty, size),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

int byteSize = raw.Height * raw.Stride;

webcam.QueryFrameResponse response = new webcam.QueryFrameResponse();

response.TimeStamp = _state.LastFrameUpdate;
response.Frame = new byte[byteSize];
response.Size = new Size(raw.Width, raw.Height);
response.Format = Guid.Empty;

System.Runtime.InteropServices.Marshal.Copy(raw.Scan0, response.Frame, 0, byteSize);

query.ResponsePort.Post(response);
}
catch (Exception ex)
{
query.ResponsePort.Post(Fault.FromException(ex));
}
finally
{
if (raw != null)
{
_state.Image.UnlockBits(raw);
}
}
}
else
{
ImageFormat format = new ImageFormat(query.Body.Format);

using (MemoryStream stream = new MemoryStream())
{
if (size == _state.Image.Size ||
size.Width == 0 ||
size.Height == 0 ||
size.Width >= _state.Image.Width ||
size.Height >= _state.Image.Height)
{
size = _state.Image.Size;
_state.Image.Save(stream, format);
}
else
{
using (Bitmap temp = new Bitmap(
_state.Image, size))
{
temp.Save(stream, format);
}
}

webcam.QueryFrameResponse response = new webcam.QueryFrameResponse();
response.TimeStamp = _state.LastFrameUpdate;
response.Frame = new byte[(int)stream.Length];
response.Size = size;
response.Format = format.Guid;

stream.Position = 0;
stream.Read(response.Frame, 0, response.Frame.Length);

query.ResponsePort.Post(response);
}
}
yield break;
}


JoshdeLeeuw at 2007-9-26 > top of Msdn Tech,Microsoft Robotics Studio,Microsoft Robotics - Community...

Microsoft Robotics Studio

Site Classified