Advertisement

Reading in a web cam for image acquisition

Started by June 08, 2004 04:27 PM
7 comments, last by CrunchDown 20 years, 5 months ago
Wonder if anybody knows how to do this. I heard it can be done using DirectPlay. Does anybody have any information about it, or know of a fairly simple way to do it. From what I hear, DirectX is quite alot of trouble. Will be coding a software eye that can convert images to 3d data Thanks in advance for help.
Not DirectPlay, the actual API is DirectShow. DirectPlay is DirectX''s answer to networking, and it is suprisingly intuitive. And actually, I have some experience with DirectShow in particualar and found it very easy to use. Direct3D is notoriously difficult, but it is very possible to only use the DirectShow api in conjunction with OpenGL (or some other program) After reading the tutorials for DirectShow, In under three hours I had a program that could take movie data imported through directshow Mpeg1/2/4/Avi filters (the filter manager can easily be configured to use a capture filter graph) and display it on an openGL textured quad. It isnt hard to do at all.



--------------------------------------

It took me long enough, but now I am finally 16. Yay! Sorta funny, but I am probably the only person on earth who wrote a 3D driving game prior to actually driving .
Advertisement
Thanks steve. Will look up some Direct Show tuts.
Here''s some horrible code that uses DirectShow to grab images from a webcam. I have a much neater version, but it''s split across multiple files so it''s not really possible to post here. Hopefully you''ll be able to figure out what''s going on here:
#define coCreateInstance(a, b, c) hResult = CoCreateInstance(CLSID_##a##, null, CLSCTX_INPROC_SERVER, IID_I##b##, (void**)&##c##);#define queryInterface(a, b, c) hResult = a##->QueryInterface(IID_I##b##, (void**)&##c##);<br><font color=green>#define</font> release(a) hResult = a##-&gt;Release();<br><br>const <font color=blue>class</font> Null<br>{<br><br>	<font color=blue>public</font>:<br><br>		<font color=blue>template</font> &lt;typename TYPE&gt;<br>		<font color=blue>operator</font> TYPE*() const<br>		{<br>			<font color=blue>return</font> 0;<br>		}<br><br>		<font color=blue>template</font> &lt;typename CLASS, typename TYPE&gt;<br>		<font color=blue>operator</font> TYPE CLASS::*() const<br>		{<br>			<font color=blue>return</font> 0;<br>		}<br><br>		<font color=blue>template</font> &lt;typename TYPE&gt;<br>		<font color=blue>friend</font> <font color=blue>bool</font> <font color=blue>operator</font>==(const TYPE* const t, const Null& n)<br>		{<br>			<font color=blue>return</font> t == (TYPE*)n;<br>		}<br><br>} null;<br><br><font color=blue>class</font> HResult<br>{<br><br>	<font color=blue>public</font>:<br><br>		HResult& <font color=blue>operator</font>=(HRESULT hr)<br>		{<br>			<font color=blue>if</font> (FAILED(hr))<br>			{<br>				std::cout &lt;&lt; <font color=darkred>"Error: "</font> &lt;&lt; (<font color=blue>unsigned</font> <font color=blue>int</font>)hr &lt;&lt; ''\n'';<br>				<font color=blue>if</font> (hr == S_OK)<br>				{<br>					std::cout &lt;&lt; <font color=darkred>"S_OK\n"</font>;<br>				}<br>				<font color=blue>if</font> (hr == VFW_S_PARTIAL_RENDER)<br>				{<br>					std::cout &lt;&lt; <font color=darkred>"VFW_S_PARTIAL_RENDER\n"</font>;<br>				}<br>				<font color=blue>if</font> (hr == E_ABORT)<br>				{<br>					std::cout &lt;&lt; <font color=darkred>"E_ABORT\n"</font>;<br>				}<br>				<font color=blue>if</font> (hr == E_POINTER)<br>				{<br>					std::cout &lt;&lt; <font color=darkred>"E_POINTER\n"</font>;<br>				}<br>				<font color=blue>if</font> (hr == VFW_E_CANNOT_CONNECT)<br>				{<br>					std::cout &lt;&lt; <font color=darkred>"VFW_E_CANNOT_CONNECT\n"</font>;<br>				}<br>				<font color=blue>if</font> (hr == VFW_E_NOT_IN_GRAPH)<br>				{<br>					std::cout &lt;&lt; <font color=darkred>"VFW_E_NOT_IN_GRAPH\n"</font>;<br>				}<br>				<font color=blue>throw</font> hr;<br>			}<br>			<font color=blue>return</font> *<font color=blue>this</font>;<br>		}<br><br>} hResult;<br><br><font color=blue>class</font> ComUninitialise<br>{<br><br>	<font color=blue>public</font>:<br><br>		<font color=blue>static</font> <font color=blue>void</font> inc();<br>		<font color=blue>static</font> <font color=blue>void</font> dec();<br><br>	<font color=blue>private</font>:<br><br>		<font color=blue>static</font> <font color=blue>int</font> c;<br><br>};<br><br><font color=blue>void</font> ComUninitialise::inc()<br>{<br>	c++;<br>}<br><br><font color=blue>void</font> ComUninitialise::dec()<br>{<br>	c--;<br>	<font color=blue>if</font> (c == 0)<br>	{<br>		CoUninitialize();<br>	}<br>}<br><br><font color=blue>int</font> ComUninitialise::c = 0;<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br><font color=blue>class</font> ComPointer<br>{<br><br>	<font color=blue>public</font>:<br><br>		ComPointer();<br>		ComPointer(COM_CLASS* comInterface);<br>		~ComPointer();<br>		ComPointer&lt;COM_CLASS&gt;& <font color=blue>operator</font>=(COM_CLASS* comInterface);<br>		COM_CLASS* <font color=blue>operator</font>-&gt;() const;<br>		<font color=blue>operator</font> COM_CLASS*() const;<br><br>	<font color=blue>private</font>:<br><br>		ComPointer(const ComPointer&lt;COM_CLASS&gt;& comInterface);<br>		ComPointer&lt;COM_CLASS&gt;& <font color=blue>operator</font>=(const ComPointer&lt;COM_CLASS&gt;& comInterface);<br><br>		COM_CLASS* i;<br><br>};<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br>ComPointer&lt;COM_CLASS&gt;::ComPointer()<br>	:<br>	i(null)<br>{<br>}<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br>ComPointer&lt;COM_CLASS&gt;::ComPointer(COM_CLASS* comInterface)<br>	:<br>	i(comInterface)<br>{<br>	ComUninitialise::inc();<br>}<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br>ComPointer&lt;COM_CLASS&gt;::~ComPointer()<br>{<br>	release(i);<br>	ComUninitialise::dec();<br>}<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br>ComPointer&lt;COM_CLASS&gt;& ComPointer&lt;COM_CLASS&gt;::<font color=blue>operator</font>=(COM_CLASS* comInterface)<br>{<br>	<font color=blue>if</font> (i)<br>	{<br>		release(i);<br>	}<br>	i = comInterface;<br>}<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br>COM_CLASS* ComPointer&lt;COM_CLASS&gt;::<font color=blue>operator</font>-&gt;() const<br>{<br>	<font color=blue>return</font> i;<br>}<br><br><font color=blue>template</font> &lt;typename COM_CLASS&gt;<br>ComPointer&lt;COM_CLASS&gt;::<font color=blue>operator</font> COM_CLASS*() const<br>{<br>	<font color=blue>return</font> i;<br>}<br><br>ComPointer&lt;IGraphBuilder&gt; graphBuilder;<br>ComPointer&lt;IBaseFilter&gt; sampleGrabberFilter;<br>ComPointer&lt;IBaseFilter&gt; nullRenderer;<br>ComPointer&lt;ISampleGrabber&gt; sampleGrabber;<br>ComPointer&lt;IMediaControl&gt; mediaControl;<br>ComPointer&lt;IMediaEvent&gt; mediaEvent;<br><font color=blue>long</font> sizeBuffer = 0;<br><font color=blue>unsigned</font> <font color=blue>char</font>* pBuffer;<br><br><font color=blue>void</font> setup()<br>{<br>	hResult = CoInitialize(null);<br>	coCreateInstance(FilterGraph, GraphBuilder, graphBuilder);<br>	coCreateInstance(SampleGrabber, BaseFilter, sampleGrabberFilter);<br>	queryInterface(sampleGrabberFilter, SampleGrabber, sampleGrabber);<br>	coCreateInstance(NullRenderer, BaseFilter, nullRenderer);<br>	hResult = graphBuilder-&gt;AddFilter(nullRenderer, L<font color=darkred>"Null Renderer"</font>);<br>	AM_MEDIA_TYPE mt;<br>	ZeroMemory(&mt, <font color=blue>sizeof</font>(AM_MEDIA_TYPE));<br>	mt.majortype = MEDIATYPE_Video;<br>	mt.subtype = MEDIASUBTYPE_RGB24;<br>	hResult = sampleGrabber-&gt;SetMediaType(&mt);<br>	hResult = graphBuilder-&gt;AddFilter(sampleGrabberFilter, L<font color=darkred>"Sample Grabber"</font>);<br>	ICreateDevEnum* deviceEnumeratorCreator;<br>	coCreateInstance(SystemDeviceEnum, CreateDevEnum, deviceEnumeratorCreator);<br>	IEnumMoniker* deviceEnumerator;<br>	hResult = deviceEnumeratorCreator-&gt;CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &deviceEnumerator, 0);<br>	IMoniker* moniker = null;<br>	IBaseFilter* filter;<br>	<font color=blue>while</font> (deviceEnumerator-&gt;Next(1, &moniker, null) == S_OK)<br>	{<br>		IPropertyBag* propertyBag;<br>		<font color=blue>try</font><br>		{<br>			hResult = moniker-&gt;BindToStorage(0, 0, IID_IPropertyBag, (<font color=blue>void</font>**)&propertyBag);<br>			<font color=blue>try</font><br>			{<br>				VARIANT variantName;<br>				VariantInit(&variantName);<br>				<font color=blue>try</font><br>				{<br>					hResult = propertyBag-&gt;Read(L<font color=darkred>"Description"</font>, &variantName, 0);<br>				}<br>				<font color=blue>catch</font> (HRESULT)<br>				{<br>					hResult = propertyBag-&gt;Read(L<font color=darkred>"FriendlyName"</font>, &variantName, 0);<br>				}<br>				USES_CONVERSION;<br>				VariantClear(&variantName);<br>				hResult = moniker-&gt;BindToObject(0, 0, IID_IBaseFilter, (<font color=blue>void</font>**)&filter);<br>				<font color=blue>while</font>(deviceEnumerator-&gt;Next(1, &moniker, null) == S_OK)<br>				{<br>				}<br>			}<br>			<font color=blue>catch</font> (HRESULT hr)<br>			{<br>			}<br>			release(propertyBag);<br>		}<br>		<font color=blue>catch</font> (HRESULT hr)<br>		{<br>		}<br>		release(moniker);<br>	}<br>	release(deviceEnumerator);<br>	release(deviceEnumeratorCreator);<br>	hResult = graphBuilder-&gt;AddFilter(filter, L<font color=darkred>"Capture Filter"</font>);<br>	IEnumPins* pEnum;<br>	filter-&gt;EnumPins(&pEnum);<br>	IPin* pCameraOutput;<br>	IPin* pGrabberInput;<br>	IPin* pGrabberOutput;<br>	IPin* pNullInputPin;<br>	<br>	hResult = pEnum-&gt;Reset();<br>	hResult = pEnum-&gt;Next(1, &pCameraOutput, NULL); <br><br>	release(pEnum);<br>	pEnum = NULL; <br>	sampleGrabberFilter-&gt;EnumPins(&pEnum);<br>	pEnum-&gt;Reset();<br>	hResult = pEnum-&gt;Next(1, &pGrabberInput, NULL); <br>	release(pEnum);<br>	pEnum = NULL;<br>	sampleGrabberFilter-&gt;EnumPins(&pEnum);<br>	pEnum-&gt;Reset();<br>	pEnum-&gt;Skip(1);<br>	hResult = pEnum-&gt;Next(1, &pGrabberOutput, NULL); <br><br><br>	release(pEnum);<br>	pEnum = NULL;<br>	nullRenderer-&gt;EnumPins(&pEnum);<br>	pEnum-&gt;Reset();<br>	hResult = pEnum-&gt;Next(1, &pNullInputPin, NULL);<br>	hResult = graphBuilder-&gt;Connect(pCameraOutput, pGrabberInput);<br><br>	hResult = graphBuilder-&gt;Connect(pGrabberOutput, pNullInputPin);<br>	release(filter);<br>	queryInterface(graphBuilder, MediaControl, mediaControl);<br>	queryInterface(graphBuilder, MediaEvent, mediaEvent);<br>	hResult = sampleGrabber-&gt;SetBufferSamples(TRUE);<br>	hResult = sampleGrabber-&gt;SetOneShot(TRUE);<br>	hResult = mediaControl-&gt;Run();<br>	<font color=blue>long</font> eventCode = 0;<br>	hResult = mediaEvent-&gt;WaitForCompletion(INFINITE, &eventCode);<br>	sizeBuffer = 0;<br>	hResult = sampleGrabber-&gt;GetCurrentBuffer(&sizeBuffer, NULL);<br>	pBuffer = <font color=blue>new</font> <font color=blue>unsigned</font> <font color=blue>char</font>[<font color=purple>sizeBuffer</font>];<br>	lastFrame = null;<br>	<font color=blue>if</font> (!pBuffer) <br>	{<br>		std::cerr &lt;&lt; <font color=darkred>"Failed\n"</font>;<br>		std::exit(-1);<br>	}<br>	release(pEnum);<br>	release(pCameraOutput);<br>	release(pGrabberInput);<br>	release(pGrabberOutput);<br>	release(pNullInputPin);<br>}<br><br><font color=blue>void</font> grabFrame()<br>{<br>	hResult = sampleGrabber-&gt;GetCurrentBuffer(&sizeBuffer, (<font color=blue>long</font>*)pBuffer);<br>}</pre><!--ENDSCRIPT--><br><br>Enigma   
I have a fairly clean API that will do this for you, but using VFW rather than DirectShow. Email me if you still need it

www.coldcity.com
code, pics, life
[size="2"]www.coldcity.com code, art, life
Uh looks like your emails not working IanC. Could you email me the source at shawn__sch@hotmail.com? Really appreciate it.

I'm sure not having an easy time with COM objects with Direct Show.

[edited by - Crunchdown on June 13, 2004 7:40:38 PM]
Advertisement
Hi Shawn,

Sorry mate, wasn't checking thread - got yr email, just zipping it up for you now :)

I.
[size="2"]www.coldcity.com code, art, life
This might be of interest: click.
Eh be sure to send that once it's zipped, too. Thanks for the link it was a good one.

This topic is closed to new replies.

Advertisement