HowTo: Use a Webcam and PC as a Magic Mirror - Part 1
Novell Cool Solutions: Feature
By Stomfi
Digg This -
Slashdot This
Posted: 27 Oct 2005 |
![]() |
![]() Welcome to my ongoing series of HowTo articles designed to help Linux newbies get comfortable with Linux. Before trying any of these HowTos, take a few minutes to study the prerequisites so you can hit the ground running. --Stomfi |
This HowTo describes a system which can be used at home and in shops to retain several views of an object or person, so that comparisons can be made between them on a computer screen. The incentive for this system was that when trying on new spectacle frames, I could not see what they really looked like. I realised that because the computer can remember several views, that many other uses where one would like to pick the best of several choices, could be an advantage for all sorts of things in the home and in shops, so I decided to create such a system using the shell, Runtime Revolution, a camera, and some picture grabbing and saving software. I have called it the "magic mirror" and I would like you to do the same if you make one.
As the inventor of this system I state that any patents arising from the description and methods described in this two part article are to be assigned by any and all developers to the Patent Commons held at the Open Source Development Laboratories for the common good.
This is a summary of the patent description for the systems described in this article. A combination of the following mechanisms assembled in such a fashion as to achieve picture grabbing, viewing and printing for the purpose of selecting a wearable product.- Any camera device that can supply a digitally downloadable picture within approximately 10 seconds of a remote button press.
- Any mirror or screen that can adequately display a suitable reflection of the user or users.
- Software and electronic display system that can display a viewable selection of down loaded pictures from the camera device, and associated control procedures that can display and mirror a single large picture of one of the selection, and enable the any or all of the displayed pictures to be printed, saved or transferred by electronic means to facilitate viewing by third parties.
- Software that can print, save and electronically transfer any or all of the displayed pictures.
The instance of the system described here I have named IKEAM, sort of a play on words, as it can be built from pre manufactured parts by the DIY enthusiast.
I started writing this how to back in December last year, but had to put it aside as finding Linux drivers for web cameras one could buy in retail stores in Australia was a non event. In less than one year the situation has changed quite dramatically. There are now drivers for all sorts of add on peripherals, from web cameras to wifi cards. We have to thank the Linux development community, and the chip manufacturers who are actively helping them, as well as the lobbying by distribution companies like SUSE, who want us to have a better desktop experience.
Because it is supposed to be more fun, we'll create this system bottom up, instead of top down, so the first thing we'll develop is the Runtime Revolution GUI interface. See www.runrev.com. I will use RunRev 2.2.1 for this development. I suggest you use the GNOME window manager when you log in, as I have found that there are a few interface issues with KDE 3.x.
Runtime Revolution recently sent me these links where you can get lots of examples about using their products, although not too much on Linux, so if you are a user and have some hints, send them a link.
http://support.runrev.com/useful_sites.php
Maybe revjournal would be a good one, SoSmart is good, as is Sons of Thunder. They have a new add on library which works on 2.2.1 and above, called arcade which is worth checking out if you like creating games and dynamic movement. I am going to play with it and make you a whiz bang how to in the near future.
You know the drill to start off a RunRev project. Create a folder in your home directory called IKEAM, create some sub folders called "bin", "bin/develop", "info", "pics", "tmp". "bin/develop" is where you will save the RunRev development file "IKEAM.rev". Start up RunRev and make a new stack. stretch the window to suit your preferred display size. I'd settle on 800x600 as the size of a large web cam picture is likely to be best at 640x480, and we need a bit of room for buttons, instructions and the like.
This is the picture layout. Either a large single picture is shown or up to 6 collected ones are tiled. Clicking the drop down menu allows the user to select one of 6 pictures to view this size, or up to 6 pictures at once. More than this is too hard to see and too hard to choose on from for the average person. The MIRROR button allows the user to horizontally flip the large picture so the magic mirror can show both what a mirror reflects or what others see when they are looking at you. This button only appears in the large picture mode.



These are pictures of some of my shell hacker guests from out of town after a long session at the screen.
The tiled pictures should be the same ratio as the large picture, which should be the same ratio as the one from your digital web camera.
Create the large image first and label it PIC1, create image PIC2 on the top left to be 1/6 of the area of image PIC1. Create the other five images by copying image PIC1 and relabelling them as image PIC3 to PIC7. Create the Picture Selector pull down menu to show 7 items which are "ALL" and "1" through to "6" , and the CLEAR and MIRROR buttons.
These are the scripts for the stack, card, and objects. You create the script by right clicking the object or a blank window area of the part you want, then choose Edit Card Script, or Edit Object Script from the pop up menu as shown here.

