Tuesday 14 August 2007

Camera Automation with PowerShell Part II

Camera Automation with PowerShell Part II

We left off yesterday with most of the basic parts for a first run test for our Camera Automation script. I realise now that Blogger has really torn into my code snippets and removed all indentation which makes some of them look pretty bad. I'm trying to figure it out but my first serious attempt (editing the raw HTML and blocking the snippets out with < code >...< /code > tags) didn't work. Suggestions appreciated as
today's post is going to have the same problem for now.

Anyway let's stick the bits we had figured out together and see what we come up with.


First off we need to initialize the camera, locate the command for taking a picture, set up a working directory and a some variables.

$WIAManager = new-object-comobject WIA.DeviceManager
$DeviceList = $WIAManager.DeviceInfos
foreach ($item in $DeviceList) {
$Device=$item
}
$ConnectedDevice = $Device.connect()
$Commands = $ConnectedDevice.Commands
foreach ($item in $Commands) {
if ($item.name -match "take") {
$TakeShot=$x.CommandID
}
}
$Sensitivity=1000
$Pdir="C:\temp\capture\test"
New-Item $Pdir -itemtype dir -ea silentlycontinue
$IConvert="c:\Program Files\ImageMagick-6.3.5-Q16\convert.exe"

The only thing new here is the "New-Item -itemtype dir" command which creates a new sub-directory. The -ea tag sets the Error Action for the command so that we don't display an error if the directory already exists.

The initial approach we're going to take is to set up a basic loop within which we will:
  • Keep a copy of the last picture we took so we can compare it to the new one
  • Take a new picture and pull it back from the camera
  • Compare the new image to the old one
So a quick and dirty version looks like this:

$SaveCount=0;
for ($stage=0;$stage -lt 10;$stage++) {
# Keep a copy of the last picture
rename-item -force "$Pdir\picture.jpg" "lastpicture.jpg" -ea silentlycontinue
# Take a picture, find it, copy it from the camera and then save it
$f=$arg.ExecuteCommand($TakeShot)
# Select the last item in the item(image) collection on the camera
$f=$arg.items.item($arg.items.Count)
$fg=$f.Transfer()
$fg.SaveFile("$Pdir\picture.jpg")
# Compare the two pictures
$compare=& $ICompare -metric MEPP "$Pdir\lastpicture.jpg" "$Pdir\picture.jpg" null: 2>&1
# Pull the exact value we need from the output
if ($compare -match "(\d+)(\.|\s)") { $result=$matches[1] }
# If the Compare result is higher than some value then save a copy of the file
if ($result -gt $Sensitivity) {
copy-item "$Pdir\picture.jpg" "$Pdir\$SaveCount-$result-picture.jpg"
Write "Saving interesting picture: $Pdir\$SaveCount-$result-picture.jpg"
$SaveCount++
}
# Tidy up the image store on the camera
$arg.items.Remove($arg.items.Count)
}

We now have a basic script that we can use to test the principle of the thing. In testing it works some\most of the time but there are lots of things that can go wrong and we've put in absolutely no error handling.

For the next stage we'll improve the image comparison baseline by taking an average of a number of images and add in better error handling both up front (to handle cases where there is no camera or the camera connected isn't suitable) and during shooting so that we don't get caught out when the camera can't take a shot for one reason or another.

And hopefully some better code sample layout.

* Edited to fix the code snippets

1 comment:

Ithiad said...

Nonbreaking spaces should handle the indents.