{"id":126,"date":"2009-09-03T18:14:28","date_gmt":"2009-09-03T23:14:28","guid":{"rendered":"http:\/\/blogs.cae.tntech.edu\/mwr\/?p=126"},"modified":"2024-10-27T14:26:19","modified_gmt":"2024-10-27T14:26:19","slug":"capturing-an-image-from-a-wia-compatible-digital-camera","status":"publish","type":"post","link":"https:\/\/sites.tntech.edu\/renfro\/2009\/09\/03\/capturing-an-image-from-a-wia-compatible-digital-camera\/","title":{"rendered":"Capturing an Image from a WIA-compatible Digital Camera"},"content":{"rendered":"<p>We&#8217;ve had a research project requiring a fair amount of image acquisition and processing, requiring\u00a0 higher resolutions than most industrial cameras can offer. As a result, we&#8217;ve tried at least three different digital cameras (Canon PowerShot S3is, Nikon D40, and Canon PowerShot SD780is). Each of them has their own advantages and disadvantages:<\/p>\n<ul>\n<li>S3is advantages:\u00a0 good control with Breezesys&#8217; PSRemote, including a pretty complete DLL that we can call from our LabVIEW code. Disadvantages: larger aperture sizes reduce the depth of field, and PSRemote can&#8217;t toggle macro and super-macro modes.<\/li>\n<li>D40 advantages: complete manual control when needed, huge range of apertures including ones that allow for good depth of field, easy to grab pictures in PTP mode from Windows Explorer. Disadvantages: Breezesys&#8217; NKRemote for Nikon doesn&#8217;t support the D40.<\/li>\n<li>SD780is advantages: ridiculously high resolution (12MP) in a tiny camera. Disadvantages: no PSRemote support, and little manual control of settings.<\/li>\n<\/ul>\n<p>So it came down to needing LabVIEW to acquire images from whatever camera automatically. We had gotten it working with PSRemote some time back for a different class of pictures, but the ones we needed now went beyond PSRemote&#8217;s and the S3is&#8217; ability to focus in on close distances. And the SD780is was out entirely. So that left the Nikon.<\/p>\n<p>Previous testing with the Nikon generally consisted of putting it in PTP mode, opening up Windows Explorer, hitting the &#8220;Take a new picture&#8221; link, and then copying over the newest image to the local drive. Great, except for the clicking and dragging. The obvious solution would be to automate the process via Win32 COM programming. After a few hours with the Python docs and MSDN, a workable Python script was born:<\/p>\n<pre>import win32com.client, time, os\n\nWIA_COM = \"WIA.CommonDialog\"\n\nWIA_DEVICE_UNSPECIFIED = 0\nWIA_DEVICE_CAMERA = 2\n\nWIA_INTENT_UNSPECIFIED = 0\n\nWIA_BIAS_MIN_SIZE = 65536\nWIA_BIAS_MAX_QUALITY = 131072\n\nWIA_IMG_FORMAT_PNG = \"{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}\"\n\nWIA_COMMAND_TAKE_PICTURE=\"{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}\"\n\ndef acquire_image_wia():\n    wia = win32com.client.Dispatch(WIA_COM) # wia is a CommonDialog object\n    dev = wia.ShowSelectDevice()\n    for command in dev.Commands:\n        if command.CommandID==WIA_COMMAND_TAKE_PICTURE:\n            foo=dev.ExecuteCommand(WIA_COMMAND_TAKE_PICTURE)\n\n    i=1\n    for item in dev.Items:\n        if i==dev.Items.Count:\n            image=item.Transfer(WIA_IMG_FORMAT_PNG)\n            break\n        i=i+1\n\n    fname = 'wia-test.jpg'\n    if os.path.exists(fname):\n        os.remove(fname)\n    image.SaveFile(fname)\n\nos.chdir('c:\/temp')\nacquire_image_wia()<\/pre>\n<p>Things I like about this:<\/p>\n<ul>\n<li>snaps the camera shutter, grabs the last image from the card, and stashes it on the local drive, no questions asked. Since I&#8217;ll probably set the camera settings once and leave it on manual focus, this is all I needed.<\/li>\n<li>easily converted into an executable with py2exe.<\/li>\n<li>roughly 3.2 seconds to acquire and save the image, with around 2 seconds of that spent on the ExecuteCommand() line with a 0.25 second shutter speed.<\/li>\n<\/ul>\n<p>Things I don&#8217;t like about this:<\/p>\n<ul>\n<li>Windows COM programming makes my brain hurt.<\/li>\n<li>To make things entirely hands-off, I had to disable my Webcam. I&#8217;m sure there&#8217;s a way to make WIA connect to a named device, but ShowSelectDevice() was all I found ready documentation for. With multiple cameras available, it always asked which one I wanted to acquire from. With only one camera available, it just went on and snapped the picture.<\/li>\n<li>I couldn&#8217;t find a good way of jumping to the end of the list of items stored on the camera. I can count them, I can iterate over them, but I&#8217;m having to iterate over each element until I get to the last one, and <strong>then<\/strong> I can transfer it over.<\/li>\n<\/ul>\n<p>Someone may have a better solution to the last two problems, but this should get people started.<\/p>\n<p><strong>Update<\/strong> &#8212; Leaner, meaner code to grab the last image off one specified camera &#8212; thanks to Janzert in the comments below:<\/p>\n<pre>import win32com.client, time, os\n\nMY_CAMERA=\"D40\"\nWIA_IMG_FORMAT_PNG = \"{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}\"\nWIA_COMMAND_TAKE_PICTURE=\"{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}\"\n\ndef acquire_image_wia():\n    # Find the camera\n    devman=win32com.client.Dispatch(\"WIA.DeviceManager\")\n    for info in devman.DeviceInfos:\n        for prop in info.Properties:\n            if prop.Name==\"Name\" and prop.Value==MY_CAMERA:\n                dev = info.Connect()\n\n    # Snap picture\n    foo=dev.ExecuteCommand(WIA_COMMAND_TAKE_PICTURE)\n    # Transfer last image (doesn't actually use PNG format, but this\n    # still is valid syntax).\n    image=dev.Items[dev.Items.count].Transfer(WIA_IMG_FORMAT_PNG)\n    # Save into file\n    fname = 'wia-test.jpg'\n    if os.path.exists(fname):\n        os.remove(fname)\n    image.SaveFile(fname)\n\nos.chdir('c:\/temp')\nacquire_image_wia()<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;ve had a research project requiring a fair amount of image acquisition and processing, requiring\u00a0 higher resolutions than most industrial cameras can offer. As a result, we&#8217;ve tried at least three different digital cameras (Canon PowerShot S3is, Nikon D40, and Canon PowerShot SD780is). Each of them has their own advantages and disadvantages: S3is advantages:\u00a0 good &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/sites.tntech.edu\/renfro\/2009\/09\/03\/capturing-an-image-from-a-wia-compatible-digital-camera\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Capturing an Image from a WIA-compatible Digital Camera&#8221;<\/span><\/a><\/p>\n","protected":false},"author":87,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-126","post","type-post","status-publish","format-standard","hentry","category-python","entry"],"_links":{"self":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts\/126","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/comments?post=126"}],"version-history":[{"count":1,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts\/126\/revisions"}],"predecessor-version":[{"id":450,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/posts\/126\/revisions\/450"}],"wp:attachment":[{"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/media?parent=126"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/categories?post=126"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sites.tntech.edu\/renfro\/wp-json\/wp\/v2\/tags?post=126"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}