The property inspector allows you to modify the objects name and as in this application the Lock Position & Size parameter.
This is the stack script which set the card in the condition it needs to be at the start. Image 1 is the large picture which appears and disappears by using the Picture Selector menu after some pictures have been saved. All the gif pictures are the same here but it would be more cognitive for the use if the message mentioned the picture number associated with the button to press in this example. Of course you could use a single button and add one to each picture number as it was pressed in the grabbing and saving section, reverting back to 1 after 6 is reached in this layout. The file "grabpic.sh" contains the shell command to grab and save the pictures.
on openStack #Hide and lower Image 1 set the invisible of image 1 to true set the layer of image 1 to bottom #Hide and show buttons set the invisible of button "MIRROR" to true set the invisible of button "CLEAR" to false #Load the instruction pictures set the filename of image "PIC1" to ($HOME & "/IKEAM/pics/file1.gif") set the filename of image "PIC2" to ($HOME & "/IKEAM/pics/file2.gif") set the filename of image "PIC3" to ($HOME & "/IKEAM/pics/file3.gif") set the filename of image "PIC4" to ($HOME & "/IKEAM/pics/file4.gif") set the filename of image "PIC5" to ($HOME & "/IKEAM/pics/file5.gif") set the filename of image "PIC6" to ($HOME & "/IKEAM/pics/file6.gif") set the filename of image "PIC7" to ($HOME & "/IKEAM/pics/file7.gif") #Delete the old jpegs put ("rm -f" && $HOME & "/IKEAM/tmp/*") into DUDEL replace return with empty in DUDEL put the shell of DUDEL into DUNDEL #Set up a global picture grab process global OGRAB put ($HOME & "/IKEAM/bin/grabpic.sh") into OGRAB end openStack
This is the card script which responds to key presses. The "ikeam" field is for messages and debugging. It is useful for displaying the key numbers, and help with the time taken to grab a picture.
The time the system, including the camera and grabbing software, takes to save the picture after the button is pressed, is called latency. On my system it is about 4 to 5 seconds with a 640x480 jpeg which means I have to remain in place for that long after I press the button (Or I can dance round the room for 3 seconds, arriving back in time for the picture). Reducing the picture size can reduce latency as this reduces the time taken to scan in the picture.
Modern digital cameras have solved this problem, but you have to find one with a remote control and USB instant download cable. Or you could design and build a mechanical relay switch which will physically press the shutter button powered from your serial port or a 9 volt battery. The possibilities are there.
The three key numbers are: the numbers above the "qwerty" keys, the keypad with the numlock on and off.
The if statements set the PressedThis holder and the switch loop decides which action to take. There are some messages for KEY1 which can be copied into the other KEY actions. You can change these to suit. Notice that although it takes a few seconds to actually take the picture, when it does do it, it is reasonably fast so small movements don't matter.
on rawKeyDown ThisKey #Return number of key for debugging put ThisKey into field "ikeam" global OGRAB #set all number key possibilities #set PressedKey to something else put "KEY0" into PressedKey if ThisKey = "49" or ThisKey = "65457" or ThisKey = "65436" then put "KEY1" into PressedThis end if if ThisKey = "50" or ThisKey = "65458" or ThisKey = "65433" then put "KEY2" into PressedThis end if if ThisKey = "51" or ThisKey = "65459" or ThisKey = "65435" then put "KEY3" into PressedThis end if if ThisKey = "52" or ThisKey = "65460" or ThisKey = "65430" then put "KEY4" into PressedThis end if if ThisKey = "53" or ThisKey = "65461" or ThisKey = "65437" then put "KEY5" into PressedThis end if if ThisKey = "54" or ThisKey = "65462" or ThisKey = "65432" then put "KEY6" into PressedThis end if if ThisKey = "45" or ThisKey = "65453" then #The minus key was pressed put "MMCLEAR" into PressedThis end if #Make sure the small pictures are on top set the invisible of image "PIC1" to true set the layer of image "PIC1" to bottom #Do the grab and display #Return activity message for debug timing switch PressedThis case "KEY1" put (OGRAB && "2") into PGRAB put "Grabbing Picture" into field "ikeam" put the shell of PGRAB into DUNGRAB set the invisible of image "PIC2" to false set the filename of image "PIC2" to empty set the filename of image "PIC2" to ($HOME & "/IKEAM/tmp/file2.jpg") put "Picture Displayed" into field "ikeam" break case "KEY2" put (OGRAB && "3") into PGRAB put the shell of PGRAB into DUNGRAB set the invisible of image "PIC3" to false set the filename of image "PIC3" to empty set the filename of image "PIC3" to ($HOME & "/IKEAM/tmp/file3.jpg") break case "KEY3" put (OGRAB && "4") into PGRAB put the shell of PGRAB into DUNGRAB set the invisible of image "PIC4" to false set the filename of image "PIC4" to empty set the filename of image "PIC4" to ($HOME & "/IKEAM/tmp/file4.jpg") break case "KEY4" put (OGRAB && "5") into PGRAB put the shell of PGRAB into DUNGRAB set the invisible of image "PIC5" to false set the filename of image "PIC5" to empty set the filename of image "PIC5" to ($HOME & "/IKEAM/tmp/file5.jpg") break case "KEY5" put (OGRAB && "6") into PGRAB put the shell of PGRAB into DUNGRAB set the invisible of image "PIC6" to false set the filename of image "PIC6" to empty set the filename of image "PIC6" to ($HOME & "/IKEAM/tmp/file6.jpg") break case "KEY6" put (OGRAB && "7") into PGRAB put the shell of PGRAB into DUNGRAB set the invisible of image "PIC7" to false set the filename of image "PIC7" to empty set the filename of image "PIC7" to ($HOME & "/IKEAM/tmp/file7.jpg") break case "MMCLEAR" put "Clearing saved Pictures" into field "ikeam" #Load the instruction pictures set the filename of image "PIC1" to ($HOME & "/IKEAM/pics/file1.gif") set the filename of image "PIC2" to ($HOME & "/IKEAM/pics/file2.gif") set the filename of image "PIC3" to ($HOME & "/IKEAM/pics/file3.gif") set the filename of image "PIC4" to ($HOME & "/IKEAM/pics/file4.gif") set the filename of image "PIC5" to ($HOME & "/IKEAM/pics/file5.gif") set the filename of image "PIC6" to ($HOME & "/IKEAM/pics/file6.gif") set the filename of image "PIC7" to ($HOME & "/IKEAM/pics/file7.gif") #Delete the old jpegs put ("rm -f" && $HOME & "/IKEAM/tmp/*") into DODEL replace return with empty in DODEL put the shell of DUDEL into DUNDEL break end switch end rawKeyDown
The global OGRAB contains the line which executes "grabpic.sh" which I'll explain in part 2 of this article.
This next script controls what happens when a menu item is selected from the Picture Select drop down menu.
Mostly it is changing the invisible state of objects and whether the large picture is at the top or bottom of the layers. The global PPAGE is used to tell the PRINT button what to display.
on menuPick thisItem global PPAGE switch thisItem case "ALL" put "S" into PPAGE set the invisible of image "PIC1" to true set the invisible of button "MIRROR" to true set the invisible of button "CLEAR" to false set the layer of image "PIC1" to bottom break case "1" put "L" into PPAGE put the filename of image "PIC2" into PicFile set the invisible of image "PIC1" to true set the layer of image "PIC1" to top set the filename of image "PIC1" to PicFile set the invisible of image "PIC1" to false set the invisible of button "MIRROR" to false set the invisible of button "CLEAR" to true break case "2" put "L" into PPAGE put the filename of image "PIC3" into PicFile set the invisible of image "PIC1" to true set the layer of image "PIC1" to top set the filename of image "PIC1" to PicFile set the invisible of image "PIC1" to false set the invisible of button "MIRROR" to false set the invisible of button "CLEAR" to true break case "3" put "L" into PPAGE put the filename of image "PIC4" into PicFile set the invisible of image "PIC1" to true set the layer of image "PIC1" to top set the filename of image "PIC1" to PicFile set the invisible of image "PIC1" to false set the invisible of button "MIRROR" to false set the invisible of button "CLEAR" to true break case "4" put "L" into PPAGE put the filename of image "PIC5" into PicFile set the invisible of image "PIC1" to true set the layer of image "PIC1" to top set the filename of image "PIC1" to PicFile set the invisible of image "PIC1" to false set the invisible of button "MIRROR" to false set the invisible of button "CLEAR" to true break case "5" put "L" into PPAGE put the filename of image "PIC6" into PicFile set the invisible of image "PIC1" to true set the layer of image "PIC1" to top set the filename of image "PIC1" to PicFile set the invisible of image "PIC1" to false set the invisible of button "MIRROR" to false set the invisible of button "CLEAR" to true break case "6" put "L" into PPAGE put the filename of image "PIC7" into PicFile set the invisible of image "PIC1" to true set the layer of image "PIC1" to top set the filename of image "PIC1" to PicFile set the invisible of image "PIC1" to false set the invisible of button "MIRROR" to false set the invisible of button "CLEAR" to true break end switch end menuPick
Each case ends in a "break" otherwise the next lot of statements might be performed.
The drop down menu, the buttons, and the images are all found in the objects menu in the RunRev main bar.
This is the CLEAR button script. This bit of script appears three times in various places you will notice.
on mouseUp #Hide and lower Image 1 set the invisible of image "PIC1" to true set the layer of image "PIC1" to bottom #Hide and show buttons set the invisible of button "MIRROR" to true set the invisible of button "CLEAR" to false #Load the instruction pictures set the filename of image "PIC1" to ($HOME & "/IKEAM/pics/file1.gif") set the filename of image "PIC2" to ($HOME & "/IKEAM/pics/file2.gif") set the filename of image "PIC3" to ($HOME & "/IKEAM/pics/file3.gif") set the filename of image "PIC4" to ($HOME & "/IKEAM/pics/file4.gif") set the filename of image "PIC5" to ($HOME & "/IKEAM/pics/file5.gif") set the filename of image "PIC6" to ($HOME & "/IKEAM/pics/file6.gif") set the filename of image "PIC7" to ($HOME & "/IKEAM/pics/file7.gif") #Delete the old jpegs put ("rm -f" && $HOME & "/IKEAM/tmp/*") into DODEL replace return with empty in DODEL put the shell of DUDEL into DUNDEL end mouseUp
This is the PRINT button script which launches the Linux "gthumb" application. I chose this one as it will automagically set up the print layout for several images on one page. You will have to set it to print 8 to a page to get all six.
on mouseUp #Print current displayed picture/s put "Using Gthumb to print pictures" into field "ikeam" global PPAGE if PPAGE = "L" then #Print single large jpeg picture put the filename of image "PIC1" into PPIC launch PPIC with "gthumb" else #print requested current jpeg pictures 2 to 6 in tmp folder if any are there put ("ls" && $HOME & "/IKEAM/tmp") into DOTSUM replace return with empty in DUSUM put the shell of DUSUM into GOTSUM if GOTSUM <> "" then put ("gthumb" && $HOME & "/IKEAM/tmp/*") into PPICS replace return with empty in PPICS put "Click Catalog in Gthumb, Select all Pics, Click File - Print" into field "ikeam" put the shell of PPICS into DUNPRINT else put "No pictures to Print" into field "ikeam" end if end if end mouseUp
This is the MIRROR button script:
on mouseUp flip image "PIC1" horizontal #Using this function turns on the paint tool, so reset to browse tool choose browse tool end mouseUp
Nice and simple really.
This is a picture of the card elements showing you the names of everything. I have also put in tooltips on the buttons to aid the user. The keyboard could be used with the rawKeyDown function to perform more activities, but in a shop situation where expenses need to be monitored, it maybe better to have an assistant in control of mouse activity for printing, and the two other functions I haven't implemented on this example which are saving on a floppy, pen drive or CD and electronically transferring via email or FTP.

When you have it all finished the layout could look something like this:

Use the property settings to lock the size and position of all your fields especially the images otherwise the small one will resize to the actual size when you grab them.

I think that it is wonderful that Linux and RunRev has made such simple easy to apply tools that a non programmer like me can use to put an idea into practice in such a short time and get such a professional result.
Three cheers to all involved.
This is the end of part one of this HowTo. In the next part we shall look at web cameras and their software. How the camera will work and what practical requirements must be met to make sure the system is usable.

Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com