<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9102179255330637934</id><updated>2011-12-14T00:57:09.048-08:00</updated><category term='weave'/><category term='matplotlib'/><category term='HITLAB'/><category term='plans'/><category term='Microsoft'/><category term='pycam'/><category term='gentoo'/><category term='ibook G4'/><category term='pylab'/><category term='harris'/><category term='im'/><category term='UI'/><category term='projects'/><category term='IDE'/><category term='C++'/><category term='AR'/><category term='fixed point'/><category term='python'/><category term='scipy'/><category term='animation'/><category term='mechanics'/><category term='windows'/><category term='Spyder'/><category term='OpenEyes'/><category term='wxWidgets'/><category term='linux'/><category term='paper'/><category term='facebook'/><category term='procrastinot'/><category term='scipy-sim'/><category term='opencv'/><category term='engineering'/><category term='facebook connect'/><category term='xo'/><category term='syntax highlighting'/><category term='googlecode'/><category term='django'/><category term='game'/><category term='Python3'/><category term='thread'/><category term='signals'/><category term='facedetection'/><category term='matlab'/><category term='vibration'/><category term='wikipedia'/><category term='socket'/><category term='numpy'/><category term='uni'/><category term='blogger'/><category term='computer vision'/><category term='appengine'/><category term='imap'/><category term='ppc'/><category term='pygame'/><category term='machine learning'/><category term='UCCC'/><category term='Learning Games'/><category term='gmail'/><category term='kiwipycon'/><category term='Opensource Interface'/><title type='text'>Brian's Python Dev Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-3144777491495181926</id><published>2011-06-19T01:53:00.000-07:00</published><updated>2011-06-19T01:53:18.546-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Dear HP &amp; Microsoft - you're doing it wrong</title><content type='html'>So I got a new computer last week, of course after a day or so decided that I might want to do some work on it in which case I'd would prefer to have Ubuntu installed. I've never had too much trouble setting up a dual boot systems in the past; notable setups I've had include Gentoo/OSX, Ubuntu/XP and Ubuntu/Mint/XP/7.&lt;br /&gt;&lt;br /&gt;So I got a brand new HP Pavilion with Windows 7 Home Premium pre-installed. It was nicely set up, had pretty much the latest drivers and if I was just wanting to live in a Windows 7 box things would have been sweet. I realize that most people fit in this category, but still not impressed with what follows. As laptops tend to these days the machine didn't come with any optical media for drivers or operating systems, instead there was a recovery partition taking up a 25GB hidden partition of my hard drive. This is fine. Perhaps an option to burn an installer DVD when you first turn it on would be a good option though.&lt;br /&gt;&lt;br /&gt;I booted from a Ubuntu live USB and resized the Windows partition and installed Ubuntu 11.04. I missed the fact that Windows wasn't residing on a normal NTFS partition, I found out later that it was a "dynamic disk", resizing seemed to throw Windows in a violent way. Ubuntu installed the bootloader grub2 and listed Windows 7, Windows Recovery Environment and of course itself. I tried booting into Windows and it blue screened on me, same for safe mode and every option I could try. I booted into Ubuntu (which of course worked) and read forums and blogs to learn what had happened. Eventually I found that I should be able to recover the full partition structure with TestDisk, I couldn't really write a new Partition structure while running an OS from the partition I wanted to edit so I booted up Ubuntu live again and ran TestDisk to restore the original partition structure - effectively changing the index and deleting my existing Ubuntu installation in order to try get back into Windows 7. Sadly that didn't work, except to remove ubuntu and grub. The HP bios software has a link to "System Recovery" so I tried booting into that, for some reason it didn't work - I got to a black screen came up suggesting I insert my Windows Installation media and choose system repair. So I reinstalled Ubuntu in order to do further research and also to give me grub pointing at the Recovery Partition. So a rather large ordeal to get to the point of being able to boot into the Recovery partition! It started looking really good - Windows logo, HP stuff... So I get to the HP recovery menu - it has options for a factory setting reset and a minimized windows install. Not needed time to ponder that choice I opted for the minimal software install. The installer made in very clear that I would lose all my data and I would get a slightly less bloated Windows install than how I received the laptop - Great! I clicked through all the fluff it eventually got started. It got to the stage "Format the windows partition", looking like a champ. At 34% of the way through this crucial step though it failed with a horrible message "Recovery Manager Failed ERROR CODE = 0xEFFFFF08" oh joy.&lt;br /&gt;&lt;br /&gt;Cue the reboot, yup you guessed it the system has been re-borked. I got into the recovery manager again, used grub command line from my Ubuntu USB something like:&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: #eeeeee; font-family: 'Courier New', Courier, monospace;"&gt;chainloader (hd0,msdos5)+1&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: #eeeeee; font-family: 'Courier New', Courier, monospace;"&gt;boot&lt;/span&gt;&lt;br /&gt;Did the trick - back to square negative 1. This time I tried the other option - reset to factory condition. Can you believe that it got to 34% and threw the same error again. I wasted my time by trying both of these again before trying to alter the conditions. I got gparted running and tried to set the whole drive up nice for the recovery manager - I obviously left the recovery partition alone thinking it would eventually be convinced to do its job - I tried deleting all partitions then running the recovery tool =&amp;gt; fail, I tried creating a 100MB NTFS partition called boot followed by a massive NTFS partition called system as it was when I got it =&amp;gt; fail, I tried with just one large NTFS partition =&amp;gt; fail, I tried with a logical partition with the boot and system partitions again =&amp;gt; fail...&lt;br /&gt;&lt;br /&gt;Eventually I came to the conclusion that who ever programmed the "Recovery" manager was probably a script kiddie with a mail order degree. Admitting defeat I went into the store where I got the laptop just days ago, I thought I was onto a winner after finding someone who actually knew what a partition was. Sadly after relating my tale of woe his best advice was try the recovery manager again. I said I'd tried quite a few times and that I was fairly confident that I'd covered that one. He said it would be impossible to get a DVD from the store without paying the $699 that a standalone Windows license costs. I asked what they could do and he said I could leave the laptop with them for a week or two and they would get it fixed. Brilliant, I really want to be without a computer for another few weeks (my existing one was stolen after the Christchurch earthquakes)&lt;br /&gt;&lt;br /&gt;After I made it clear that I wasn't keen for that option he suggested downloading Windows 7 off the internet. I asked if he had a link because I'd had a quick look on HP and on Microsoft's websites for such a download but only found my way to their stores for purchasing Windows. The advice I got from the store was to download an ISO from thepiratebay or similar torrent sites. Since I purchased the laptop I &amp;nbsp;told him that resorting to illegal measures could wait until I have run out of other options. I enquired about using my friends Windows 7 Ultimate DVD to reinstall Windows on my laptop and the shop assistant said that should work fine and that he should have suggested something like that as his first idea.&lt;br /&gt;&lt;br /&gt;I left the shop full of hope, thinking I'd get back to a Windows desktop with little or no further agony. Oh I wish it had been that simple.&lt;br /&gt;&lt;br /&gt;So my friend gave me a DVD ISO which he told me had a folder of activation cracks and serial numbers included - I burnt the ISO to a DVD from my handy live USB operating system hoping to use my LEGITIMATE serial number from the bottom of my brand new laptop. I booted from the DVD and went through the install process - it didn't give me any options regarding version - it was just an Ultimate DVD and it wasn't until it had installed and rebooted that it asked for my serial number. I awkwardly read the number of the bottom of my laptop and triple checked it. After clicking next it took a long time to come to the conclusion that my key was valid but not matched to this &lt;a href="http://en.wikipedia.org/wiki/System_Locked_Preinstallation"&gt;Windows SLP&lt;/a&gt;. Starting to get a touch feed up by this stage I reinstalled Ubuntu and tried to forget about the Portal 2 game that I'd bought to play on my new high end laptop. After a few hours of sulking I decided to try again.&lt;br /&gt;&lt;br /&gt;With a bit of googling I found a &lt;a href="http://forums.mydigitallife.info/threads/12785-7-Oem-Sources-Folder-Project"&gt;project&lt;/a&gt; to gather the OEM specific scripts and keys that go onto laptops, I downloaded the HP zip and mounted the Windows 7 iso in a writeable mode from Ubuntu. I copied all the content across and burnt my new, modified to look like an OEM DVD. This unfortunately didn't help at all and I got to the same point.&lt;br /&gt;&lt;br /&gt;I got another Windows 7 ISO from another friend - this one was a retail "Windows 7&amp;nbsp;Professional" disk, but he said it was a universal installer - the checksum SHA-1 matched what was listed on Microsoft.com so I was much more confident that being a fully legit installer it would help me install the operating system. So I burnt it to a new DVD, booted the installer and got the option of Windows Professional 32 bit or 64 bit but no other options. Once again I didn't bother with the install because it clearly wasn't going to install the right version of Windows 7. I read &lt;a href="http://www.mydigitallife.info/how-to-select-any-edition-or-version-sku-of-windows-7-to-install-from-single-edition-dvd-disc-media-or-iso/"&gt;online&lt;/a&gt; that in the Win7 DVD a file called ei.cfg within the sources folder was the only thing responsible for what version the DVD installed and that deleting the file. I can't remember if I tried deleting the file, but I do remember&amp;nbsp;installing WINE in ubuntu and running a &lt;a href="http://code.kliu.org/misc/winisoutils/"&gt;binary patch&lt;/a&gt; on the iso file to change its version to Windows 7 Home Premium.&lt;br /&gt;&lt;br /&gt;I was running out of blank DVDs so I thought I'd do the same as I've done for the last few years with Ubuntu and install from a USB stick. I formatted a stick in fat32, ticked the boot flag and copied the ISO's contents to the USB disk. Attempting to boot from it got to a black screen complaining about something. I used grub2 to chainload into the usb, and got a different error - this one was complaining about the media not being "bootable" and asking me to insert my installation disk. I tried a few things from grub with loopback devices and mapping drives to try fool the thing but eventually decided that was just wasting time so I went and got more DVDs. I burnt my patched ISO and installed Windows 7 Home Premium and thank goodness it accepted my serial number.&lt;br /&gt;&lt;br /&gt;Despite Ubuntu working with my laptops graphics, wireless, bluetooth and lan out of the box Windows 7 couldn't manage more than a low resolution graphics driver, bluetooth and no LAN and no wireless. I had to download drivers from HP and transfer them via USB before I could connect to my home network with either cable or wifi.&lt;br /&gt;&lt;br /&gt;I'm writing this now from Windows 7, and I have internet. The thing is I'm not sure how long it will last - this copy of windows isn't activated because it says my product key is invalid for activation:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-maWfAc0YeoE/Tf23Hh6W9SI/AAAAAAAACW4/qF3zZiUJbyQ/s1600/no_activation.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-maWfAc0YeoE/Tf23Hh6W9SI/AAAAAAAACW4/qF3zZiUJbyQ/s320/no_activation.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Thankfully I called the number and entered in my 48 digit installation ID and then entered in the 48 digit&amp;nbsp;confirmation&amp;nbsp;ID. Don't know why this transfer of digits couldn't have been done online but I'm glad it was activated. Thanks Microsoft for making this about as painful as it could be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-3144777491495181926?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/3144777491495181926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2011/06/dear-hp-microsoft-youre-doing-it-wrong.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3144777491495181926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3144777491495181926'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2011/06/dear-hp-microsoft-youre-doing-it-wrong.html' title='Dear HP &amp; Microsoft - you&apos;re doing it wrong'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-maWfAc0YeoE/Tf23Hh6W9SI/AAAAAAAACW4/qF3zZiUJbyQ/s72-c/no_activation.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1443283162311905548</id><published>2011-06-18T23:59:00.000-07:00</published><updated>2011-10-27T12:48:26.924-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python3'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Porting labjack's Python 2 library to Python 3</title><content type='html'>I'm teaching an introduction to programming with Python 3 at work, 12 weeks with a 2 hour seminar once a week and homework. Internally one of the biggest uses of Python is in hardware interaction - especially when it comes to automated testing. We communicate with embedded devices running &lt;a href="http://www.eluaproject.net/"&gt;elua&lt;/a&gt;, &lt;a href="http://labjack.com/"&gt;labjacks&lt;/a&gt;, programmable power supplies, oscilloscopes, &lt;a href="http://www.kvaser.com/"&gt;Kvaisers&lt;/a&gt; and more with Python - primarily using the serial&amp;nbsp;interface&amp;nbsp;and abstracting the hardware with Python.&lt;br /&gt;&lt;br /&gt;Since most of our existing code uses python2, I figured I should spend an hour looking at porting an existing Python module to python3. The python library we currently use to communicate with Labjack is an in house ctypes wrapper, but Labjack have their own Python library code so I decided to port that to Python3.&lt;br /&gt;&lt;br /&gt;I only did the bare minimum to get the basic tutorial running but you can see forked code on &lt;a href="https://github.com/hardbyte/LabJackPython3"&gt;github&lt;/a&gt;. For the most part 2to3 did everything. The modifications I had to make were all because the Labjack operates at a pretty low level. Where previously the code was converting strings into int lists with ord, I just removed that map as now it uses bytes. The only other thing that 2to3 seemed to miss was a floor division.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1443283162311905548?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1443283162311905548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2011/06/porting-labjacks-python-2-library-to.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1443283162311905548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1443283162311905548'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2011/06/porting-labjacks-python-2-library-to.html' title='Porting labjack&apos;s Python 2 library to Python 3'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>2</thr:total><georss:featurename>Middleton, New Zealand</georss:featurename><georss:point>-43.542134221065666 172.59039181235357</georss:point><georss:box>-43.54952972106567 172.5744688123536 -43.534738721065665 172.60631481235356</georss:box></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1545932661171874301</id><published>2010-06-01T03:53:00.000-07:00</published><updated>2010-06-01T04:00:05.590-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wikipedia'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='machine learning'/><title type='text'>Wikipedia Mining</title><content type='html'>So I was studying nearest&amp;nbsp;neighbor&amp;nbsp;for my machine learning exam tomorrow and I stumbled across "breadth-first search" and it got me thinking... Okay I've come across it before but never thought of a breadth-first search of wikipedia as a means of finding the nearest neighbour...&lt;br /&gt;&lt;br /&gt;I thought about all the internal links that wikipedia keeps and how easy it would be to use each page as a graph node then do a bit of a breadth-first search by visiting all those child nodes. Then I thought maybe the links from the child nodes would be interesting so I created a link counter to keep track of how often a link shows up across all children of a page. The way I implemented it wasn't using the wikipedia api or anything - just scraping the data off the web. This means it kinda downloads a few thousand wikipedia pages for a single query... but still it was interesting!&lt;br /&gt;&lt;br /&gt;If I query "&lt;a href="http://en.wikipedia.org/wiki/Machine_learning"&gt;Machine learning&lt;/a&gt;" the closest match is not "&lt;a href="http://en.wikipedia.org/wiki/Artificial_intelligence"&gt;Artificial intelligence&lt;/a&gt;" as you might guess, but rather&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/International_Standard_Book_Number"&gt;International Standard Book Number&lt;/a&gt;.&amp;nbsp;It has 38 links pointing to it as opposed to 30. I looked at a few of the pages and it appears these are links I could ignore - info boxes for journals seem to like linking to the ISBN article.... DOI was up there as well.&lt;br /&gt;&lt;br /&gt;Anyhow all these links are taken from all the children of the &lt;a href="http://en.wikipedia.org/wiki/Machine_learning"&gt;Machine Learning page on wikipedia&lt;/a&gt;. There were 11008 total links only one node away, and of these 6873 were unique.&lt;br /&gt;&lt;br /&gt;I thought about adding another level to it, ie exploring the children linked to by the children - but as it already takes a minute or so, I imagine that will take a few hours to run and download a crapload of wikipedia. I minor improvement would be needed if any depth could be specified - we wouldn't want to revisit the same node again and again.&lt;br /&gt;&lt;br /&gt;Running the program with input "cheese", I found a few more children - 417 of them. This took about 10 minutes to download all the webpages then it quickly used some sets and dictionaries to work out that cheese is equally related to "Rice" and "Carbohydrate" according to this quick measure, &amp;nbsp;from all of cheese's internal links 124 of them point to each. Bread is a close follower with 122 links.&lt;br /&gt;&lt;br /&gt;Hmm well that was a fun diversion, back to study me thinks.&lt;br /&gt;&lt;br /&gt;The code in case anyone wants to play:&lt;br /&gt;&lt;br /&gt;&lt;div class="highlight" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span style="color: #408080; font-style: italic;"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;from&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;urllib2&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;import&lt;/span&gt; build_opener&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;HTMLParser&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;from&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;HTMLParser&lt;/span&gt; &lt;span style="color: green; font-weight: bold;"&gt;import&lt;/span&gt; HTMLParser&lt;br /&gt;URL &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'http://en.wikipedia.org'&lt;/span&gt;&lt;br /&gt;ignore_urls &lt;span style="color: #666666;"&gt;=&lt;/span&gt; [&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Portal'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Special'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/w/index.php'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Help'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'wiki/Wikipedia'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Main_Page'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Category'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Template'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/Talk:'&lt;/span&gt;,&lt;br /&gt;    &lt;span style="color: #ba2121;"&gt;'/wiki/File:'&lt;/span&gt;,&lt;br /&gt;    &lt;br /&gt;]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;LinkingHTMLParser&lt;/span&gt;(HTMLParser):&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;__init__&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;):&lt;br /&gt;        HTMLParser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;__init__(&lt;span style="color: green;"&gt;self&lt;/span&gt;)&lt;br /&gt;        &lt;span style="color: #408080; font-style: italic;"&gt;#super(LinkingHTMLParser, self).__init__()&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: green;"&gt;set&lt;/span&gt;()&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;handle_starttag&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;, tag, attrs):&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;if&lt;/span&gt; tag &lt;span style="color: #666666;"&gt;==&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;"a"&lt;/span&gt; &lt;span style="color: #aa22ff; font-weight: bold;"&gt;and&lt;/span&gt; &lt;span style="color: green;"&gt;len&lt;/span&gt;(attrs) &lt;span style="color: #666666;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #666666;"&gt;1&lt;/span&gt;:&lt;br /&gt;            (_,url), (_, title) &lt;span style="color: #666666;"&gt;=&lt;/span&gt; attrs[&lt;span style="color: #666666;"&gt;0&lt;/span&gt;], attrs[&lt;span style="color: #666666;"&gt;1&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;if&lt;/span&gt; url&lt;span style="color: #666666;"&gt;.&lt;/span&gt;startswith(&lt;span style="color: #ba2121;"&gt;'/wiki'&lt;/span&gt;) &lt;span style="color: #aa22ff; font-weight: bold;"&gt;and&lt;/span&gt; &lt;span style="color: #aa22ff; font-weight: bold;"&gt;not&lt;/span&gt; &lt;span style="color: green;"&gt;any&lt;/span&gt;(addy &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; url &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; addy &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; ignore_urls):&lt;br /&gt;                &lt;span style="color: #408080; font-style: italic;"&gt;#print 'Linked to %s at address: %s' % (title, url)&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links&lt;span style="color: #666666;"&gt;.&lt;/span&gt;add(url)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;opener &lt;span style="color: #666666;"&gt;=&lt;/span&gt; build_opener()&lt;br /&gt;opener&lt;span style="color: #666666;"&gt;.&lt;/span&gt;addheaders &lt;span style="color: #666666;"&gt;=&lt;/span&gt; [(&lt;span style="color: #ba2121;"&gt;'User-agent'&lt;/span&gt;, &lt;span style="color: #ba2121;"&gt;'Mozilla/5.0'&lt;/span&gt;)]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;class&lt;/span&gt; &lt;span style="color: blue; font-weight: bold;"&gt;Page&lt;/span&gt;(&lt;span style="color: green;"&gt;object&lt;/span&gt;):&lt;br /&gt;    &lt;span style="color: #ba2121; font-style: italic;"&gt;'''&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121; font-style: italic;"&gt;    A node on the internet... a webpage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ba2121; font-style: italic;"&gt;        &amp;gt;&amp;gt;&amp;gt; Page('http://en.wikipedia.org/wiki/Nearest_neighbor_search')&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121; font-style: italic;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #ba2121; font-style: italic;"&gt;    '''&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;__init__&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;, url):&lt;br /&gt;        &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;url &lt;span style="color: #666666;"&gt;=&lt;/span&gt; url&lt;br /&gt;        &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;handle &lt;span style="color: #666666;"&gt;=&lt;/span&gt; opener&lt;span style="color: #666666;"&gt;.&lt;/span&gt;open(url)&lt;br /&gt;        &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser &lt;span style="color: #666666;"&gt;=&lt;/span&gt; LinkingHTMLParser()&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;__repr__&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;):&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'Page(&lt;/span&gt;&lt;span style="color: #bb6688; font-weight: bold;"&gt;%s&lt;/span&gt;&lt;span style="color: #ba2121;"&gt;)'&lt;/span&gt; &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;url&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;__str__&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;):&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'&lt;/span&gt;&lt;span style="color: #bb6622; font-weight: bold;"&gt;\n&lt;/span&gt;&lt;span style="color: #ba2121;"&gt;'&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;join(line &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; line &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;handle)&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;parse&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;):&lt;br /&gt;        &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;feed(&lt;span style="color: green;"&gt;str&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;))&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'Number of internal links: &lt;/span&gt;&lt;span style="color: #bb6688; font-weight: bold;"&gt;%d&lt;/span&gt;&lt;span style="color: #ba2121;"&gt;'&lt;/span&gt; &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: green;"&gt;len&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links)&lt;br /&gt;        &lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;create_children&lt;/span&gt;(&lt;span style="color: green;"&gt;self&lt;/span&gt;):&lt;br /&gt;        &lt;span style="color: #ba2121; font-style: italic;"&gt;'''Create nodes for each link in self'''&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;children &lt;span style="color: #666666;"&gt;=&lt;/span&gt; []&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; url &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links:&lt;br /&gt;            child &lt;span style="color: #666666;"&gt;=&lt;/span&gt; Page(URL &lt;span style="color: #666666;"&gt;+&lt;/span&gt; url)&lt;br /&gt;            &lt;span style="color: green;"&gt;self&lt;/span&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;children&lt;span style="color: #666666;"&gt;.&lt;/span&gt;append(&lt;br /&gt;                child&lt;br /&gt;                )&lt;br /&gt;&lt;span style="color: green; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: blue;"&gt;find_n_most_related_pages&lt;/span&gt;(topic&lt;span style="color: #666666;"&gt;=&lt;/span&gt;&lt;span style="color: #ba2121;"&gt;'Nearest neighbor search'&lt;/span&gt;, n&lt;span style="color: #666666;"&gt;=10&lt;/span&gt;):&lt;br /&gt;    topic &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'/wiki/'&lt;/span&gt; &lt;span style="color: #666666;"&gt;+&lt;/span&gt; topic&lt;span style="color: #666666;"&gt;.&lt;/span&gt;replace(&lt;span style="color: #ba2121;"&gt;' '&lt;/span&gt;, &lt;span style="color: #ba2121;"&gt;'_'&lt;/span&gt;)&lt;br /&gt;    p &lt;span style="color: #666666;"&gt;=&lt;/span&gt; Page(URL &lt;span style="color: #666666;"&gt;+&lt;/span&gt; topic)&lt;br /&gt;    p&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parse()&lt;br /&gt;    p&lt;span style="color: #666666;"&gt;.&lt;/span&gt;create_children()&lt;br /&gt;    total_links &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: green;"&gt;len&lt;/span&gt;(p&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links)&lt;br /&gt;    all_links &lt;span style="color: #666666;"&gt;=&lt;/span&gt; p&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links&lt;br /&gt;    link_counts &lt;span style="color: #666666;"&gt;=&lt;/span&gt; {}&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; child &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; p&lt;span style="color: #666666;"&gt;.&lt;/span&gt;children:&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;try&lt;/span&gt;:&lt;br /&gt;            child&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parse()&lt;br /&gt;            &lt;span style="color: #408080; font-style: italic;"&gt;#print 'Child "%s" has %d links.' % (child.url, len(child.parser.links))&lt;/span&gt;&lt;br /&gt;            total_links &lt;span style="color: #666666;"&gt;+=&lt;/span&gt; &lt;span style="color: green;"&gt;len&lt;/span&gt;(child&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links)&lt;br /&gt;            all_links &lt;span style="color: #666666;"&gt;=&lt;/span&gt; all_links&lt;span style="color: #666666;"&gt;.&lt;/span&gt;union(child&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links)&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; link &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; child&lt;span style="color: #666666;"&gt;.&lt;/span&gt;parser&lt;span style="color: #666666;"&gt;.&lt;/span&gt;links:&lt;br /&gt;                &lt;span style="color: green; font-weight: bold;"&gt;if&lt;/span&gt; link &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; link_counts:&lt;br /&gt;                    link_counts[link] &lt;span style="color: #666666;"&gt;+=&lt;/span&gt; &lt;span style="color: #666666;"&gt;1&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: green; font-weight: bold;"&gt;else&lt;/span&gt;:&lt;br /&gt;                    link_counts[link] &lt;span style="color: #666666;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;"&gt;1&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;except&lt;/span&gt;:&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'error'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'Link counts:'&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;for&lt;/span&gt; i, link &lt;span style="color: #aa22ff; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: green;"&gt;enumerate&lt;/span&gt;(&lt;span style="color: green;"&gt;sorted&lt;/span&gt;(link_counts, &lt;span style="color: green;"&gt;cmp&lt;/span&gt;&lt;span style="color: #666666;"&gt;=&lt;/span&gt;&lt;span style="color: green; font-weight: bold;"&gt;lambda&lt;/span&gt; x, y: link_counts[y] &lt;span style="color: #666666;"&gt;-&lt;/span&gt; link_counts[x])):&lt;br /&gt;        &lt;span style="color: green; font-weight: bold;"&gt;if&lt;/span&gt; i &lt;span style="color: #666666;"&gt;&amp;lt;=&lt;/span&gt; n:&lt;br /&gt;            &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'&lt;/span&gt;&lt;span style="color: #bb6688; font-weight: bold;"&gt;%s&lt;/span&gt;&lt;span style="color: #ba2121;"&gt; has &lt;/span&gt;&lt;span style="color: #bb6688; font-weight: bold;"&gt;%d&lt;/span&gt;&lt;span style="color: #ba2121;"&gt; links.'&lt;/span&gt; &lt;span style="color: #666666;"&gt;%&lt;/span&gt; (link, link_counts[link])&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'*'&lt;/span&gt; &lt;span style="color: #666666;"&gt;*&lt;/span&gt; &lt;span style="color: #666666;"&gt;80&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'Total links only one node away: &lt;/span&gt;&lt;span style="color: #bb6688; font-weight: bold;"&gt;%d&lt;/span&gt;&lt;span style="color: #ba2121;"&gt;'&lt;/span&gt; &lt;span style="color: #666666;"&gt;%&lt;/span&gt; total_links&lt;br /&gt;    &lt;span style="color: green; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span style="color: #ba2121;"&gt;'Unique pages only one node away: &lt;/span&gt;&lt;span style="color: #bb6688; font-weight: bold;"&gt;%d&lt;/span&gt;&lt;span style="color: #ba2121;"&gt;'&lt;/span&gt; &lt;span style="color: #666666;"&gt;%&lt;/span&gt; &lt;span style="color: green;"&gt;len&lt;/span&gt;(all_links)&lt;br /&gt;&lt;br /&gt;find_n_most_related_pages(&lt;span style="color: #ba2121;"&gt;'Cheese'&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1545932661171874301?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1545932661171874301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2010/06/wikipedia-mining.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1545932661171874301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1545932661171874301'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2010/06/wikipedia-mining.html' title='Wikipedia Mining'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-3773591348852494166</id><published>2010-05-19T21:54:00.000-07:00</published><updated>2010-05-19T21:54:25.114-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mechanics'/><category scheme='http://www.blogger.com/atom/ns#' term='engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><category scheme='http://www.blogger.com/atom/ns#' term='vibration'/><title type='text'>Analysis of a 3 degree of freedom building in an earthquake with scipy</title><content type='html'>&lt;span class="Apple-style-span"&gt;This is my building, I want to know how much each floor moves in an earthquake... Also it would be nice to know the acceleration experienced by each floor.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_lewp47C9PZI/S_S9U0KWDeI/AAAAAAAACLw/XxzY0rrysrE/s1600/building.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_lewp47C9PZI/S_S9U0KWDeI/AAAAAAAACLw/XxzY0rrysrE/s320/building.png" width="273" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;First off we need some data. I have an earthquake data file containing ground acceleration data from the &lt;a href="http://en.wikipedia.org/wiki/Great_Hanshin_earthquake"&gt;Kobe earthquake&lt;/a&gt;&amp;nbsp;of 1995. It is a matlab file, so the data will have to be extracted into a numpy format. Scipy has an &lt;i&gt;io&lt;/i&gt; module which contains a &lt;i&gt;matlab&lt;/i&gt; submodule. Since we want to visualize this data somehow, the &lt;i&gt;pylab&lt;/i&gt; package will also be used.&lt;br /&gt;&lt;br /&gt;Firstly I'll make a small helper function that enforces complex symmetry, useful for after the frequency domain analysis:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;from&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;scipy.io&lt;/span&gt; &lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matlab&lt;/span&gt; &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mio&lt;/span&gt;&lt;br /&gt;&lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;from&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;pylab&lt;/span&gt; &lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;annotate&lt;/span&gt;&lt;br /&gt;&lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;numpy&lt;/span&gt; &lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;as&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;np&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;enforce_complex_sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nyquist&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt; &lt;span class="sd" style="color: #4070a0; font-style: italic;"&gt;'''Enforce complex symmetry'''&lt;/span&gt;&lt;br /&gt; &lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;nyquist&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;+&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;conj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;nyquist&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;/pre&gt;Next I'll write two plotting functions, that will annotate the maximum of some time indexed data:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;analyse_time_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plot_title&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plot_label&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yunits&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'m/s^{2}'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;plot_responses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arrayN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp" style="color: #007020;"&gt;var&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="p"&gt;So with all the setup done, we can get the data from the matlab file:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="p"&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Load earthquake data from matlab file&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;kobe_data&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mio&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loadmat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'Kobe.mat'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kobe_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'f'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'dt'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="p"&gt;So this opens the matlab file "Kobe.mat" which contains&amp;nbsp;matrices&amp;nbsp;'f', 't', and 'dt'. Once the file is open we can load the data into numpy arrays a, t and dt. At this point I used my analyse_time_data function to plot the raw ground acceleration.&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_lewp47C9PZI/S_S7AELHkaI/AAAAAAAACLs/Uo6vDKDjOCE/s1600/kobe_ground_acceleration.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/_lewp47C9PZI/S_S7AELHkaI/AAAAAAAACLs/Uo6vDKDjOCE/s320/kobe_ground_acceleration.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="p"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="p"&gt;Now we have the data, and it looks very earthquake like, lets create our system:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="p"&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# data on each story:&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;10000&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;1600000&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;13000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Construct System matricies:&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;diag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;[&lt;/span&gt;  &lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;&lt;br /&gt;     &lt;br /&gt;&lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;M, C and K are all (3 x 3) matrices, F is the force on each floor, N is the number of sample points:&lt;/div&gt;&lt;div&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;transpose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;nyquist&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;/&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now we could numerically integrate this, or we could jump into the frequency domain, I like my fft's so lets do that. We then iterate over the frequency domain data applying a transfer function.&lt;/div&gt;&lt;div&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Transform into frequency domain&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;Fs&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;fft&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;fft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;fft&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;fftfreq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Calculate and apply the transfer function upto nyquist frequency&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;Vs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dVs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ddVs&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;zeros&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;complex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="nb" style="color: #007020;"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="nb" style="color: #007020;"&gt;xrange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nyquist&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;Gs&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;**&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;+&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;Vs&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Gs&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;c_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fs&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;dVs&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;Vs&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;ddVs&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Vs&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;*&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;**&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;enforce_complex_sym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nyquist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Vs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dVs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ddVs&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;The reason we only go up to the nyquist frequency is because the data is all contained in the first half of the complex signal, we simply enforce complex symmetry then convert back to the time domain:&lt;/div&gt;&lt;div&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Convert back to the time domain&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dvt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ddvt&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;fft&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;ifft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="kp" style="color: #007020;"&gt;real&lt;/span&gt; &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="kp" style="color: #007020;"&gt;array&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Vs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dVs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ddVs&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Plot the response&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;plot_responses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'Displacement'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'m'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;plot_responses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dvt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'Velocity'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'m/s'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;plot_responses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ddvt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'Acceleration'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'m/s^{2}'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="p"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;And now for some plots:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lewp47C9PZI/S_S_LK9gJVI/AAAAAAAACL0/sKJaf5Btjuw/s1600/kobe_floor_displacement.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_lewp47C9PZI/S_S_LK9gJVI/AAAAAAAACL0/sKJaf5Btjuw/s320/kobe_floor_displacement.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It can be seen that the max displacement for floor 1 is about half that of the 3rd floor. The maximum the top story ends up moving is 0.33m.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_lewp47C9PZI/S_S_QD0EEiI/AAAAAAAACL4/Av3YuQslQL8/s1600/kobe_floor_acceleration.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/_lewp47C9PZI/S_S_QD0EEiI/AAAAAAAACL4/Av3YuQslQL8/s320/kobe_floor_acceleration.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Acceleration shows a similar pattern, the top story suffers the worst, reaching over 1G laterally. Possibly in a future post I will do the same analysis the numerical integration way.&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-3773591348852494166?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/3773591348852494166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2010/05/analysis-of-3-degree-of-freedom.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3773591348852494166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3773591348852494166'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2010/05/analysis-of-3-degree-of-freedom.html' title='Analysis of a 3 degree of freedom building in an earthquake with scipy'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lewp47C9PZI/S_S9U0KWDeI/AAAAAAAACLw/XxzY0rrysrE/s72-c/building.png' height='72' width='72'/><thr:total>1</thr:total><georss:featurename>Hyōgo Prefecture, Japan</georss:featurename><georss:point>34.6912688 135.1830706</georss:point><georss:box>33.5620923 133.31539460000002 35.8204453 137.0507466</georss:box></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-8110218044149574182</id><published>2010-05-05T21:55:00.000-07:00</published><updated>2010-05-05T21:55:54.639-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><category scheme='http://www.blogger.com/atom/ns#' term='imap'/><title type='text'>Python and Gmail with IMAP</title><content type='html'>Today I had to automatically access my Gmail inbox from Python. I needed the ability to get an unread email count, the subjects of those unread emails and then download them. I found a Gmail.py library on sourceforge, but it actually opened the normal gmail webpage and site scraped the info. I wanted something much faster, luckily gmail can now be accessed with both pop and imap.&lt;br /&gt;&lt;br /&gt;After a tiny amount of research I decided imap was the better albiet slightly more difficult protocol. Enabling imap in gmail is straight forward, it was under labs.&lt;br /&gt;&lt;br /&gt;The address for gmail's imap server is:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;imap.gmail.com:993&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Python has a library module called &lt;i&gt;imaplib&lt;/i&gt;, we will make heavy use of that to access our emails. I'm going to assume that we have already defined two globals - username and password. To connect and login to the gmail server and select the inbox we can do:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;imaplib&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;imap_server&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imaplib&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IMAP4_SSL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;"imap.gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;993&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'INBOX'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;All pretty straight forward so far, lets find out how many unread emails we have:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Count the unread emails&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'INBOX'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;"(UNSEEN)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;unreadcount&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="nb" style="color: #007020;"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;').,]'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span class="n"&gt;unreadcount&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Now I'm not saying this is a particularly nice way of doing this, but if you print the response and reverse engineer it you will see how I arrived with that string parsing. Regex would be another option, but I try avoid that unless it is required. Now lets get a list of the identifiers for each unread message, I'm going to call it email_ids:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="c" style="color: #60a0b0; font-style: italic;"&gt;# Search for all new mail&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_ids&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp" style="color: #007020;"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'(UNSEEN)'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;If I want to download a particular list of messages, or maybe download the subjects for a list of messages I can use the following functions:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;get_emails&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e_id&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'(UID BODY[TEXT])'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;get_subjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;subjects&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e_id&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'(body[header.fields (subject)])'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;subjects&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;9&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span class="n"&gt;subjects&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And I often search for emails from someone in particular, I can do that easily from Python as well:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;emails_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd" style="color: #4070a0; font-style: italic;"&gt;'''Search for all mail from name'''&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imap_server&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp" style="color: #007020;"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'(FROM "&lt;/span&gt;&lt;span class="si" style="color: #70a0d0; font-style: italic;"&gt;%s&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;")'&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;%&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;email_ids&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;e_id&lt;/span&gt; &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e_id&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'Number of emails from &lt;/span&gt;&lt;span class="si" style="color: #70a0d0; font-style: italic;"&gt;%s&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;: &lt;/span&gt;&lt;span class="si" style="color: #70a0d0; font-style: italic;"&gt;%i&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;. IDs: &lt;/span&gt;&lt;span class="si" style="color: #70a0d0; font-style: italic;"&gt;%s&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb" style="color: #007020;"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span class="n"&gt;email_ids&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Now this can all be combined to print the body of the latest 3 emails sent by my friend bob:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get_emails&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;"bob"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;-&lt;/span&gt;&lt;span class="mi" style="color: #40a070;"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Thats all folks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-8110218044149574182?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/8110218044149574182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2010/05/python-and-gmail-with-imap.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/8110218044149574182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/8110218044149574182'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2010/05/python-and-gmail-with-imap.html' title='Python and Gmail with IMAP'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1891753475153055960</id><published>2010-04-29T05:42:00.000-07:00</published><updated>2010-04-29T05:47:05.597-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Publicly query facebook using Python</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="posting"&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;In my cosc lab today a few students were asking about doing something "real" and "cool" with Python, something that isn't easy in excel. After a bit of a think I came to the conclusion that getting data from the internet is a "real" enough problem. As for "cool", since most people seem to have facebook open in the background during labs I thought getting some real live data off facebook could be interesting.&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;First a disclaimer or two.&lt;/div&gt;&lt;ul&gt;&lt;li style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;Don't just run random code without reading it and satisfying yourself that its not trying to delete your operating system or do anything sinister!&lt;/li&gt;&lt;li style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px;"&gt;I don't make the test or the assignment. This is not at all related, except for the fact it is using Python (okay it uses a for loop to iterate over a list, if nothing else in this post is of interest to you, learn how to do that!)&lt;/li&gt;&lt;/ul&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;So if anyone is still reading, let me introduce the problem, then look into how we can solve it.&amp;nbsp;We will take a quick look at facebook's graph api, then finally how it all ties together in a pretty short snippet of Python.&amp;nbsp;There are two modules you probably haven't seen from the Python standard library so I'll briefly touch on those as well.&amp;nbsp;&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;Onwards to the&amp;nbsp;&lt;strong&gt;problem&lt;/strong&gt;: Lets say I'm very interested in comparing how many fans various public pages on facebook have. Maybe I am very pedantic and I check all the time, at least once an hour. But I really hate searching for the page on facebook each time to check how many fans there are. My tech friend told me about bookmarks, so I bookmarked each of the pages I check but it still takes me too long. All this other information is irrelevant to me... what I really want is to write a program that cuts through the crap so to speak and gives me the data. All I require for each page I'm interested in is the current number of fans.&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;Facebook has an application programming interface (API) called Graph API, basically it connects everything on facebook to anything else on facebook.&amp;nbsp;For example, the official facebook page for the&amp;nbsp;Facebook Platform&amp;nbsp;has the id 19292868552, so you can fetch the object at&amp;nbsp;&lt;a href="https://graph.facebook.com/19292868552" style="color: blue; text-decoration: none;"&gt;https://graph.facebook.com/19292868552&lt;/a&gt;, alternatively if you know the username (and the page/user has one) you can fetch the object from&amp;nbsp;&lt;a href="https://graph.facebook.com/platform" style="color: blue; text-decoration: none;"&gt;https://graph.facebook.com/platform&lt;/a&gt;. If you clicked on those links you will notice the data is very similar to a python dictionary - this is data in the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Json" style="color: blue; text-decoration: none;"&gt;json&lt;/a&gt;&amp;nbsp;format. If you know your own username on facebook, try see what is publicly known about you - just replace platform with your username (Note: since accessing private data on facebook requires secure authentication, we are just going to look at public pages). To see more about the facebook graph api go to&amp;nbsp;&lt;a href="http://developers.facebook.com/docs/api" style="color: blue; text-decoration: none;"&gt;http://developers.facebook.com/docs/api&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;I imagine you have at least peeked at the code below by now, and line one should now make sense. If we want to decode json data aren't we lucky that Python has an inbuilt json module, lets use it!&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;Oh wait, before we can decode the json data we need to get access to it in Python. So just like in our earlier labs where you open a csv file, by calling&amp;nbsp;&lt;em&gt;open&lt;/em&gt;&amp;nbsp;with a filename, we open a website by its url. The only function we use from&amp;nbsp;&lt;em&gt;urllib2&lt;/em&gt;&amp;nbsp;is&amp;nbsp;&lt;em&gt;urlopen&lt;/em&gt;, it takes an address (url) as its parameter, then instead of calling readlines like we did in lab 6, we call read. At this stage we have the data, but as a single large string.[1]&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;Line 7 creates a python dictionary out of the json data found at the address we specify. No I didn't know how to do that, I looked it up - the documentation is your friend. Google for "python json" and the first link will be the official documentation (including examples). Scan through that and you will find a function&amp;nbsp;&lt;em&gt;loads&lt;/em&gt;&amp;nbsp;that will load python data from a string of json, and a function&amp;nbsp;&lt;em&gt;load&lt;/em&gt;&amp;nbsp;that will load json from a file-like object. A url behaves very similar to a file, if we wanted we could call&amp;nbsp;&lt;em&gt;readlines&lt;/em&gt;() on an object created by&amp;nbsp;&lt;em&gt;urlopen&lt;/em&gt;, just like we could for a file object created with&amp;nbsp;&lt;em&gt;open&lt;/em&gt;.&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;&lt;/div&gt;&lt;pre style="background-color: transparent; border-bottom-color: rgb(204, 204, 204); border-bottom-style: none; border-bottom-width: 1px; border-color: initial; border-left-style: none; border-right-style: none; border-top-color: rgb(204, 204, 204); border-top-style: none; border-top-width: 1px; border-width: initial; font-family: 'Bitstream Vera Sans Mono', monospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;json&lt;/span&gt;&lt;br /&gt;&lt;span class="kn" style="color: #007020; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span class="nn" style="color: #0e84b5; font-weight: bold;"&gt;urllib2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;load_facebook_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;facebook_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd" style="color: #4070a0; font-style: italic;"&gt;'''Return a dictionary of data from a facebook page id or username'''&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;addy&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'http://graph.facebook.com/'&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;+&lt;/span&gt; &lt;span class="n"&gt;facebook_id&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urllib2&lt;/span&gt;&lt;span class="o" style="color: #666666;"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addy&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span class="nf" style="color: #06287e;"&gt;print_fans&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;facebook_page_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd" style="color: #4070a0; font-style: italic;"&gt;'''Print the name and number of fans of a facebook page'''&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;facebook_page&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_facebook_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;facebook_page_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k" style="color: #007020; font-weight: bold;"&gt;print&lt;/span&gt; &lt;span class="n"&gt;facebook_page&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'fans: '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;facebook_page&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s" style="color: #4070a0;"&gt;'fan_count'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;page_ids&lt;/span&gt; &lt;span class="o" style="color: #666666;"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'pythonlang'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'62842406160'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s" style="color: #4070a0;"&gt;'63723325087'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class="k" style="color: #007020; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span class="n"&gt;facebook_id&lt;/span&gt; &lt;span class="ow" style="color: #007020; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span class="n"&gt;page_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;print_fans&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;facebook_id&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;Hmm writing this description has taken about four or five times as long as writing the code! It really turned into an essay, opps. Luckily everything after line 8 should be very straight forward.&amp;nbsp;Make up some problems and improvements. A simple one to start with would be printing out the address of the facebook page as well as its name and the number of fans.&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 8px;"&gt;[1] The module was called urllib but when it first got introduced people decided to write a new version that was so different from the original that they called it urllib2. In python 3 the old urllib is being thrown out and urllib2 becomes urllib - complicated much?&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1891753475153055960?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1891753475153055960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2010/04/in-my-cosc-lab-today-few-students-were.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1891753475153055960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1891753475153055960'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2010/04/in-my-cosc-lab-today-few-students-were.html' title='Publicly query facebook using Python'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-8959637111432505144</id><published>2010-01-06T12:50:00.000-08:00</published><updated>2010-01-06T12:50:07.094-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computer vision'/><category scheme='http://www.blogger.com/atom/ns#' term='paper'/><category scheme='http://www.blogger.com/atom/ns#' term='kiwipycon'/><title type='text'>Python in Computer Vision Paper</title><content type='html'>The conference proceedings have just been released for the 1st Kiwi PyCon. I presented and wrote a paper so this is my first ever published work.&lt;br /&gt;&lt;br /&gt;The entire journal can be found on the &lt;a href="http://ojs.pythonpapers.org/index.php/tppm/issue/view/16"&gt;pythonpapers.org&lt;/a&gt; site and just my paper is &lt;a href="http://ojs.pythonpapers.org/index.php/tppm/article/view/94/111"&gt;here&lt;/a&gt;. The abstract is simply:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;An introduction to computer vision in Python, from the general concept to its implementation with some current open-source libraries. This paper demonstrates a selection of basic computer vision examples using SciPy, OpenCV and Pygame.&lt;br /&gt;&lt;/blockquote&gt;&lt;div id="__ss_2435892" style="text-align: left; width: 425px;"&gt;&lt;a href="http://www.slideshare.net/hardbyte/python-in-computer-vision" style="display: block; font-family: Helvetica,Arial,Sans-serif; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; margin: 12px 0pt 3px; text-decoration: underline;" title="Python in Computer Vision"&gt;Python in Computer Vision&lt;/a&gt;&lt;object height="355" style="margin: 0px;" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presentation-091106011217-phpapp01&amp;stripped_title=python-in-computer-vision" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presentation-091106011217-phpapp01&amp;stripped_title=python-in-computer-vision" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="font-family: tahoma,arial; font-size: 11px; height: 26px; padding-top: 2px;"&gt;View more &lt;a href="http://www.slideshare.net/" style="text-decoration: underline;"&gt;documents&lt;/a&gt; from &lt;a href="http://www.slideshare.net/hardbyte" style="text-decoration: underline;"&gt;Brian Thorne&lt;/a&gt; on slideshare.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-8959637111432505144?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/8959637111432505144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2010/01/python-in-computer-vision-paper.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/8959637111432505144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/8959637111432505144'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2010/01/python-in-computer-vision-paper.html' title='Python in Computer Vision Paper'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-7212171224416728866</id><published>2009-12-13T18:21:00.000-08:00</published><updated>2009-12-13T18:21:29.775-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scipy-sim'/><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><title type='text'>SciPy-Simulator</title><content type='html'>For the last few weeks I have been working on a &lt;a href="http://www.mathworks.com/products/simulink/"&gt;Simulink&lt;/a&gt; / &lt;a href="http://www.ni.com/labview/"&gt;Labview&lt;/a&gt; / &lt;a href="http://ptolemy.berkeley.edu/ptolemyII/"&gt;Ptolemy II&lt;/a&gt; like program for modelling... all sorts of stuff!! I am interested in modeling with different systems of computation, and of course some engineering problems, mechanical and electrical control etc. Ptolemey II is an open source java based system which a whole lot of people from Berkley have been working on for a number of years - I am not trying to match what they have - or get anywhere near the breadth that the commercial products Simulink and Labview have. But I do think something useful is very achievable - and of course leveraging what I can from Ptolemy II and basing mine on Python - heavily using &lt;a href="http://www.scipy.org/"&gt;SciPy&lt;/a&gt;, &lt;a href="http://numpy.scipy.org/"&gt;NumPy&lt;/a&gt; and &lt;a href="http://matplotlib.sourceforge.net/"&gt;MatPlotLib&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So far I have been working on the semantics - in essence creating a new language for defining models by using blocks (or Actors) that carry out a very specific function. An example actor might be a &lt;i&gt;Ramp Source&lt;/i&gt; or a &lt;i&gt;Sin Function&lt;/i&gt;. Each of these actors run in their own thread and communicate via dedicated Channels - which are based on the thread safe &lt;a href="http://en.wikipedia.org/wiki/FIFO"&gt;fifo queue&lt;/a&gt; implementation in the Python standard library. These base level actors can be composed together to create models, which are also actors in their own right - running in their own thread with all communication&amp;nbsp;occurring&amp;nbsp;through input and output channels.&lt;br /&gt;&lt;br /&gt;The final goal is to have a visual interface - drag and drop blocks around, then connect up the model with channels. For now the whole thing is code based, so one of the more complicated models I have made is a simple pulse width modulator generator.&lt;br /&gt;&lt;br /&gt;Here is the full code that defines and runs the model:&lt;br /&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="sd"&gt;&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;Created on 13/12/2009&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="sd"&gt;@author: brian&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;models.actors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Plotter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Ramp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Summer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Copier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GreaterThan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Subtractor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Constant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PassThrough&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CTSinGenerator&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;plt&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;models.actors.Actor&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MakeChans&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Logger enabled&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_multi_sum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd"&gt;&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    This example connects 3 sources ( 2 ramps and a random) to a summer block&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    The final output AND one of the ramps are dynamically plotted.&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    The components are all generating the same sequence of tags so are always&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    synchronised&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;sim_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;sim_res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10000&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;wire_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;sin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;const_offset&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;offset_sin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;ramp_probe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;ramp_plot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;offset_sin_probe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;sin_plot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;pwm_bool&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;on_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;off_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="s"&gt;&amp;#39;pwm_value&amp;#39;&lt;/span&gt;&lt;br /&gt;                  &lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;raw_wires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MakeChans&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wire_names&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;wires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;wire_names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw_wires&lt;/span&gt; &lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;ramp_src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Ramp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp_probe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;simulation_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;sin_src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CTSinGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;sin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;amplitude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timestep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sim_res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;simulation_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;const_src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;const_offset&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;simulation_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;offset_sin_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Summer&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;sin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;const_offset&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;offset_sin_probe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;ramp_cloning_probe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Copier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp_probe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp_plot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;ramp_plotter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Plotter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp_plot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;sin_cloning_probe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Copier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;offset_sin_probe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;offset_sin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;sin_plot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;sin_plotter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Plotter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;sin_plot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="c"&gt;# Output = sin - ramp&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;subtractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Subtractor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;offset_sin&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ramp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="c"&gt;# Want to see when that is &amp;gt; 0&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;comparison&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GreaterThan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;pwm_bool&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;boolean_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;if_device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PassThrough&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;pwm_bool&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;on_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;pwm_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;else_data_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;off_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;output_value_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;on_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;simulation_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;output_value_off&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;off_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolution&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;simulation_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sim_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;pwm_plotter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Plotter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wires&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;pwm_value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;components&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ramp_src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;br /&gt;                  &lt;span class="n"&gt;sin_src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;const_src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;offset_sin_sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;ramp_cloning_probe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;br /&gt;                  &lt;span class="n"&gt;ramp_plotter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;br /&gt;                  &lt;span class="n"&gt;sin_cloning_probe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;br /&gt;                  &lt;span class="n"&gt;sin_plotter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;br /&gt;                  &lt;span class="n"&gt;subtractor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;comparison&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;if_device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;output_value_on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;output_value_off&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;                  &lt;span class="n"&gt;pwm_plotter&lt;/span&gt;&lt;br /&gt;                  &lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Starting simulation&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Finished starting actors&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;The program will stay &amp;quot;running&amp;quot; while the plot is open&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;br /&gt;&lt;br /&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Finished running simulation&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;run_multi_sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And here is the output:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lewp47C9PZI/SyWf7pPfCmI/AAAAAAAAA3A/CUq5gkUASMk/s1600-h/pwm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="255" src="http://2.bp.blogspot.com/_lewp47C9PZI/SyWf7pPfCmI/AAAAAAAAA3A/CUq5gkUASMk/s400/pwm.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This relatively simple model has 15 threads, and takes no time at all to run. There is still a long way to go, but if you are interested check out the project homepage on google code: &lt;a href="http://scipy-sim.googlecode.com/"&gt;http://scipy-sim.googlecode.com&lt;/a&gt;&lt;br /&gt;Or clone the source directly with:&amp;nbsp;hg clone https://scipy-sim.googlecode.com/hg/ scipy-sim&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-7212171224416728866?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/7212171224416728866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/12/scipy-simulator.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7212171224416728866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7212171224416728866'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/12/scipy-simulator.html' title='SciPy-Simulator'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lewp47C9PZI/SyWf7pPfCmI/AAAAAAAAA3A/CUq5gkUASMk/s72-c/pwm.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1398455594998675474</id><published>2009-12-07T23:06:00.000-08:00</published><updated>2009-12-07T23:06:50.694-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Learning Games'/><category scheme='http://www.blogger.com/atom/ns#' term='computer vision'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='Opensource Interface'/><category scheme='http://www.blogger.com/atom/ns#' term='AR'/><title type='text'>Open Allure DS</title><content type='html'>&lt;a href="http://code.google.com/p/open-allure-ds/"&gt;        &lt;img alt="Logo" src="http://code.google.com/p/open-allure-ds/logo?logo_id=1259864027" /&gt; &lt;span style="font-size: large;"&gt;     &lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: x-large;"&gt;Open Allure DS&lt;/span&gt;&lt;br /&gt;An open source project that I have started with John Graves a PHD student in Auckland for a smart computer interface for tutoring. Haven't really had an opportunity to start hacking away yet - but I am really hoping to find some time to chuck something together. It will possibly use my pycam module and speech recognition - ideally it will be cross platform and open source.&lt;br /&gt;&lt;br /&gt;&lt;div id="wikicontent" style="padding: 0pt 3em 1.2em 0pt;"&gt;To start with we are planning to create a learning game involving recognizing numbers and colors for the initial prototype. Interaction is based on a novel vision and speech based system instead of the mouse and keyboard. The learning game(s), initially aimed at preschool age children, teaching anything from recognizing numbers and colours to basic math. Interaction is based on a novel vision and speech based system instead of the mouse and keyboard.&lt;br /&gt;&lt;br /&gt;A very early vision of what it might look like...&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://wave.googleusercontent.com/wave/attachment/gameidea?id=4eSRbdoA2&amp;amp;key=AH0qf5yKEYriqS2ShDoVsfkGtMRRzkkqrA" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="https://wave.googleusercontent.com/wave/attachment/gameidea?id=4eSRbdoA2&amp;amp;key=AH0qf5yKEYriqS2ShDoVsfkGtMRRzkkqrA" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Each column is a different color or contains a different letter (or different number or animal...) and you have to move your body left or right into the column the program specifies (vocally) in order to advance to the next problem. All other control is done with voice, eg giving up, asking for a hint, changing between the modes... quiting etc Some of the problems could be posed graphically but need a speech answer.&lt;br /&gt;Written in the Python programming language using pygame and dragonfly.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Possible activities for the prototype include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Choosing a color - the colors name could be spoken and/or displayed on screen, or it could be phrased more like a question eg "What colour is grass?" (This would be an appropriate problem for under 5 year olds or 5 to 6 year old children with learning difficulties)&lt;/li&gt;&lt;li&gt;Counting up to 10 - Could display 5 random digits and pose a question like what comes after 4... Or could say outloud the name of a digit eg "one" and the player has to select the correct character "1". This is aimed at a similar age as choosing a color - mostly preschool.&lt;/li&gt;&lt;li&gt;Selecting phonoms - for example the program could make the sounds "ka", "ta", "fa" etc and there would be different options presented to the player and they would have to select the appropriate one.&lt;span __wave_annotations="" __wave_xml="Activities&amp;lt;line&amp;gt;&amp;lt;/line&amp;gt;Possible activities include:&amp;lt;line t=&amp;quot;li&amp;quot;&amp;gt;&amp;lt;/line&amp;gt;Choosing a color - the colors name could be spoken and/or displayed on screen, or it could be phrased more like a question eg &amp;quot;What colour is grass?&amp;quot; (This would be an appropriate problem for under 5 year olds or 5 to 6 year old children with learning difficulties)&amp;lt;line t=&amp;quot;li&amp;quot;&amp;gt;&amp;lt;/line&amp;gt;Counting up to 10 - Could display 5 random digits and pose a question like what comes after 4... Or could say outloud the name of a digit eg &amp;quot;one&amp;quot; and the player has to select the correct character &amp;quot;1&amp;quot;. This is aimed at a similar age as choosing a color - mostly preschool.&amp;lt;line t=&amp;quot;li&amp;quot;&amp;gt;&amp;lt;/line&amp;gt;Selecting phonoms - for example the program could make the sounds &amp;quot;ka&amp;quot;, &amp;quot;ta&amp;quot;, &amp;quot;fa&amp;quot; etc and there would be different options presented to the player and they would have to select the appropriate one." class="__wave_paste"&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Project Homepage: &lt;a href="http://open-allure-ds.googlecode.com/" target="_blank"&gt;http://open-allure-ds.googlecode.com&lt;/a&gt; &lt;br /&gt;Code is housed using Mecurial: &lt;a href="http://code.google.com/p/open-allure-ds/source/checkout" target="_blank"&gt;http://code.google.com/p/open-allure-ds/source/checkout&lt;/a&gt;&lt;br /&gt;We also have a Wave - it will be made public at some stage - just needs cleaning up! &lt;br /&gt;&lt;br /&gt;A slightly more realistic view:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://wave.googleusercontent.com/wave/attachment/091126%20Selection.jpg?id=WqY5ZoFQ7&amp;amp;key=AH0qf5wC3iPkgQTLJszdFZPFRJ0a6aulCg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="290" src="https://wave.googleusercontent.com/wave/attachment/091126%20Selection.jpg?id=WqY5ZoFQ7&amp;amp;key=AH0qf5wC3iPkgQTLJszdFZPFRJ0a6aulCg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If you are interested - pop over to open-allure-ds.googlecode.com or leave a comment here.&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1398455594998675474?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1398455594998675474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/12/open-allure-ds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1398455594998675474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1398455594998675474'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/12/open-allure-ds.html' title='Open Allure DS'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-2982456730647749554</id><published>2009-11-23T15:07:00.000-08:00</published><updated>2009-11-23T15:07:03.102-08:00</updated><title type='text'>Eptidy</title><content type='html'>Last summer my flatmates and I made a TV episode tidying program - called eptidy. Its found at &lt;a href="http://eptidy.googlecode.com/"&gt;http://eptidy.googlecode.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a screenshot:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lewp47C9PZI/SwsVjMM_kdI/AAAAAAAAAno/vCQwZvux0pA/s1600/Screenshot-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="232" src="http://2.bp.blogspot.com/_lewp47C9PZI/SwsVjMM_kdI/AAAAAAAAAno/vCQwZvux0pA/s400/Screenshot-1.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-2982456730647749554?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/2982456730647749554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/eptidy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2982456730647749554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2982456730647749554'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/eptidy.html' title='Eptidy'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lewp47C9PZI/SwsVjMM_kdI/AAAAAAAAAno/vCQwZvux0pA/s72-c/Screenshot-1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-6022999775401351148</id><published>2009-11-18T23:55:00.000-08:00</published><updated>2009-11-18T23:56:34.463-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax highlighting'/><title type='text'>Python syntax highlighting</title><content type='html'>Command line tool called pygmentize:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;pygmentize -f html moretkagain.py &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;copy output straight into blogger.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-6022999775401351148?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/6022999775401351148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/python-syntax-highlighting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6022999775401351148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6022999775401351148'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/python-syntax-highlighting.html' title='Python syntax highlighting'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-4526822126325238537</id><published>2009-11-18T23:50:00.000-08:00</published><updated>2009-11-18T23:55:17.933-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><category scheme='http://www.blogger.com/atom/ns#' term='pylab'/><category scheme='http://www.blogger.com/atom/ns#' term='matplotlib'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Animations with matplotlib</title><content type='html'>For some reason this wasn't overly clear in the documentation, but a simple way to make an animation using the default backend in matplotlib is something like this:&lt;br /&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arange&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;plt&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ion&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;"starting"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'d-'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;200&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.500000&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_axes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autoscale_view&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c"&gt;# redraw the canvas&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-4526822126325238537?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/4526822126325238537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/animations-with-matplotlib.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/4526822126325238537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/4526822126325238537'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/animations-with-matplotlib.html' title='Animations with matplotlib'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-585521383838389783</id><published>2009-11-15T13:38:00.000-08:00</published><updated>2009-11-15T13:38:05.621-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computer vision'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='kiwipycon'/><title type='text'>Kiwi Pycon 2009 - Basic Computer Vision in Python</title><content type='html'>Well I have given my first ever conference talk! Wasn't any where near as scary as I'd feared and all my live python demos using the webcam worked fine.&amp;nbsp;My slides have been uploaded on slideshare &lt;a href="http://www.slideshare.net/hardbyte/python-in-computer-vision"&gt;here&lt;/a&gt;. Heaps of random snippets from the weekend made it onto &lt;a href="http://twitter.com/#search?q=kiwipycon"&gt;twitter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_lewp47C9PZI/SwB0riaFGPI/AAAAAAAAAmY/kFhGCuKEuV4/s1600-h/me_kiwipycon.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_lewp47C9PZI/SwB0riaFGPI/AAAAAAAAAmY/kFhGCuKEuV4/s320/me_kiwipycon.jpg" width="240" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The conference had two main tracks, with delegates enjoying presentations on project management, science and maths, games and animation, and web development. There were also more interactive sessions with conference attendees participating in short presentations or open discussions on a specific theme.&lt;br /&gt;&lt;br /&gt;All in all I had a great weekend at the conference, learnt heaps and made some new contacts in the Python community.&amp;nbsp;The maths exam the following day wasn't to bad either. Now the next challenge - concurrent systems&amp;nbsp;modelling for scipy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-585521383838389783?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/585521383838389783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/kiwi-pycon-2009-basic-computer-vision.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/585521383838389783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/585521383838389783'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/11/kiwi-pycon-2009-basic-computer-vision.html' title='Kiwi Pycon 2009 - Basic Computer Vision in Python'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lewp47C9PZI/SwB0riaFGPI/AAAAAAAAAmY/kFhGCuKEuV4/s72-c/me_kiwipycon.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-6014194261168374513</id><published>2009-09-29T17:22:00.000-07:00</published><updated>2009-09-29T17:22:09.214-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pycam'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Bring your hat!</title><content type='html'>So thought I would make a really simple example of how pygame can be used with a webcam. This example uses opencv to detect a face, then pygame to draw a "hat".&lt;br /&gt;&lt;br /&gt;&lt;div class="syntax"&gt;&lt;pre&gt;#!/usr/bin/python&lt;br /&gt;from pycam import VideoCapturePlayer&lt;br /&gt;from pycam import pygameFaceDetect&lt;br /&gt;import pygame&lt;br /&gt;from pygame.locals import *&lt;br /&gt;&lt;br /&gt;def process(surf):&lt;br /&gt;    faces = pygameFaceDetect.getFaces(surf)&lt;br /&gt;    if faces:&lt;br /&gt;        s = pygameFaceDetect.faceDetect.image_scale&lt;br /&gt;        for face in faces:&lt;br /&gt;            pointsInHat = [ (face.x*s, face.y*s),&lt;br /&gt;                            (face.x*s + face.width*s, face.y*s),&lt;br /&gt;                            (face.x*s + face.width*s/2, face.y*s - face.height*s/2 )   ]&lt;br /&gt;            pygame.draw.polygon(surf, Color("red"), pointsInHat)&lt;br /&gt;            pygame.draw.polygon(surf, Color("black"), pointsInHat, 10)&lt;br /&gt;    return surf&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;    vcp = VideoCapturePlayer(processFunction=process)&lt;br /&gt;    vcp.main()&lt;br /&gt;    pygame.quit()&lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;And the&amp;nbsp;obligatory&amp;nbsp;screen shot:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_lewp47C9PZI/SsKj-boNeFI/AAAAAAAAAkU/cNTPTjxUtjI/s1600-h/hatme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://3.bp.blogspot.com/_lewp47C9PZI/SsKj-boNeFI/AAAAAAAAAkU/cNTPTjxUtjI/s320/hatme.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I would love to have some time to make a game or two now! Maybe pong?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-6014194261168374513?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/6014194261168374513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/bring-your-hat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6014194261168374513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6014194261168374513'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/bring-your-hat.html' title='Bring your hat!'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lewp47C9PZI/SsKj-boNeFI/AAAAAAAAAkU/cNTPTjxUtjI/s72-c/hatme.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-3139693790619193907</id><published>2009-09-16T22:09:00.000-07:00</published><updated>2009-09-16T22:38:44.866-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pycam'/><category scheme='http://www.blogger.com/atom/ns#' term='computer vision'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Greenscreen</title><content type='html'>Something used heaps in the film industry is the "&lt;span style="font-style: italic;"&gt;Greenscree&lt;/span&gt;n" I thought I would take a quick look at how to make a  greenscreen that works fast enough to run on a live webcam stream. And infact one that works with any coloured background. It has many many limitations, but was a fun experiment! To run this example you will need OpenCV with the SWIG Python bindings installed. You can get this code from my SVN repository &lt;a href="http://code.google.com/p/pycam/source/browse/trunk/speed/back_sub_opencv.py"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Firstly the background I started with:&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_lewp47C9PZI/SrGxBlSqOnI/AAAAAAAAAiw/VQzUnIZxk6g/blank.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" height="74" src="http://lh6.ggpht.com/_lewp47C9PZI/SrGxBlSqOnI/AAAAAAAAAiw/VQzUnIZxk6g/blank.jpg" style="display: block; height: 499px; margin-bottom: 10px; margin-left: auto; margin-right: auto; margin-top: 0px; text-align: center; width: 400px;" width="96" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Adding an object to the scene, and carrying out back ground subtraction:&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_lewp47C9PZI/SrGxCca6nHI/AAAAAAAAAi4/f37sknEtFfM/output.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" height="96" src="http://lh5.ggpht.com/_lewp47C9PZI/SrGxCca6nHI/AAAAAAAAAi4/f37sknEtFfM/output.jpg" style="display: block; height: 501px; margin-bottom: 10px; margin-left: auto; margin-right: auto; margin-top: 0px; text-align: center; width: 400px;" width="76" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So anyhow the code:&lt;br /&gt;&lt;div class="syntax"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;VideoCapturePlayer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VideoCapturePlayer&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;VCP&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;opencv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;threshold_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Record the first 5 images to get a background, then diff current frame with the last saved frame.&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# n[4] will be our background&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# First capture a few images&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvCloneMat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class="c"&gt;# last time here &lt;/span&gt;&lt;br /&gt;            &lt;span class="c"&gt;# could do averaging here.&lt;/span&gt;&lt;br /&gt;            &lt;span class="k"&gt;pass&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;differenceImage&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvCloneMat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvAbsDiff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;differenceImage&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;thresholdValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;50&lt;/span&gt;     &lt;span class="c"&gt;# 32 &lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvThreshold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;differenceImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;differenceImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thresholdValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CV_THRESH_BINARY&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvSmooth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;differenceImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;differenceImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CV_MEDIAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;gray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvCreateImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvGetSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;differenceImage&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvCvtColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;differenceImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CV_BGR2GRAY&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;   &lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;result&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvCloneMat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvSetZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvAnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Background Subtraction Output&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;VCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threshold_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Some objects don't work so well. Output is very noisy.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lh5.ggpht.com/_lewp47C9PZI/SrGxDh19KzI/AAAAAAAAAi8/CtMS27Phxho/noise.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0"  src="http://lh5.ggpht.com/_lewp47C9PZI/SrGxDh19KzI/AAAAAAAAAi8/CtMS27Phxho/noise.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now there is nothing to say a green background must be used at all, so what about just using my desk as the background:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lh4.ggpht.com/_lewp47C9PZI/SrGxEHWCa3I/AAAAAAAAAjA/-cbVfyATG5s/blank-desk.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://lh4.ggpht.com/_lewp47C9PZI/SrGxEHWCa3I/AAAAAAAAAjA/-cbVfyATG5s/blank-desk.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And adding my highlighter to the desk...&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lh5.ggpht.com/_lewp47C9PZI/SrGxEm69PwI/AAAAAAAAAjI/SRh5Cm3RHGE/desk-output.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://lh5.ggpht.com/_lewp47C9PZI/SrGxEm69PwI/AAAAAAAAAjI/SRh5Cm3RHGE/desk-output.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And a simple shot showing the final scene to show I didn't cheat.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lh5.ggpht.com/_lewp47C9PZI/SrGxEeUGYWI/AAAAAAAAAjE/UtQoXtrT6fk/desk-pen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://lh5.ggpht.com/_lewp47C9PZI/SrGxEeUGYWI/AAAAAAAAAjE/UtQoXtrT6fk/desk-pen.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And there you have it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-3139693790619193907?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/3139693790619193907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/greenscreen.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3139693790619193907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3139693790619193907'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/greenscreen.html' title='Greenscreen'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_lewp47C9PZI/SrGxBlSqOnI/AAAAAAAAAiw/VQzUnIZxk6g/s72-c/blank.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-5311183912622568705</id><published>2009-09-11T01:11:00.000-07:00</published><updated>2009-09-11T01:35:48.286-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='harris'/><category scheme='http://www.blogger.com/atom/ns#' term='kiwipycon'/><title type='text'>Kiwi Pycon</title><content type='html'>&lt;div style="text-align: center;"&gt;I have been looking at harris feature detection lately. Implementing it side by side in OpenCV and SciPy, luckily for &lt;span class="Apple-style-span" style="font-size: medium;"&gt;me a SciPy implementation by Jan Solem&lt;/span&gt;&lt;span class="Apple-style-span"   style="font-family:'Trebuchet MS', Trebuchet, Arial, Verdana, sans-serif;color:#999999;"&gt;&lt;span class="Apple-style-span" style=" letter-spacing: 1px; line-height: 16px; text-transform: uppercase;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="  color: rgb(153, 153, 153); font-weight: bold; letter-spacing: 1px; line-height: 16px; text-transform: uppercase; font-family:'Trebuchet MS', Trebuchet, Arial, Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"  style="color: rgb(0, 0, 0);  font-weight: normal; letter-spacing: normal; line-height: normal; text-transform: none;  font-family:Georgia, serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;was found on this &lt;/span&gt;&lt;a href="http://jesolem.blogspot.com/2009/01/harris-corner-detector-in-python.html"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;blog&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;. As I was going through &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color: rgb(0, 0, 0);  font-weight: normal; letter-spacing: normal; line-height: normal; text-transform: none;  font-family:Georgia, serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;the code, I wanted to get my head around what was happening. So using these two lines:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;from IPython.Shell import IPShellEmbed&lt;/div&gt;&lt;div&gt;IPShellEmbed()()&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;This piece of magic can be put anywhere, right deep inside a nested loop, inside a function called from X via Y via Z etc. And it obviously pops you right into the brilliant IPython shell, with the full normal IPython luxuries like timeit, history, autocomplete, pylab plotting... So I plotted a few images midway through processing, just to see what the program sees.&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lewp47C9PZI/SqoG69m_unI/AAAAAAAAAhE/8MmyiOBCtWE/s1600-h/grayscaleimagepng.png"&gt;&lt;img src="http://3.bp.blogspot.com/_lewp47C9PZI/SqoG69m_unI/AAAAAAAAAhE/8MmyiOBCtWE/s320/grayscaleimagepng.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5380120314887780978" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 241px; " /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lewp47C9PZI/SqoG71tVvVI/AAAAAAAAAhU/KLshu2_rRj0/s1600-h/y+derivativespng.png"&gt;&lt;/a&gt;&lt;div&gt;First is the grayscale image taken from my webcam. No I'm not colour blind - I realize I have plotted it in colour.... Second and thirdly the two gaussian derivatives of the image, one in X and one in Y.&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lewp47C9PZI/SqoG71tVvVI/AAAAAAAAAhU/KLshu2_rRj0/s1600-h/y+derivativespng.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 241px;" src="http://1.bp.blogspot.com/_lewp47C9PZI/SqoG71tVvVI/AAAAAAAAAhU/KLshu2_rRj0/s320/y+derivativespng.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5380120329946774866" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lewp47C9PZI/SqoG7RSY-eI/AAAAAAAAAhM/t5WaKMRneaI/s1600-h/x_derivativespng.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 241px;" src="http://2.bp.blogspot.com/_lewp47C9PZI/SqoG7RSY-eI/AAAAAAAAAhM/t5WaKMRneaI/s320/x_derivativespng.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5380120320170064354" /&gt;&lt;/a&gt;&lt;a href="http://www.blogger.com/img/blank.gif"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lewp47C9PZI/SqoLFRzMnKI/AAAAAAAAAhc/Y7jcQ2gyzu8/s1600-h/Screenshot-2.png"&gt;&lt;img src="http://2.bp.blogspot.com/_lewp47C9PZI/SqoLFRzMnKI/AAAAAAAAAhc/Y7jcQ2gyzu8/s320/Screenshot-2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5380124890152869026" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 250px; " /&gt;&lt;/a&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span"  style="color:#0000EE;"&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;And a bit later after getting the thing going - the final  output! Pretty cool to see how it came about with the two derivatives convolved together. Some filtering to choose spread out points (clearly not working) and then drawing dots! The code for this in OpenCV and in SciPy is &lt;a href="http://code.google.com/p/pycam/source/browse/trunk/speed/harris_scipy.py"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Oh and check it out - &lt;a href="http://nz.pycon.org/talks/talk/18/"&gt;my first conference presentation&lt;/a&gt;! &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ahh, I'm going to have to prepare something now!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-5311183912622568705?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/5311183912622568705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/kiwi-pycon.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/5311183912622568705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/5311183912622568705'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/kiwi-pycon.html' title='Kiwi Pycon'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lewp47C9PZI/SqoG69m_unI/AAAAAAAAAhE/8MmyiOBCtWE/s72-c/grayscaleimagepng.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-2164022421328414551</id><published>2009-09-04T23:20:00.000-07:00</published><updated>2009-09-05T05:07:54.957-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='signals'/><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Gaussian Blur</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span"  style="color:#0000EE;"&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span"  style="color:#0000EE;"&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lewp47C9PZI/SqJSUG7MJEI/AAAAAAAAAgs/s8aSE0FBCwI/s1600-h/lena_diff_ndfilt_iir.png"&gt;&lt;/a&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Trying to work out why the gaussian blur in OpenCV is different from that of SciPy...&lt;/div&gt;&lt;div&gt;The differences are too small to see, but are still there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Following is an imshow of each channel of the difference image.&lt;/div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_lewp47C9PZI/SqJSE-P0QDI/AAAAAAAAAgc/VD9iOtzl9F0/s1600-h/lena_opencv_ndfilt_iir.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lewp47C9PZI/SqIEHFH1EGI/AAAAAAAAAgU/0H50ceb8k7M/s1600-h/Screenshot2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 166px;" src="http://2.bp.blogspot.com/_lewp47C9PZI/SqIEHFH1EGI/AAAAAAAAAgU/0H50ceb8k7M/s320/Screenshot2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5377865424714403938" /&gt;&lt;/a&gt;And by looking at a singe row, we see that the difference spikes the whole intensity range.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lewp47C9PZI/SqIEG3PcAzI/AAAAAAAAAgM/GD2z-Zx7hg8/s1600-h/Screenshot3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 211px;" src="http://4.bp.blogspot.com/_lewp47C9PZI/SqIEG3PcAzI/AAAAAAAAAgM/GD2z-Zx7hg8/s320/Screenshot3.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5377865420988220210" /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Edit: That was pretty much staring me in the face wasn't it... uint8's are prone to integer overflow!&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.blogger.com/img/blank.gif"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Comparing the OpenCV implementation with two versions in SciPy now gives:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lewp47C9PZI/SqJSij80bjI/AAAAAAAAAg0/PFoWpCJX3gk/s1600-h/lena_opencv_ndfilt_iir.png"&gt;&lt;img src="http://3.bp.blogspot.com/_lewp47C9PZI/SqJSij80bjI/AAAAAAAAAg0/PFoWpCJX3gk/s320/lena_opencv_ndfilt_iir.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5377951658753158706" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 131px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Doing a pixel for pixel comparison on each channel between the SciPy and OpenCV examples:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lewp47C9PZI/SqJUN8qYLPI/AAAAAAAAAg8/eqHVYKICPzU/s1600-h/gaussian_diffs.png"&gt;&lt;img src="http://4.bp.blogspot.com/_lewp47C9PZI/SqJUN8qYLPI/AAAAAAAAAg8/eqHVYKICPzU/s320/gaussian_diffs.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5377953503632698610" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 241px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lewp47C9PZI/SqJSUG7MJEI/AAAAAAAAAgs/s8aSE0FBCwI/s1600-h/lena_diff_ndfilt_iir.png"&gt;&lt;img src="http://1.bp.blogspot.com/_lewp47C9PZI/SqJSUG7MJEI/AAAAAAAAAgs/s8aSE0FBCwI/s320/lena_diff_ndfilt_iir.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5377951410443527234" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 155px; " /&gt;&lt;/a&gt;The second one is comparing an IIR filter implementation to a ndfilt.&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span"  style="color:#0000EE;"&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-2164022421328414551?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/2164022421328414551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/gaussian-blur.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2164022421328414551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2164022421328414551'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/gaussian-blur.html' title='Gaussian Blur'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lewp47C9PZI/SqIEHFH1EGI/AAAAAAAAAgU/0H50ceb8k7M/s72-c/Screenshot2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-6468623526071565427</id><published>2009-09-03T00:22:00.000-07:00</published><updated>2009-09-03T00:41:49.089-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Decoration to the rescue!</title><content type='html'>&lt;div class="syntax"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;scipy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;opencv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;adaptors&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;scipyFromOpenCV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;This decorator can be used to wrap a function that takes &lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    and returns a numpy array into one that takes and retuns an&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    opencv CvMat.&lt;/span&gt;&lt;br /&gt;&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;    &lt;br /&gt;&lt;br /&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# Convert CvMat to ndarray&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;np_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adaptors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ipl2NumPy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class="c"&gt;# Call the original function&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;np_image_filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class="c"&gt;# Convert back to CvMat&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;adaptors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumPy2Ipl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np_image_filtered&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="nd"&gt;@scipyFromOpenCV&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slowGaussianBlur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Manual gaussian blur - Very very very slow!&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;filterSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;filt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gauss_kern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filterSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[:,:,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;filt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;same&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[:,:,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;filt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;same&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[:,:,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;filt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;same&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uint8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transpose&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-6468623526071565427?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/6468623526071565427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/decoration-to-rescue.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6468623526071565427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6468623526071565427'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/09/decoration-to-rescue.html' title='Decoration to the rescue!'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-2255351460548104693</id><published>2009-08-12T23:01:00.000-07:00</published><updated>2009-08-12T23:20:11.069-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pycam'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Windows + Pygame + VidCap</title><content type='html'>&lt;div style="text-align: left;"&gt;So I thought I would try out the &lt;a href="http://code.google.com/p/pycam/"&gt;pycam &lt;/a&gt;module on windows.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First of all it seems windows comes with nothing, not even python. So after installing python I still needed this: &lt;a href="http://videocapture.sourceforge.net/"&gt;http://videocapture.sourceforge.net/&lt;/a&gt;&lt;div&gt;&lt;div&gt;and this: &lt;a href="http://pygame.org/ftp/pygame-1.9.1.win32-py2.5.msi"&gt;http://pygame.org/ftp/pygame-1.9.1.win32-py2.5.msi&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vid cap itself is so easy:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'times new roman'; "&gt;&lt;pre&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;from VideoCapture import Device cam = Device() cam.saveSnapshot('image.jpg')&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To get just the most basic stuff going, for some reason the VidCap module wouldn't let me open a camera unless the size was set at (160, 120) and the Camera class seemed to change going to windows... anyhow if you want to play with this grab it from the repo &lt;a href="http://code.google.com/p/pycam/source/browse/branches/windows-branch/pycam/VideoCapturePlayer.py#"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;img src="http://3.bp.blogspot.com/_lewp47C9PZI/SoOtAb9MLEI/AAAAAAAAAfc/tv4Xu-aNFDE/s320/win-edge.PNG" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 211px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5369325403771776066" /&gt;&lt;div style="text-align: left;"&gt;This is using the pygame edge detect, just tried the scipy one - appears to be a problem mapping surface to numpy array... from memory there was a hack to get around something so maybe thats no longer required. &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://2.bp.blogspot.com/_lewp47C9PZI/SoOtG2r5MAI/AAAAAAAAAfk/CMKX1uagNgo/s320/win-green.PNG" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 270px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5369325514026201090" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;The "greenscreen" example and the simple threshold.&lt;/div&gt;&lt;img src="http://4.bp.blogspot.com/_lewp47C9PZI/SoOtHva4lTI/AAAAAAAAAfs/rGoiNv0KPpw/s320/win-thresh.PNG" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 172px; height: 147px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5369325529255679282" /&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Couldn't immediatly see how to get the python wrappings for swig going on windows, and all the face detection stuff won't work untill they are installed correctly. I did rebuild opencv in visual studio and all the C examples work fine, Windows and Python don't seem to get along that well. Anyhow I don't plan on looking into it in a hurry. Do people actually still use windows? (Why?)&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-2255351460548104693?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/2255351460548104693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/08/windows-pygame-vidcap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2255351460548104693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2255351460548104693'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/08/windows-pygame-vidcap.html' title='Windows + Pygame + VidCap'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lewp47C9PZI/SoOtAb9MLEI/AAAAAAAAAfc/tv4Xu-aNFDE/s72-c/win-edge.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1917737330710100543</id><published>2009-08-12T19:57:00.000-07:00</published><updated>2009-08-12T19:57:01.770-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='matplotlib'/><category scheme='http://www.blogger.com/atom/ns#' term='Spyder'/><category scheme='http://www.blogger.com/atom/ns#' term='matlab'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><title type='text'>Spyder</title><content type='html'>&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Enter the new matlab contender, Spyder:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_lewp47C9PZI/SoN9zqHw2CI/AAAAAAAAAfU/slz1JzN9Q8E/s1600-h/pydee.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_lewp47C9PZI/SoN9zqHw2CI/AAAAAAAAAfU/slz1JzN9Q8E/s400/pydee.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;This would have been pretty handy over the last summer! All the pylab, scipy and numpy docs. The matplotlib integration is key. Eventually it would be awesome to see pydb and stepping through python scripts like you can for m files in matlab. But this is a huge step in the right direction!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;This is also my first post from Windows, good to see that Python(x,y) has been coming along nicely since I last looked at it. I will see how this Pydee (renamed to Spyder) goes on all three platforms that I now use.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1917737330710100543?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1917737330710100543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/08/spyder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1917737330710100543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1917737330710100543'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/08/spyder.html' title='Spyder'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lewp47C9PZI/SoN9zqHw2CI/AAAAAAAAAfU/slz1JzN9Q8E/s72-c/pydee.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-2266415753100121524</id><published>2009-07-20T01:15:00.000-07:00</published><updated>2009-07-20T01:15:09.302-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Opencv source on Ubuntu 9.10</title><content type='html'>The &lt;a href="http://opencv.willowgarage.com/wiki/InstallGuide"&gt;build instructions&lt;/a&gt; for opencv really didn't make it clear how to go about building opencv. Well the ./configure command kept failing...&lt;br /&gt;So for my own reference, use the cmake method not autotools.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li style="list-style-type: none;"&gt;&lt;div class="line891"&gt;&lt;tt&gt;cd&amp;nbsp;~/projects/opencv&amp;nbsp;#&amp;nbsp;the&amp;nbsp;directory&amp;nbsp;containing&amp;nbsp;INSTALL,&amp;nbsp;CMakeLists.txt&amp;nbsp;etc.&amp;nbsp;&lt;/tt&gt; &lt;span class="anchor" id="line-65"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;&lt;div class="line891"&gt;&lt;tt&gt;mkdir&amp;nbsp;release&amp;nbsp;&lt;/tt&gt; &lt;span class="anchor" id="line-66"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;&lt;div class="line891"&gt;&lt;tt&gt;cd&amp;nbsp;release&amp;nbsp;&lt;/tt&gt; &lt;span class="anchor" id="line-67"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;&lt;div class="line891"&gt;&lt;tt&gt;cmake&amp;nbsp;-D&amp;nbsp;CMAKE_BUILD_TYPE=RELEASE&amp;nbsp;-D&amp;nbsp;CMAKE_INSTALL_PREFIX=/usr/local&amp;nbsp;-D&amp;nbsp;BUILD_PYTHON_SUPPORT=ON&amp;nbsp;../&lt;/tt&gt;&lt;/div&gt;&lt;div class="line891"&gt;&lt;tt&gt;make&lt;/tt&gt;&lt;/div&gt;&lt;div class="line891"&gt;&lt;tt&gt; sudo make install&lt;/tt&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-2266415753100121524?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/2266415753100121524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/opencv-source-on-ubuntu-910.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2266415753100121524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2266415753100121524'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/opencv-source-on-ubuntu-910.html' title='Opencv source on Ubuntu 9.10'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-5404521086079717565</id><published>2009-07-15T19:07:00.000-07:00</published><updated>2009-07-15T19:07:07.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='im'/><title type='text'>Instant Messaging, Threading and Sockets</title><content type='html'>So we were given an assignment for software today. It's going to be used to teach us promala and spin and good multi-threaded software practices. The overall goal is to make a simple GUI based multi-user instant messager system in C++.&lt;br /&gt;I haven't used allot of concurrency before so I thought I would investigate by trying some stuff out in python. Also I haven't used sockets directly before - so wanted to have a look at them.&lt;br /&gt;&lt;br /&gt;Firstly taking a read of the &lt;a href="http://docs.python.org/howto/sockets.html"&gt;Socket Programming HOWTO guide&lt;/a&gt; - there is plenty of information there. And also handy is the &lt;a href="http://docs.python.org/library/socket.html"&gt;Socket documentation&lt;/a&gt; for python.&lt;br /&gt;&lt;br /&gt;For now I just want a echoing server that can service multiple clients at once.&lt;br /&gt;&lt;br /&gt;So the server will be the difficult part - might as well dive in there!&lt;br /&gt;&lt;br /&gt;Firstly creating a socket and echoing any data it recieves is pretty easy with this loop:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;while True:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = self.conn.recv(1024)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not data:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.conn.send(data)&lt;/span&gt;&lt;/blockquote&gt;Now wraping this up in a thread than can be started at any time is straighforward. And for good measure I'll add some logging in at the same time.&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class AsyncEcho(threading.Thread):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def __init__(self, conn, addr):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; threading.Thread.__init__(self)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.conn = conn&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.addr = repr(addr) # Note just storing string for identification purposes&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def run(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.info("Starting to run thread for client: %s" % self.addr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while True:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.debug("server waiting to receive from client: %s" % self.addr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = self.conn.recv(1024)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not data:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.debug("Connection to client '%s' complete. Breaking connection" % self.addr)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.debug('Server received: "%s" from client "%s", sending back...' % (data,self.addr))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.conn.send(data)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.info('Finished background servicing of client: %s' % self.addr)&lt;/blockquote&gt;&lt;br /&gt;&amp;nbsp;And the rest of the script that actually starts these threads, minus the imports:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.info("Server started")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Created a socket on the server")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s.bind((HOST, PORT))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Server Socket has been bound. Server is ready to accept connections")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;while True:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.listen(5) # We want to queue up at most 5 requests&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.debug("Main thread of server listening for new connections")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn, addr = s.accept()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.info('New connection by &amp;lt;%s&amp;gt;' %&amp;nbsp; repr(addr))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.debug("Socket Object: %s" % repr(conn)) &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; background = AsyncEcho(conn, addr)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.info("Created a new thread object to service this client, about to start it.")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; background.start()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; logging.info('Started the thread, the main program continues to run in foreground.')&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&amp;nbsp;Now that wasn't too painful at all, the client is even easier. It needs to establish a connection via the socket with the server, then pass and receive data. Easy as:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;clientName = raw_input("Client Name: ")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;HOST = 'localhost'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # The remote host, could be differant to server...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Created a socket on the client")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s.connect((HOST, PORT))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Client socket connected")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Sending Client name")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;s.send(clientName)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Sent data, trying to receive now")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;data = s.recv(1024)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.debug("Data received '%s'" % data)&lt;/span&gt;&lt;/blockquote&gt;Now we might as well have a loop for the client so it acts more like a command line:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;logging.info("Start a loop. 'quit' will quit")&lt;br /&gt;while True:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = raw_input("&amp;gt;")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if data == "quit":&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s.send(data)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; data2 = s.recv(1024)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(data2)&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So starting up the server:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;brian@brian-hitlab:~/projects/python/instantmess/src$ python server.py &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INFO:root:Logger enabled&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INFO:root:Server started&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Created a socket on the server&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Server Socket has been bound. Server is ready to accept connections&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Main thread of server listening for new connections&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At this point the server just waits for a client to be started, so lets do that in another terminal:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;brian@brian-hitlab:~/projects/python/instantmess/src$ python client.py &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INFO:root:Logger enabled&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INFO:root:Client started&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Client Name: client1&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Created a socket on the client&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Client socket connected&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Sending Client name&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Sent data, trying to receive now&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Data received 'client1'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And then the loop:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INFO:root:Start a loop. 'quit' will quit&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt;Hi&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Hi&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt;this is a test&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;this is a test&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt;sweet&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sweet&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;gt;quit&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Closing socket&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Received 'quit'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;During all this the server was spitting out lots as well:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:server waiting to receive from client: ('127.0.0.1', 50535)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Server received: "Hi" from client "('127.0.0.1', 50535)", sending back...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:server waiting to receive from client: ('127.0.0.1', 50535)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Server received: "this is a test" from client "('127.0.0.1', 50535)", sending back...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:server waiting to receive from client: ('127.0.0.1', 50535)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Server received: "sweet" from client "('127.0.0.1', 50535)", sending back...&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:server waiting to receive from client: ('127.0.0.1', 50535)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DEBUG:root:Connection to client '('127.0.0.1', 50535)' complete. Breaking connection&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INFO:root:Finished background servicing of client: ('127.0.0.1', 50535)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Okay time for lunch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-5404521086079717565?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/5404521086079717565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/instant-messaging-threading-and-sockets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/5404521086079717565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/5404521086079717565'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/instant-messaging-threading-and-sockets.html' title='Instant Messaging, Threading and Sockets'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-4838937392822651896</id><published>2009-07-12T16:09:00.000-07:00</published><updated>2009-07-12T16:09:33.043-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='matplotlib'/><title type='text'>Matplotlib in Django</title><content type='html'>The official django tutorial is very good, it stops short of displaying&lt;br /&gt;&lt;div id="globalWrapper"&gt;&lt;div id="column-content"&gt;&lt;div id="content"&gt;&lt;div id="bodyContent"&gt;data with matplotlib - which could be very handy for dsp or automated&lt;br /&gt;testing. This is an extension to the tutorial. So first you must do the&lt;br /&gt;official tutorial!&lt;br /&gt;&lt;a class="external text" href="http://docs.djangoproject.com/en/dev/intro/tutorial01/" rel="nofollow" title="http://docs.djangoproject.com/en/dev/intro/tutorial01/"&gt;Complete the tutorial&lt;/a&gt; (as of writing this up to part 4).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;Adding an image to a view&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To start with we will take a static image from the hard drive and&lt;br /&gt;display it on the polls index page.&lt;br /&gt;Usually if it really is a static image this would be managed by the&lt;br /&gt;webserver eg apache. For introduction purposes we will get django to&lt;br /&gt;serve the static image. To do this we first need to change the&lt;br /&gt;template.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-create.g?blogID=9102179255330637934" name="Change_the_template"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;Change the template&lt;/h4&gt;&lt;br /&gt;At the moment poll_list.html probably looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-smarty"&gt;&amp;lt;h1&amp;gt;Django test app - Polls&amp;lt;/h1&amp;gt;&lt;br /&gt;{% if object_list %}&lt;br /&gt;&lt;br /&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;{% for object in object_list %}&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href="/polls/{{object.id}}"&amp;gt;{{ object.question }}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&lt;br /&gt;{% endfor %}&lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;{% else %}&lt;br /&gt;&lt;br /&gt;&amp;lt;p&amp;gt;No polls are available.&amp;lt;/p&amp;gt;&lt;br /&gt;{% endif %}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Change it by adding the line anywhere &lt;b&gt;outside&lt;/b&gt; of the special "{% template tags %}"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-html4strict"&gt;&amp;lt;img src="/polls/staticImage.png" width="500px"&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now if you reload your page - you should see a placeholder&lt;br /&gt;image, or nothing. If you view the source in your browser you should&lt;br /&gt;see the extra line we added. If we try to view just the image, eg going&lt;br /&gt;to &lt;a class="external autonumber" href="http://localhost:8000/polls/staticImage.png" rel="nofollow" title="http://localhost:8000/polls/staticImage.png"&gt;[1]&lt;/a&gt; we should see a django 404 (page not found error).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-create.g?blogID=9102179255330637934" name="Add_the_url_for_the_static_image_into_the_url_handler"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;Add the url for the static image into the url handler&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Now we must add a line in the urls.py file to link the image with a view:&lt;br /&gt;It should end up looking something like the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-python"&gt;from django.conf.urls.defaults import *&lt;br /&gt;from mysite.polls.models import Poll&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;info_dict = {&lt;br /&gt;'queryset': Poll.objects.all()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;urlpatterns = patterns('',&lt;br /&gt;(r'^$', 'django.views.generic.list_detail.object_list',info_dict),&lt;br /&gt;(r'^(?P&amp;lt;object_id&amp;gt;\d+)/$', 'django.views.generic.list_detail.object_detail',info_dict),&lt;br /&gt;url(r'^(?P&amp;lt;object_id&amp;gt;\d+)/results/$', 'django.views.generic.list_detail.object_detail',dict(info_dict,template_name="polls/results.html"),'poll_results'),&lt;br /&gt;(r'^(?P&amp;lt;poll_id&amp;gt;\d+)/vote/$', 'mysite.polls.views.vote'),&lt;br /&gt;(r'^staticImage.png$', 'mysite.polls.views.showStaticImage'),&lt;br /&gt;&lt;br /&gt;)&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This means we have to make a view called showStaticImage.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-create.g?blogID=9102179255330637934" name="Add_the_view_for_the_static_image"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;Add the view for the static image&lt;/h4&gt;&lt;br /&gt;Add a function to the views.py file as follows - replace the path with your own&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-python"&gt;def showStaticImage(request):&lt;br /&gt;""" Simply return a static image as a png """&lt;br /&gt;&lt;br /&gt;imagePath = "C:/Documents and Settings/thorneb/My Documents/Fiordland_Lake_Marian.png"&lt;br /&gt;from PIL import Image&lt;br /&gt;Image.init()&lt;br /&gt;i = Image.open(imagePath)&lt;br /&gt;&lt;br /&gt;response = HttpResponse(mimetype='image/png')&lt;br /&gt;i.save(response,'PNG')&lt;br /&gt;return response&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_lewp47C9PZI/SS8ES6GytmI/AAAAAAAAAV4/YQtlSR7z1tc/s1600-h/djangoTutStaticImage.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5273438411556042338" src="http://3.bp.blogspot.com/_lewp47C9PZI/SS8ES6GytmI/AAAAAAAAAV4/YQtlSR7z1tc/s400/djangoTutStaticImage.jpg" style="cursor: pointer; display: block; height: 400px; margin: 0px auto 10px; text-align: center; width: 306px;" /&gt;&lt;/a&gt;&lt;br /&gt;This point it is worth noting we have imported &lt;b&gt;PIL&lt;/b&gt; the python image library - it is not always included by default.&lt;br /&gt;&lt;br /&gt;Now if you try reload your poll index page - you should see whatever image you choose.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-create.g?blogID=9102179255330637934" name="Adding_a_dynamic_image"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Adding a dynamic image&lt;/h3&gt;&lt;br /&gt;Thats all well and good but we want to plot data, dynamically generated based on changing data.&lt;br /&gt;Keeping going with the polls app - lets plot the results automatically - so the results page shows a graph.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Add an image tag somewhere in the results template:&lt;br /&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-html4strict"&gt;&amp;lt;img src="result.png"&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Add another url clause:&lt;br /&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-python"&gt;(r'^(?P&amp;lt;poll_id&amp;gt;\d+)/results/result.png$', 'mysite.polls.views.plotResults')&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Add another new view:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;"&gt;&lt;pre class="source-python"&gt;def plotResults(request,poll_id):&lt;br /&gt;import matplotlib&lt;br /&gt;from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas&lt;br /&gt;from matplotlib.figure import Figure&lt;br /&gt;from matplotlib.dates import DateFormatter&lt;br /&gt;fig = Figure()&lt;br /&gt;&lt;br /&gt;ax=fig.add_subplot(1,1,1)&lt;br /&gt;p = get_object_or_404(Poll, pk=poll_id) # Get the poll object from django&lt;br /&gt;&lt;br /&gt;x = matplotlib.numpy.arange(1,p.choice_set.count())&lt;br /&gt;choices = p.choice_set.all()&lt;br /&gt;&lt;br /&gt;votes = [choice.votes for choice in choices]&lt;br /&gt;names = [choice.choice for choice in choices]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;numTests = p.choice_set.count()&lt;br /&gt;ind = matplotlib.numpy.arange(numTests) # the x locations for the groups&lt;br /&gt;&lt;br /&gt;cols = ['red','orange','yellow','green','blue','purple','indigo']*10&lt;br /&gt;&lt;br /&gt;cols = cols[0:len(ind)]&lt;br /&gt;ax.bar(ind, votes,color=cols)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ax.set_xticks(ind + 0.5)&lt;br /&gt;ax.set_xticklabels(names)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ax.set_xlabel("Choices")&lt;br /&gt;ax.set_ylabel("Votes")&lt;br /&gt;&lt;br /&gt;#ax.set_xticklabels(names)&lt;br /&gt;&lt;br /&gt;title = u"Dynamically Generated Results Plot for poll: %s" % p.question&lt;br /&gt;ax.set_title(title)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#ax.grid(True)&lt;br /&gt;canvas = FigureCanvas(fig)&lt;br /&gt;response = HttpResponse(content_type='image/png')&lt;br /&gt;&lt;br /&gt;canvas.print_png(response)&lt;br /&gt;return response&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I may have fabricated these votes :-P&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_lewp47C9PZI/SS8E3o22bdI/AAAAAAAAAWA/s22QGHbghWo/s1600-h/djangoTutDynamicImage.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5273439042580934098" src="http://2.bp.blogspot.com/_lewp47C9PZI/SS8E3o22bdI/AAAAAAAAAWA/s22QGHbghWo/s400/djangoTutDynamicImage.jpg" style="cursor: pointer; display: block; height: 289px; margin: 0px auto 10px; text-align: center; width: 400px;" /&gt;&lt;/a&gt;&lt;br /&gt;Hmm, sorry for the formating of this post - I'll try get back to it if I can find the original wiki page I made while at Tait.&lt;br /&gt;&lt;h3&gt;Links&lt;/h3&gt;&lt;a class="external text" href="http://djangoproject.com/" rel="nofollow" title="http://djangoproject.com"&gt;Official Django Site&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-4838937392822651896?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/4838937392822651896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/matplotlib-in-django.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/4838937392822651896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/4838937392822651896'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/matplotlib-in-django.html' title='Matplotlib in Django'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lewp47C9PZI/SS8ES6GytmI/AAAAAAAAAV4/YQtlSR7z1tc/s72-c/djangoTutStaticImage.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-7275697194915756909</id><published>2009-07-12T15:52:00.001-07:00</published><updated>2009-07-12T16:37:22.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pycam'/><category scheme='http://www.blogger.com/atom/ns#' term='HITLAB'/><category scheme='http://www.blogger.com/atom/ns#' term='xo'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Camera Histogram Demo</title><content type='html'>&lt;div&gt;&lt;br /&gt;There is a really cool demo for opencv in C called camshiftdemo. I decided to write a version in python... The only one I could find online used &lt;a href="http://code.google.com/p/ctypes-opencv/" id="kcd4" target="_blank" title="opencv with ctypes"&gt;opencv with ctypes&lt;/a&gt;, so this was a simple enough modification to get it running in more pure "swigged" python. It's in my pycam repository if anyone is interested:&amp;nbsp;&lt;a href="http://code.google.com/p/pycam/source/browse/trunk/pycam/cam-histo.py" id="lv5r" title="http://code.google.com/p/pycam/source/browse/trunk/pycam/cam-histo.py"&gt;http://code.google.com/p/pycam/source/browse/trunk/pycam/cam-histo.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here are some screenshots.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id="kk.t" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_179d75w2jg4_b" style="height: 400px; width: 640px;" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;This is the python cam shift demo tracking the orange on the XO's logo.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;div id="nf9." style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_180p9fkwjdz_b" style="height: 400px; width: 640px;" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Now tracking the green section, you can see the histogram for the entire image shown. It is a really simple demo, and quite fun! At the Hitlab open night this was what I used to keep the kids occupied!&lt;/div&gt;Unlike the previous computer vision post - this doesn't use pygame at all. It would be a really good example for the XO pippy computer vision package idea however.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-7275697194915756909?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/7275697194915756909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/camera-histogram-demo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7275697194915756909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7275697194915756909'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/07/camera-histogram-demo.html' title='Camera Histogram Demo'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-6394459842905905445</id><published>2009-06-30T01:58:00.000-07:00</published><updated>2009-07-12T16:29:03.920-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UCCC'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook connect'/><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='procrastinot'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='appengine'/><title type='text'>Facebook App</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;Well I thought I would have a crack at making a facebook application last weekend.&lt;br /&gt;Figured although theres no official python facebook api there were a few third party options so I might as well use my favorite language...&lt;br /&gt;&lt;br /&gt;I also decided that it would also be a nice opportunity to look at this Django framework thing...&lt;br /&gt;&lt;br /&gt;I also decided that it might as well run on Google's Appengine...&lt;br /&gt;&lt;a href="http://images.ientrymail.com/webpronews/article_pics/facebook-connect.jpg"&gt;&lt;/a&gt;&lt;br /&gt;So first I skimmed through the django tutorial again - I've only used django once before and that was just a quick look to get graphs from Matplotlib displayed on a webpage.&lt;br /&gt;&lt;br /&gt;Then I took my time going through the appengine tutorial.... There are a few things that you have to get used too in switching from django to appengine. The easiest but also most annoying is changing all the models to use Google db models.&lt;br /&gt;&lt;br /&gt;Once I was reasonably to grips with both engines I started the fun bit of getting a django app running on app engine. It is actually easy as! My mechanical engineering friend Jun is keen to help out, so I have set up a bzr repository, and a shared appengine application. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So far I have a basic django app running at &lt;a href="http://thebetterprocrastinot.appspot.com/"&gt;http://thebetterprocrastinot.appspot.com/&lt;/a&gt; and the facebook application at &lt;a href="http://thebetterprocrastinot.appspot.com/procrastinot/"&gt;http://thebetterprocrastinot.appspot.com/procrastinot/&lt;/a&gt; or &lt;a href="http://apps.facebook.com/procrastinot/"&gt;http://apps.facebook.com/procrastinot/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.ientrymail.com/webpronews/article_pics/facebook-connect.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 450px; height: 358px;" src="http://images.ientrymail.com/webpronews/article_pics/facebook-connect.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since facebook api is sweet, and I noticed a small wee site called Digg using it - I then decided to integrate facebook connect into my alpha uccc site on appengine, thats so remarkably easy I can't wait to find time to get the actual site using facebook connect instead of yet another username/password combination. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-6394459842905905445?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/6394459842905905445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/06/facebook-app.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6394459842905905445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6394459842905905445'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/06/facebook-app.html' title='Facebook App'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-7078245843196909830</id><published>2009-05-04T22:09:00.001-07:00</published><updated>2009-05-04T22:09:25.722-07:00</updated><title type='text'>Swig with C++ and external libs</title><content type='html'>This is the kind of problem I work out how to solve, then I forget... and eventually have to do again... So more for my sake here is how to compile a python extension in c++ that has external libraries like opencv. Automatically wrapped with swig from distutils...&lt;br&gt;&lt;br&gt;So first up I have a random library of C++ that I want to use from python. One such C file is doing some low level math on an opencv IPL image. Since I want to use this in python but require it to be fast, I need to create an extension.&lt;br&gt;&lt;br style="font-family: Courier New;"&gt;&lt;hr style="font-family: Courier New;" size="2"&gt;&lt;span style="font-family: Courier New;"&gt;// The header file I want to wrap.&lt;br&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;#include &amp;lt;math.h&amp;gt;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;#include "cv.h"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;void remove_corneal_reflection(IplImage *image, IplImage *threshold_image, int sx, int sy, int window_size, &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int biggest_crr, int &amp;amp;crx, int &amp;amp;cry, int&amp;amp; crr, int *valid_point_calc);&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;hr size="2"&gt;&lt;br&gt;This has a few normal includes and "cv.h". This is refering to the opencv installed NOT in the default dir but in /usr/local/. &lt;br&gt;&lt;br&gt;Next is the instructions for swig to use when creating the wrapper for the file. This uses the autodoc feature so in python the docstrings have some (almost) usefull information about what the parameters are.&lt;br&gt;&lt;br style="font-family: Times New Roman;"&gt;&lt;hr style="font-family: Times New Roman;" size="2"&gt;&lt;span style="font-family: Courier New;"&gt;/* Interface to the C file remove_corneal_reflection.c */&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;%module removeCornealReflection &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;%{ &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Put header files here or function declarations like below */ &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #include "opencv/cv.h"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #include "remove_corneal_reflection.h"&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;%}&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;// Tell swig to put type information into the functions docstrings... &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;%feature("autodoc", "1");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;// Tell swig to parse the header file.&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;%include "remove_corneal_reflection.h"&lt;/span&gt;&lt;hr size="2"&gt;&lt;br&gt;To get distutils to do all the compiling and linking we need a setup.py file:&lt;br&gt;&lt;br&gt;&lt;hr size="2"&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;import distutils &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;from distutils.core import setup, Extension &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;setup( &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = "Brian's C++ Library wrapped up all nice for python", &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; author = 'Brian Thorne', &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; author_email = 'hardbyte@gmail.com', &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; license='GPL v3 :: GNU General Public License', &amp;nbsp;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; version = "0.1", &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ext_modules = [ &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Extension( &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "_helloWorld",&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sources = ["interfaceFile.i","Hello World.cpp"],&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; swig_opts=["-c++"],&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ),&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Extension(&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "_removeCornealReflection",&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sources = ["remove_corneal_reflection.i","remove_corneal_reflection.cpp"],&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; swig_opts=["-c++"],&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; library_dirs=['/usr/local/lib/opencv'],&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; libraries=['cv','highgui','cvaux','cvaux'],&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; include_dirs = ['/usr/local/include/opencv']&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ] &lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;br&gt;&lt;hr size="2"&gt;And for the first time I also made a setup.cfg file with a whole two lines:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;[build_ext]&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;inplace=1&lt;/span&gt;&lt;br&gt;&lt;br&gt;And then the whole thing can be wrapped up with the familiar command:&lt;br&gt;&lt;br&gt;brian@brian-hitlab:~/dev/swig/linkedLib$ python setup.py build&lt;br&gt;running build&lt;br&gt;running build_ext&lt;br&gt;building '_helloWorld' extension&lt;br&gt;swigging interfaceFile.i to interfaceFile_wrap.cpp&lt;br&gt;swig -python -c++ -o interfaceFile_wrap.cpp interfaceFile.i&lt;br&gt;creating build&lt;br&gt;creating build/temp.linux-x86_64-2.6&lt;br&gt;gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c interfaceFile_wrap.cpp -o build/temp.linux-x86_64-2.6/interfaceFile_wrap.o&lt;br&gt;cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++&lt;br&gt;gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c Hello World.cpp -o build/temp.linux-x86_64-2.6/Hello World.o&lt;br&gt;cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++&lt;br&gt;g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/interfaceFile_wrap.o build/temp.linux-x86_64-2.6/Hello World.o -o _helloWorld.so&lt;br&gt;building '_removeCornealReflection' extension&lt;br&gt;swigging remove_corneal_reflection.i to remove_corneal_reflection_wrap.cpp&lt;br&gt;swig -python -c++ -o remove_corneal_reflection_wrap.cpp remove_corneal_reflection.i&lt;br&gt;gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/opencv -I/usr/include/python2.6 -c remove_corneal_reflection_wrap.cpp -o build/temp.linux-x86_64-2.6/remove_corneal_reflection_wrap.o&lt;br&gt;cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++&lt;br&gt;gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/opencv -I/usr/include/python2.6 -c remove_corneal_reflection.cpp -o build/temp.linux-x86_64-2.6/remove_corneal_reflection.o&lt;br&gt;cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++&lt;br&gt;g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/remove_corneal_reflection_wrap.o build/temp.linux-x86_64-2.6/remove_corneal_reflection.o -L/usr/local/lib/opencv -lcv -lhighgui -lcvaux -lcvaux -o _removeCornealReflection.so&lt;br&gt;&lt;br&gt;&lt;br&gt;This creates two python extensions - one called &lt;span style="font-family: Courier New;"&gt;helloWorld&lt;/span&gt; and one called &lt;span style="font-family: Courier New;"&gt;removeCornealReflection&lt;/span&gt;. Ideal! Not sure why the warning message comes up, it looks like it is using gcc for the linking when surely g++ would be better... anyhow can't argue with positive results!&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-7078245843196909830?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/7078245843196909830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/05/swig-with-c-and-external-libs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7078245843196909830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7078245843196909830'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/05/swig-with-c-and-external-libs.html' title='Swig with C++ and external libs'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-2158938765067512204</id><published>2009-04-30T21:48:00.000-07:00</published><updated>2009-04-30T21:48:33.469-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facedetection'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='computer vision'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='HITLAB'/><title type='text'>Eye Locating</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_lewp47C9PZI/Sfp83AQgkDI/AAAAAAAAAXQ/1Z-iAKx0Kxo/s1600-h/eye-locate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_lewp47C9PZI/Sfp83AQgkDI/AAAAAAAAAXQ/1Z-iAKx0Kxo/s400/eye-locate.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Image capturing is happening with the pygame.camera module. Object Detection is using an ObjectDetect class I wrote that wraps the cvHaarDetectObject from the opencv library.&lt;br /&gt;&lt;br /&gt;Just for fun the green box is drawn with pygame, the Red boxes are drawn with opencv. And the whole thing is rendered with pygame.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-2158938765067512204?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/2158938765067512204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/eye-locating.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2158938765067512204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2158938765067512204'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/eye-locating.html' title='Eye Locating'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lewp47C9PZI/Sfp83AQgkDI/AAAAAAAAAXQ/1Z-iAKx0Kxo/s72-c/eye-locate.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-2261243930515107251</id><published>2009-04-28T18:13:00.000-07:00</published><updated>2009-04-28T18:13:23.560-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='googlecode'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Project makes it to the intertubes...</title><content type='html'>Well I have finally put my code into a repository. It's all open source.&lt;br /&gt;&lt;br /&gt;I listed it on pygame.org and it went to the front page automatically which was cool!&lt;br /&gt;&lt;br /&gt;You can find my project at &lt;a href="http://www.pycam.googlecode.com/"&gt;http://www.pycam.googlecode.com&lt;/a&gt;&lt;br /&gt;The pygame project page is: &lt;a href="http://pygame.org/project/1111/"&gt;http://pygame.org/project/1111/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-2261243930515107251?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/2261243930515107251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/project-makes-it-to-intertubes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2261243930515107251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/2261243930515107251'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/project-makes-it-to-intertubes.html' title='Project makes it to the intertubes...'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1152586360370003502</id><published>2009-04-25T05:41:00.000-07:00</published><updated>2009-04-25T05:59:50.241-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facedetection'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Face Detection with python using opencv</title><content type='html'>&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;So I have been continuing on with the live edge detection I looked out a few weeks ago... I have made that code alot more object oriented and hopefully re-useable. I am now using both pygame and opencv built from svn instead of the ubuntu repositories. I wanted independence in the image rendering, the webcam capturing and the image processing. So I needed to convert between a numpy array (which pygame and any scipy processing uses) and cvMat which is opencv's data type. This was not immediately obvious as the opencv.adaptors module was full of routines for converting via the Python Image Library (PIL). These images were annoyingly being rotated by the functions when going from numpy to cvMat, then rotated back to the correct way going back from cvMat to numpy. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;First up is the VideoCapturePlayer class, it can be used to simply display a video feed. It uses pygame camera, stores the images as a pygame.surface and shows the video with pygame. The latest pygame has an option to force pygame.camera to use opencv. Also in this class is an optional process function, something that takes and returns a surface... So in here one could put in the edge detection functionality that I looked at in the last post.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;pygame&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.camera&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;from&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.locals&lt;/span&gt; &lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;numpy&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;VideoCapturePlayer&lt;/b&gt;(object):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;&lt;span style="color: #00aa00;"&gt;"""A VideoCapturePlayer object is an encapsulation of &lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;the display of a video stream. A process can be &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;given (as a function) that is done on every frame&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;For example a filter function that takes and returns a &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;surface can be given. This player will take the webcam image, &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;pass it through the filter then display the result.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;If the function takes significant computation time (&amp;gt;1second)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;The VideoCapturePlayer takes 3 images between each, this ensures &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;an updated picture is used in the next computation.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;size&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;width,height&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: maroon;"&gt;640&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;480&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;__init__&lt;/b&gt;(&lt;i&gt;self&lt;/i&gt;,&lt;/span&gt; &lt;span style="color: black;"&gt;processFunction&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: blue;"&gt;None&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: black;"&gt;forceOpenCv&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: blue;"&gt;False&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: black;"&gt;**argd):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.__dict__.update(**argd)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;super(VideoCapturePlayer,&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;).__init__(**argd)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;pygame.init()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;pygame.camera.init()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;forceOpenCv:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;os&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;os.environ[&lt;/span&gt;&lt;i&gt;&lt;span style="color: #00aa00;"&gt;"PYGAME_CAMERA"&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;]&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"opencv"&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processFunction&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;processFunction&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# create a display surface. standard pygame stuff&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.display&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.display.set_mode(&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.size,&lt;/span&gt; &lt;span style="color: maroon;"&gt;0&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# gets a list of available cameras.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.clist&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.camera.list_cameras()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.clist:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;raise&lt;/span&gt; &lt;span style="color: black;"&gt;ValueError(&lt;/span&gt;&lt;i&gt;&lt;span style="color: #00aa00;"&gt;"Sorry, no cameras detected."&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# creates the camera of the specified size and in RGB colorspace&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.camera&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.camera.Camera(&lt;i&gt;self&lt;/i&gt;.clist[&lt;/span&gt;&lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;],&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.size,&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"RGB"&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# starts the camera&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.camera.start()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.waitForCam()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.clock&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.time.Clock()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processClock&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.time.Clock()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# create a surface to capture to. for performance purposes, you want the&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# bit depth to be the same as that of the display surface.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.snapshot&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.surface.Surface(&lt;i&gt;self&lt;/i&gt;.size,&lt;/span&gt; &lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.display)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;get_and_flip&lt;/b&gt;(&lt;i&gt;self&lt;/i&gt;):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;&lt;span style="color: #00aa00;"&gt;"""We will take a snapshot, do some arbitrary process (eg in numpy/scipy)&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;then display it. &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# capture an image&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.snapshot&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.camera.get_image(&lt;i&gt;self&lt;/i&gt;.snapshot).convert()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processFunction:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processClock.tick()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processClock.get_fps()&lt;/span&gt; &lt;span style="color: black;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: maroon;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"Running your resource intensive process at %f fps"&lt;/span&gt;&lt;/i&gt; &lt;span style="color: black;"&gt;%&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processClock.get_fps()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# flush the camera buffer to get a new image... &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# we have the time since the process is so damn slow...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt; &lt;span style="color: black;"&gt;i&lt;/span&gt; &lt;span style="color: blue;"&gt;in&lt;/span&gt; &lt;span style="color: black;"&gt;range(&lt;/span&gt;&lt;span style="color: maroon;"&gt;3&lt;/span&gt;&lt;span style="color: black;"&gt;):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.waitForCam()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.snapshot&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.camera.get_image(&lt;i&gt;self&lt;/i&gt;.snapshot).convert()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.snapshot&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.processFunction(&lt;i&gt;self&lt;/i&gt;.snapshot)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# blit it to the display surface. simple!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.display.blit(&lt;i&gt;self&lt;/i&gt;.snapshot,&lt;/span&gt; &lt;span style="color: black;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt;&lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;pygame.display.flip()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;waitForCam&lt;/b&gt;(&lt;i&gt;self&lt;/i&gt;):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# Wait until camera is ready to take image&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt; &lt;span style="color: blue;"&gt;not&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.camera.query_image():&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;pass&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;main&lt;/b&gt;(&lt;i&gt;self&lt;/i&gt;):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"Video Capture &amp;amp; Display Started... press Escape to quit"&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;going&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: blue;"&gt;True&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;fpslist&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;[]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;while&lt;/span&gt; &lt;span style="color: black;"&gt;going:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;events&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygame.event.get()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt; &lt;span style="color: black;"&gt;e&lt;/span&gt; &lt;span style="color: blue;"&gt;in&lt;/span&gt; &lt;span style="color: black;"&gt;events:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;e.type&lt;/span&gt; &lt;span style="color: black;"&gt;==&lt;/span&gt; &lt;span style="color: black;"&gt;QUIT&lt;/span&gt; &lt;span style="color: blue;"&gt;or&lt;/span&gt; &lt;span style="color: black;"&gt;(e.type&lt;/span&gt; &lt;span style="color: black;"&gt;==&lt;/span&gt; &lt;span style="color: black;"&gt;KEYDOWN&lt;/span&gt; &lt;span style="color: blue;"&gt;and&lt;/span&gt; &lt;span style="color: black;"&gt;e.key&lt;/span&gt; &lt;span style="color: black;"&gt;==&lt;/span&gt; &lt;span style="color: black;"&gt;K_ESCAPE):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;going&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: blue;"&gt;False&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# if you don't want to tie the framerate to the camera, you can check and&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# see if the camera has an image ready. note that while this works&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# on most cameras, some will never return true.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;# note seems to work on my camera at hitlab - Brian&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 120px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.camera.query_image():&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.get_and_flip()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.clock.tick()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 160px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;i&gt;self&lt;/i&gt;.clock.get_fps():&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 200px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;fpslist.append(&lt;i&gt;self&lt;/i&gt;.clock.get_fps())&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 200px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;print&lt;/span&gt; &lt;span style="color: black;"&gt;fpslist[-&lt;/span&gt;&lt;span style="color: maroon;"&gt;1&lt;/span&gt;&lt;span style="color: black;"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"Video Capture &amp;amp; Display complete."&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"Average Frames Per Second "&lt;/span&gt;&lt;/i&gt; &lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;avg&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;numpy.average(fpslist)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 80px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;print&lt;/span&gt; &lt;span style="color: black;"&gt;avg&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;__name__&lt;/span&gt; &lt;span style="color: black;"&gt;==&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"__main__"&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;vcp&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;VideoCapturePlayer(processFunction=&lt;/span&gt;&lt;span style="color: blue;"&gt;None&lt;/span&gt;&lt;span style="color: black;"&gt;,forceOpenCv=&lt;/span&gt;&lt;span style="color: blue;"&gt;True&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;vcp.main()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; margin-left: 40px;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;pygame.quit()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div id="gdiw" style="text-align: center;"&gt;&lt;div id="z54g" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_151fhzfvbdn_b" style="height: 480px; width: 640px;" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Standalone running the module (from pydev in eclipse)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;If you see behind me I have it printing the frames per second... I am sadly limited somewhat on my ibook in this respect. It cannot keep up with the 15fps that my machine at hitlab could do just displaying video.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Well that is all good and fun, say to add in the edge detection filter from last post I would write this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;(As a random aside the indentation was lost importing this into google docs.... so you will have to work out how the code was indented to run it.... Stupid problem I know! Actually on second thought I might remove most of the code from here - if any one wants it just message me. Eventually I will put it into an svn repo...&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;edgeDetectionProcess&lt;/b&gt;(surf):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; &lt;span style="color: black;"&gt;useScipy:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; imageArray1&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;numpy.mean(surfarray.pixels3d(surf),&lt;/span&gt;&lt;span style="color: maroon;"&gt;2&lt;/span&gt;&lt;span style="color: black;"&gt;)&lt;/span&gt; &lt;span style="color: silver;"&gt;# converting here to one col&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt; &lt;span style="color: black;"&gt;scipySpline:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; imageArray2&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;edgeDetect2(imageArray1)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; imageArray2&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;edgeDetect1(imageArray1)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; surf&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;surfarray.make_surface(imageArray2)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: silver;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # use pygame transform&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; surf&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;transform.laplacian(surf)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; &lt;span style="color: black;"&gt;surf&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;main&lt;/b&gt;():&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vcp&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;VideoCapturePlayer(processFunction=edgeDetectionProcess)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vcp.main()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pygame.quit()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="lv8r" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_152cknrsrd5_b" style="height: 480px; width: 640px;" /&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Musing on the coolness of it all...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;I also changed the edge detection to work on an average of the red, green and blue values instead of just one. Once I had got everything working I compared the performance of forcing pygame.camera to use opencv internally for the capturing. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;opencv  edgeDetection scipy spline result&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;true  false N/A N/A 66ms&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;false  false n/A n/a 66ms &lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;true  true false N/A 209ms // opencv capture, pygame edge detection&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;false  true false n/a 211ms&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;true  true true false 553ms&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;false  true true false 551ms&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;true  true true true 790ms&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;false  true true true 795&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Might as well just throw it out there, next I thought Face detection would be a good idea. Cue a lot of research into haarcascades and object recognition. So eventually found some working code in the opencv samples and hacked away at it to come up:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;detect&lt;/b&gt;(img):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; gray&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvCreateImage(&lt;/span&gt; &lt;span style="color: black;"&gt;cvSize(img.width,img.height),&lt;/span&gt; &lt;span style="color: maroon;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;1&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; small_img&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvCreateImage(&lt;/span&gt; &lt;span style="color: black;"&gt;cvSize(&lt;/span&gt; &lt;span style="color: black;"&gt;cvRound&lt;/span&gt; &lt;span style="color: black;"&gt;(img.width/image_scale),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvRound&lt;/span&gt; &lt;span style="color: black;"&gt;(img.height/image_scale)),&lt;/span&gt; &lt;span style="color: maroon;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;1&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvCvtColor(&lt;/span&gt; &lt;span style="color: black;"&gt;img,&lt;/span&gt; &lt;span style="color: black;"&gt;gray,&lt;/span&gt; &lt;span style="color: black;"&gt;CV_BGR2GRAY&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvResize(&lt;/span&gt; &lt;span style="color: black;"&gt;gray,&lt;/span&gt; &lt;span style="color: black;"&gt;small_img,&lt;/span&gt; &lt;span style="color: black;"&gt;CV_INTER_LINEAR&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvEqualizeHist(&lt;/span&gt; &lt;span style="color: black;"&gt;small_img,&lt;/span&gt; &lt;span style="color: black;"&gt;small_img&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvClearMemStorage(&lt;/span&gt; &lt;span style="color: black;"&gt;storage&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/span&gt;&lt;span style="color: black;"&gt;(&lt;/span&gt; &lt;span style="color: black;"&gt;cascade&lt;/span&gt; &lt;span style="color: black;"&gt;):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvGetTickCount()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; faces&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvHaarDetectObjects(&lt;/span&gt; &lt;span style="color: black;"&gt;small_img,&lt;/span&gt; &lt;span style="color: black;"&gt;cascade,&lt;/span&gt; &lt;span style="color: black;"&gt;storage,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; haar_scale,&lt;/span&gt; &lt;span style="color: black;"&gt;min_neighbors,&lt;/span&gt; &lt;span style="color: black;"&gt;haar_flags,&lt;/span&gt; &lt;span style="color: black;"&gt;min_size&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvGetTickCount()&lt;/span&gt; &lt;span style="color: black;"&gt;-&lt;/span&gt; &lt;span style="color: black;"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"%i faces found, detection time = %gms"&lt;/span&gt;&lt;/i&gt; &lt;span style="color: black;"&gt;%&lt;/span&gt; &lt;span style="color: black;"&gt;(faces.total,t/(cvGetTickFrequency()*&lt;/span&gt;&lt;span style="color: maroon;"&gt;1000.&lt;/span&gt;&lt;span style="color: black;"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/span&gt; &lt;span style="color: black;"&gt;faces&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"no cascade"&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;detect_and_draw&lt;/b&gt;(&lt;/span&gt; &lt;span style="color: black;"&gt;img&lt;/span&gt; &lt;span style="color: black;"&gt;):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;&lt;span style="color: #00aa00;"&gt;"""&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;draw a box with opencv on the image around the detected faces.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;faces&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;detect(img)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;faces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for&lt;/span&gt; &lt;span style="color: black;"&gt;r&lt;/span&gt; &lt;span style="color: blue;"&gt;in&lt;/span&gt; &lt;span style="color: black;"&gt;faces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"Face found at (x,y) = (%i,%i)"&lt;/span&gt;&lt;/i&gt; &lt;span style="color: black;"&gt;%&lt;/span&gt; &lt;span style="color: black;"&gt;(r.x*image_scale,r.y*image_scale)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pt1&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvPoint(&lt;/span&gt; &lt;span style="color: black;"&gt;int(r.x*image_scale),&lt;/span&gt; &lt;span style="color: black;"&gt;int(r.y*image_scale))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pt2&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;cvPoint(&lt;/span&gt; &lt;span style="color: black;"&gt;int((r.x+r.width)*image_scale),&lt;/span&gt; &lt;span style="color: black;"&gt;int((r.y+r.height)*image_scale)&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvRectangle(&lt;/span&gt; &lt;span style="color: black;"&gt;img,&lt;/span&gt; &lt;span style="color: black;"&gt;pt1,&lt;/span&gt; &lt;span style="color: black;"&gt;pt2,&lt;/span&gt; &lt;span style="color: black;"&gt;CV_RGB(&lt;/span&gt;&lt;span style="color: maroon;"&gt;255&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt;&lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt;&lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;span style="color: black;"&gt;),&lt;/span&gt; &lt;span style="color: maroon;"&gt;3&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;8&lt;/span&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: maroon;"&gt;0&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cvShowImage(&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"result"&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;,&lt;/span&gt; &lt;span style="color: black;"&gt;img&lt;/span&gt; &lt;span style="color: black;"&gt;)&lt;/span&gt; &lt;span style="color: silver;"&gt;# TODO is this reqd if pygame renders?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Now the main function in the above file (now edited out) is using opencv for the capture, analysis and the rendering. I also made the next script to interface with it using the VideoCapturePlayer class from above and to use pygame for the rendering. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;drawFacesOnSurface&lt;/b&gt;(surf,faces):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;&lt;span style="color: #00aa00;"&gt;"""draw rectangles around detected cvObjects with pygame&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="color: #00aa00;"&gt;  &lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;...Snip....&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;__name__&lt;/span&gt; &lt;span style="color: black;"&gt;==&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"__main__"&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vcp&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;VideoCapturePlayer(processFunction=locateFaces)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vcp.main()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pygame.quit()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;I suppose showing it working would be a good idea :-P&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div id="gdiw" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_150hc45hxg9_b" style="height: 480px; width: 640px;" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div id="rysb" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_153pjftrkfr_b" style="height: 480px; width: 640px;" /&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div id="noxp" style="text-align: center;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Yes it still works close up!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div id="xef4" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_157g9rmrxck_b" style="height: 240px; width: 320px;" /&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;And further back...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div id="d8xs" style="text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_155dhp57bcw_b" style="height: 486px; width: 648px;" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;And it works on more than one face at once!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div id="mgte" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_156cwvsqzc7_b" style="height: 480px; width: 640px;" /&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Now if you see the blue box at the top of my screen... yeah thats my CPU usage... This is a rather intese process and seems to take about a second for the loop that does a capture, a conversion, analysis, reconversion and rendering.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Well that should just about do it for today! Actually no, maybe I'll do a quick mash of the edgedetection + face detection :-P&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: silver;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;#!/usr/bin/python&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;from&lt;/span&gt; &lt;span style="color: black;"&gt;VideoCapturePlayer&lt;/span&gt; &lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;*&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;pygameFaceDetect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;import&lt;/span&gt; &lt;span style="color: black;"&gt;edgeDetect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;def&lt;/span&gt; &lt;span style="color: black;"&gt;&lt;b&gt;process&lt;/b&gt;(surf):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;faces&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;pygameFaceDetect.getFaces(surf)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;surf&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;edgeDetect.edgeDetectionProcess(surf)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;faces:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;pygameFaceDetect.drawFacesOnSurface(surf,&lt;/span&gt; &lt;span style="color: black;"&gt;faces)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: black;"&gt;surf&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; &lt;span style="color: black;"&gt;__name__&lt;/span&gt; &lt;span style="color: black;"&gt;==&lt;/span&gt; &lt;i&gt;&lt;span style="color: #00aa00;"&gt;"__main__"&lt;/span&gt;&lt;/i&gt;&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;vcp&lt;/span&gt; &lt;span style="color: black;"&gt;=&lt;/span&gt; &lt;span style="color: black;"&gt;VideoCapturePlayer(processFunction=process)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;vcp.main()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: black;"&gt;pygame.quit()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div id="i1yo" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_158g2cgrbhr_b" style="height: 768px; width: 1024px;" /&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Yes that is a book I am holding up... &lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div align="center" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;span style="color: black;"&gt;&lt;span style="font-family: Monospace;"&gt;&lt;span style="font-size: x-small;"&gt;Next maybe eye detection within a face...? Who knows! Then face recognition? Oh the possibilities! &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div align="left" style="-moz-background-clip: -moz-initial; -moz-background-inline-policy: -moz-initial; -moz-background-origin: -moz-initial; background: transparent none repeat scroll 0% 0%; font-style: normal;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1152586360370003502?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1152586360370003502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/face-detection-with-python-using-opencv.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1152586360370003502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1152586360370003502'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/face-detection-with-python-using-opencv.html' title='Face Detection with python using opencv'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-3845915590141540507</id><published>2009-04-03T02:53:00.001-07:00</published><updated>2009-04-03T04:26:56.619-07:00</updated><title type='text'>Live Edge Detection using Pygame and Numpy</title><content type='html'>So I thought I would start playing with image processing a bit more.  I haven't used pygame before, but a mechanical engineering friend of mine was talking about it so I'm taking a look. I have also been recently following &lt;a title="this blog" target="_blank" href="http://eclecti.cc/" id="e7ln"&gt;this blog&lt;/a&gt;, where the author made a webcam module for pygame for a Google Summer of Code project. So I svn checked out the latest pygame and fired up a few basic examples. I am impressed it's really easy to use! Loading images and making a simple animation, or event driven game is straight forward. I followed a particularly bad tutorial on showmedo, making a simple box that was keyboard event driven around a screen. &lt;div id="olo0" style="text-align: center;"&gt;&lt;img style="width: 320px; height: 247.755px;" src="http://docs.google.com/File?id=dfp426p7_141cnssbzfs_b" /&gt;&lt;/div&gt;Well this is all good and well, a black box I can steer around a white screen. Boy that is cool! :-P&lt;br /&gt;Don't despair, there is more to come, after this dismal tutorial I went to pygame's site - funnily enough they have introductory tutorials on using pygame and they were not quite so boring! So program 2 was loading an image of a ball and letting it bounce around the screen as shown.&lt;br /&gt;&lt;br /&gt;&lt;div id="k71c" style="text-align: center;"&gt;&lt;img style="width: 648px; height: 470.935px;" src="http://docs.google.com/File?id=dfp426p7_1429dmckwf8_b" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Well sure so not exactly enthralling stuff - it's interesting to see just how easy it was to get to this point. So anyhow the next thing I did was fire up the old ipython terminal and try to get an image from my webcam displayed....&lt;br /&gt;&lt;br /&gt;&lt;div id="myli" style="text-align: center;"&gt;&lt;img src="http://docs.google.com/File?id=dfp426p7_14345v3zqxf_b" height="641" width="640" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Pretty impressed that 14 lines of code can get an image of me typing the 12th line displayed on my screen! The very observant will realize that line 12 of my screen-shot produces an error! It should have been&lt;br /&gt;    &lt;span style="font-family:Courier New;"&gt;snapshot = camera.get_image()&lt;/span&gt;&lt;br /&gt;Then the last two lines for completeness are:&lt;br /&gt;&lt;br /&gt;    &lt;span style="font-family:Courier New;"&gt; &amp;gt;&amp;gt;&amp;gt; display.blit(snapshot,(0,0,))&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;         &amp;lt;rect(0, 0, 640, 480)&amp;gt;&lt;/span&gt;  &lt;span style="font-family:Courier New;"&gt;   &amp;gt;&amp;gt;&amp;gt; pygame.display.flip()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So now to use some other tools with this! So first up I wanted a numpy array of this image. Turns out pygame itself solves this one:&lt;br /&gt;   &lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&amp;gt;&amp;gt;&amp;gt; from pygame import surfarray&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; numpyArray = surfarray.&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;array3d(snapshot)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&amp;gt;&amp;gt;&amp;gt; type(numpyArray)&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;    &amp;lt;type 'numpy.ndarray'&amp;gt;&lt;/span&gt;  &lt;span style="font-family:Courier New;"&gt;&amp;gt;&amp;gt;&amp;gt; numpyArray.shape&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;    (640, 480, 3)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; Well now that was easy! So now I can do image processing using scipy's  signal processing toolbox on data recieved via pygame's camera module.&lt;br /&gt;&lt;br /&gt;How about doing that live? First I found in the pygame examples folder a camera.py file. This simply displays the live video feed in pygame and outputs the frame rate to the terminal. When I run that on my pc at hitlab I get an average of 73 frames per second.&lt;br /&gt;&lt;br /&gt;I used that as my base and added in an optional edge detection mode. When enabled this converts the image from a pygame surface to a numpy array as above. Then it calls this function:&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;def edgeDetect1(imageArray):&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;    laplacian = numpy.array([[0,1,0],[1,-4,1],[0,1,0]])&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;    deriv = signal.convolve2d(       \                 imageArray[:,:,0],laplacian,mode="same",boundary="symm")&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;    return deriv&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This carries out edge detection on only ONE of the RGB pixel arrays (I assume red...?)&lt;br /&gt;&lt;div id="koe-" style="text-align: center;"&gt;&lt;img style="width: 1600px; height: 1000px;" src="http://docs.google.com/File?id=dfp426p7_144fkrjpwfd_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see I was excited about this! I felt this was a very good start!&lt;br /&gt;It wasn't all rosy however, the FPS went down. This was expected but alarming as to how much... The new result was 3.3fps. Now this was a bit hit so I did some re con into what was slowing this down, and the result surprised me. It wasn't the convolve line. It was the converting to a numpy array and back...&lt;br /&gt;&lt;br /&gt;So instead of using surfarray, I had a nosy around the pygame docs - sure enough there is a &lt;span style="font-size:100%;"&gt;&lt;a title="pygame.transform.laplacian" target="_blank" href="http://www.pygame.org/docs/ref/transform.html#pygame.transform.laplacian" name="pygame.transform.laplacian"&gt;pygame.transform.laplacian.&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;So using that directly on the surface captured, gave a way cooler live feeling cause it was not too laggy at 15 fps.&lt;br /&gt;&lt;div id="hmjm" style="text-align: center;"&gt;&lt;img style="width: 648px; height: 559.098px;" src="http://docs.google.com/File?id=dfp426p7_145d5j56fv5_b" /&gt;&lt;/div&gt;&lt;br /&gt;Hmm I should get back to my work report now... I would like to see a fast way of getting the data into numpy tho.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-3845915590141540507?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/3845915590141540507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/live-edge-detection-using-pygame-and.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3845915590141540507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/3845915590141540507'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/04/live-edge-detection-using-pygame-and.html' title='Live Edge Detection using Pygame and Numpy'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-7115080435817770534</id><published>2009-03-26T19:04:00.000-07:00</published><updated>2009-03-26T19:09:17.975-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wxWidgets'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Software ENEL 428</title><content type='html'>So I have enrolled in a software class at uni... It appears that there is some sort of assignment due next week... In C++. Small we issue with that being I don't &lt;span style="font-weight: bold;"&gt;YET&lt;/span&gt; know C++.&lt;br /&gt;&lt;br /&gt;I have to make a game. It appears everyone else in the class is just modifying some code the lecturer gave us in FLTK. Now personally I think FLTK is almost as ugly as java's SWING so I am treating this as an extended opportunity to use wxWidgets. I have used wxPython before so that should help a little! Now I get to use it at a much lower level!&lt;br /&gt;&lt;br /&gt;So to start with I have got Code::Blocks an open source cpp IDE, it seems pretty good and has inbuilt support for both fltk and wx apps. Using the included wxSmith tool I managed to make the GUI for my game in no time at all.&lt;br /&gt;&lt;br /&gt;Now I just have to learn the language and code the game! My idea is to make a jetboat racer game. There will be a map and you will have to race around it... Sounds simple right!?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-7115080435817770534?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/7115080435817770534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/software-enel-428.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7115080435817770534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/7115080435817770534'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/software-enel-428.html' title='Software ENEL 428'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1622007647529651786</id><published>2009-03-26T18:53:00.000-07:00</published><updated>2009-03-26T18:57:41.780-07:00</updated><title type='text'>Eye Tracking Project</title><content type='html'>Well my project has been approved (I think)&lt;br /&gt;So now I guess I have to start working on some crazy eye tracking!&lt;br /&gt;&lt;br /&gt;First order of business will be getting the existing Matlab code running.&lt;br /&gt;After that I will try compile and run the open source C code that works using two firewire cameras. If that looks all good I will wrap it in SWIG for python and then port it to USB cameras. All going according to plan a fully python version should be released as open source by the conclusion of the project.&lt;br /&gt;&lt;br /&gt;The difficult bit might be the hardware - getting two small cameras close to ones face with out being too annoying! One has to point at the eye and the other points forward at what you are looking at.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1622007647529651786?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1622007647529651786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/eye-tracking-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1622007647529651786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1622007647529651786'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/eye-tracking-project.html' title='Eye Tracking Project'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-6764235738159105487</id><published>2009-03-13T17:24:00.001-07:00</published><updated>2009-03-13T17:25:45.882-07:00</updated><title type='text'>Hitlab has some slow internet</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lewp47C9PZI/Sbr5VkQYm8I/AAAAAAAAAWw/51lb4AOmWxU/s1600-h/speedy-webs.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 300px; height: 135px;" src="http://3.bp.blogspot.com/_lewp47C9PZI/Sbr5VkQYm8I/AAAAAAAAAWw/51lb4AOmWxU/s400/speedy-webs.png" alt="" id="BLOGGER_PHOTO_ID_5312832859341888450" border="0" /&gt;&lt;/a&gt;My goodness me, I don't know what to do with all this speed!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-6764235738159105487?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/6764235738159105487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/hitlab-has-some-slow-internet.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6764235738159105487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6764235738159105487'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/hitlab-has-some-slow-internet.html' title='Hitlab has some slow internet'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lewp47C9PZI/Sbr5VkQYm8I/AAAAAAAAAWw/51lb4AOmWxU/s72-c/speedy-webs.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1420806177496370311</id><published>2009-03-04T20:07:00.000-08:00</published><updated>2009-03-13T17:26:36.431-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenEyes'/><category scheme='http://www.blogger.com/atom/ns#' term='HITLAB'/><category scheme='http://www.blogger.com/atom/ns#' term='uni'/><title type='text'>My Final Year Project working in the HIT lab</title><content type='html'>Well it looks like I got my first choice for final year projects, Sweet!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Project: Robust Low Cost Eye Tracking.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The HIT Lab NZ is interested in developing hardware and software for a robust low cost eye tracker that could be used for computer interfaces that respond to eye gaze. The hardware should be a head worn camera with Infra Red LED that shines in the eye and detects the reflection. Simple image processing software can then be used to detect the point of maximum reflection and so track the eye gaze point.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The hit lab already has an early working version of this, the goal of this project is to explore alternative hardware designs and develop more robust software to work with the hardware. Work can be based on the OpenEyes platform.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If there is sufficient time - an application showing how eye gaze could be used in a computer interface.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Could have my work cut out for me this year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1420806177496370311?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1420806177496370311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/my-final-year-project-working-in-hit.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1420806177496370311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1420806177496370311'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/03/my-final-year-project-working-in-hit.html' title='My Final Year Project working in the HIT lab'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-5253373731712701257</id><published>2009-02-17T19:47:00.000-08:00</published><updated>2009-02-17T20:30:23.518-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='weave'/><category scheme='http://www.blogger.com/atom/ns#' term='fixed point'/><title type='text'>Weave</title><content type='html'>&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt; &lt;p style="margin-bottom: 0cm;"&gt;Weave is a python module that includes a method of including C and C++ code inline with python. Has a slightly bigger overhead than the swig approach but is a lot easier to implement.  And the code can be any dynamically created string.  For example this block of python code calculates the fixed point multiplication of var1 and var2. The code is modified from a matlab algorithm worked on during my summer internship at &lt;a href="http://tait.co.nz/"&gt;Tait Electronics&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="margin-bottom: 0cm;"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; scipy.weave &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;import&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inline &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inlineC&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;u&gt;r&lt;/u&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; = rounding &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;and&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;or&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;0 &lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;i&gt;# Blatent hack to convert from pythons True/False to 1/0 for C/C++&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;                    &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;        &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;exp = &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;"""&lt;br /&gt;signed int K,result;&lt;br /&gt;signed long int temp;&lt;br /&gt;temp = (long int)var1 * (long int)var2;&lt;br /&gt;signed int sign = temp/abs(temp);&lt;br /&gt;if(r) {&lt;br /&gt;K = 1 &lt;&lt; (numBits-1); temp = temp + K; } result = sign*(abs(temp) &gt;&gt; numBits);&lt;br /&gt;if(result &gt; fp_Max){&lt;br /&gt;result = fp_Max;&lt;br /&gt;}&lt;br /&gt;if(result &lt; result =" fp_Min;" return_val =" result;"&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;i&gt; &lt;/i&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;i&gt;        &lt;/i&gt;&lt;/span&gt;&lt;i&gt; &lt;/i&gt;&lt;/p&gt;&lt;i&gt; &lt;/i&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;i&gt;        &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;result = inlineC(exp,[&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;&lt;i&gt;'var1'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;,&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;&lt;i&gt;'var2'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;,&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;&lt;i&gt;'numBits'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;,&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;&lt;i&gt;'fp_Min'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;,&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;&lt;i&gt;'fp_Max'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;,&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;&lt;i&gt;'r'&lt;/i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;])&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;i&gt; &lt;/i&gt;&lt;p style="margin-bottom: 0cm;"&gt;It must be noted the C code is just a string to python, the string is then passed to scipy.weave.inline along with any variables required by the code. The only non standard piece of c is assigning return_val, this is set up by weave and can be assigned with any type to return into python. Also note the commented out printf statement in the C code – was very useful for debugging as it still outputs to standard out.&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;Weave is a quick and powerful way to include c code or optimize a bottleneck in an algorithm. The above example is probably to simple to get any speed up as its a very trivial problem and the overhead of calling C must be factored in. Weave is pretty awesome for when you have a loop in python you cannot get rid of that MUST go faster.&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;As with all optimization tho, ask yourself if you really need it?&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;Here is another example...&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;The original code:&lt;br /&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt;        &lt;/p&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt; &lt;/p&gt;  &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt; &lt;/p&gt; &lt;blockquote&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; numpy &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;import&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt; *&lt;br /&gt;def&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;b&gt;wastedLoop&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(n):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;"""wastedLoop does alot of looping adding up the numbers 1 + 2 + ... N&lt;br /&gt;wastedLoop(n) loops n times"""&lt;br /&gt;  p = &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;br /&gt;for&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; k &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; range(n+&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="font-size:85%;"&gt;):&lt;br /&gt;p = p + k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;br /&gt;print&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; p&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;p style="margin-bottom: 0cm;"&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Then at an ipython prompt do a quick timing test:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt;&gt; %timeit wastedLoop(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1000000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;br /&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; loops, best of &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;464&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; ms per loop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p style="margin-bottom: 0cm;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;Ok so now lets use numpy functions instead of looping:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;blockquote&gt;&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt;  &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;def&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;b&gt;numpySumMethod&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(n):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;br /&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sum(arange(n+&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt; &lt;/p&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt;  &lt;/p&gt;&lt;blockquote&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt;&gt; %timeit numpySumMethod(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1000000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;br /&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; loops, best of &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;12.9&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; ms per loop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;So we already have achieved a 35 times faster run time than the original. And have clearer code!&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;blockquote&gt;&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt;     &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; scipy &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;import&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt; weave&lt;br /&gt;def&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;b&gt;wastedLoop&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;(n):&lt;br /&gt;&lt;i&gt;"""&lt;br /&gt;wastedLoop does alot of looping adding up the numbers 1 + 2 + ... N&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;wastedLoop(n) loops n times&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;         &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;p = int(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;exp = &lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;i&gt;"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;int i;&lt;br /&gt;for(i=0;i&lt;n;i++){ p="p" n=""&gt;&lt;/n;i++){&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;weave.inline(exp,[&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;i&gt;'p'&lt;/i&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;i&gt;'n'&lt;/i&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;br /&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt; &lt;/p&gt;  &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;%timeit wastedLoop(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1000000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;br /&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; loops, best of &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;2.8&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; ms per loop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;We see an improvement here but its not amazing...  Just one more example, doing the same thing but with the knowledge about the problem. Using the algorithm:&lt;br /&gt;&lt;blockquote&gt;&lt;style type="text/css"&gt;  &lt;!--   @page { margin: 2cm }   P { margin-bottom: 0.21cm }  --&gt;  &lt;/style&gt;   &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;def&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;b&gt;efficientMethod&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(n):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 170, 0);"&gt;&lt;i&gt;&lt;br /&gt;      """Return sum of 1+2+3...+N"""&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;br /&gt;   return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; n*(n+&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)/&lt;/span&gt;2.0&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt; &lt;/p&gt;  &lt;p style="margin-bottom: 0cm;" align="left"&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt;&gt; timeit efficientMethod(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;1000000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;)&lt;br /&gt;1000000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; loops, best of &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;0.00000173&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; s per loop&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;And there we have it: 1.73µs There is a lesson in that! A bit of math goes a long way! For the cases where you don't have insider knowledge however, it is clear numpy alone can suffice in most situations.&lt;br /&gt;&lt;br /&gt;Stay tuned for a look at python extensions with swig.&lt;br /&gt;&lt;br /&gt;P.S: What is with this editor for blogger? It is crap!!!&lt;i&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;p&gt;&lt;/p&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;p&gt;&lt;/p&gt;&lt;i&gt;&lt;i&gt; &lt;/i&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-5253373731712701257?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/5253373731712701257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/02/weave.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/5253373731712701257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/5253373731712701257'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/02/weave.html' title='Weave'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-1901138481127923923</id><published>2009-02-17T19:27:00.000-08:00</published><updated>2009-02-17T19:40:43.588-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gentoo'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='ppc'/><category scheme='http://www.blogger.com/atom/ns#' term='ibook G4'/><title type='text'>Gentoo on the ibook G4</title><content type='html'>Well I finally decided to try be a real nerd... I have installed Gentoo on my laptop.&lt;br /&gt;&lt;br /&gt;I installed it for the worst possible reason too - because I managed to break my ubuntu install when trying to upgrade to the jaunty beta...&lt;br /&gt;&lt;br /&gt;First I went through the awesome manual at &lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml"&gt;http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml&lt;/a&gt;. Then decided to break a bit so I went through the awesome manual at &lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml"&gt;http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml&lt;/a&gt;. Then decided to break a bit so I went through the awesome manual at &lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml"&gt;http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml&lt;/a&gt;. Then decided to break a bit so I went through the awesome manual at &lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml"&gt;http://www.gentoo.org/doc/en/handbook/handbook-ppc.xml&lt;/a&gt;....&lt;br /&gt;&lt;br /&gt;Eventually I have a lot more knowledge about how awesome chroot is, how to manually set up a wired and a wireless connection, how to emerge and USE.&lt;br /&gt;&lt;br /&gt;Immediately noticed a speed increase, and things like the hibernate on closed lib when on battery... just work. That never happened on Ubuntu intrepid!&lt;br /&gt;&lt;br /&gt;I first tried xfce with slim which was nice but I missed some things from my old ubuntu. So left the pc for a day doing:&lt;br /&gt;# emerge gnome&lt;br /&gt;&lt;br /&gt;I found updating from python2.4 to python2.5 weird - you have to run python-updater or when you are running your presentation at uni it WONT WORK.&lt;br /&gt;&lt;br /&gt;Playing with X and my video out gave me a cloned screen on our homemade projector at home.  Looking good!&lt;br /&gt;&lt;br /&gt;I am now running my first "deep update" of world, currently been compiling for 4 hours...&lt;br /&gt;Don't really know if all of this configuring is really worth it to be honest....&lt;br /&gt;I'll give it a few weeks and see if I go back to ubuntu or stay...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-1901138481127923923?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/1901138481127923923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/02/gentoo-on-ibook-g4.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1901138481127923923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/1901138481127923923'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/02/gentoo-on-ibook-g4.html' title='Gentoo on the ibook G4'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-6743455541885922117</id><published>2009-01-30T04:37:00.001-08:00</published><updated>2009-01-30T04:37:10.850-08:00</updated><title type='text'>Flash on Ubuntu PPC</title><content type='html'>&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h1&gt;&lt;br /&gt; Flash on my iBook G4 (Ubuntu 8.10 ppc)&lt;br /&gt;&lt;/h1&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;You know what would be great? Having skype and youtube um work... Ok to be fair youtube &lt;i&gt;kinda&lt;/i&gt; works unless I want to show people something - in which case it will ALWAYS fail miserably. So I want better flash for youtube...&amp;nbsp; and after &lt;u&gt;extensive&lt;/u&gt; looking into skype:&lt;br&gt;&lt;ol&gt;&lt;li&gt;pidgoen plugins (that needed skype running duh)&lt;/li&gt;&lt;li&gt;emulation with a virtual os - might look back into puppy linux just had some proxy annoyances&lt;/li&gt;&lt;li&gt;qemu user-mode looks promising - will definatly look into this further.&lt;/li&gt;&lt;li&gt;even looked into reverse engineering the protocol (don't even bother btw, seriously scary trying to debug that program).&lt;/li&gt;&lt;/ol&gt;So what I came up with is that &lt;a title="imo.im" href="http://imo.im" id="suay"&gt;imo.im&lt;/a&gt; is the answer... its actually as easy as visiting that address and logging in - online solution works for me! :-P &lt;br&gt;BUT... although I can now text chat to people on skype - to make calls and have video I need far better flash support. Does this exist for the ppc gnu/linux user? &lt;br&gt;&lt;br&gt;So I really want decent flash support on my iBook - is that really so much to ask? After looking through Adobe Labs and system settings it appears they make support (make binaries for):&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;br /&gt; Any thing windows xp (or higher) can run on.&lt;br&gt;&lt;br /&gt; &lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;br /&gt; Any operating system of x86 architecture&lt;/li&gt;&lt;li&gt;Any intel based macs (gnu/linux or osx)&lt;/li&gt;&lt;li&gt;ppc based macs running osx&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;And most certainly not ppc based macs running gnu/linux... how unexpected!&lt;br&gt;So there are two things to investigate from here:&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="a decoder/renderer for Macromedia Flash animations" href="http://swfdec.freedesktop.org/wiki/" id="uv1k"&gt;swfdec&lt;/a&gt; - which I have from ubuntu repositories&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="gnash" href="http://www.gnu.org/software/gnash/" id="j4g9"&gt;gnash&lt;/a&gt; (&lt;a title="devsite" href="http://savannah.gnu.org/projects/gnash/" id="vnhq"&gt;devsite&lt;/a&gt;)- which I also have from repos but am about to install from source.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;h2&gt;Gnash from source on ubuntu&lt;/h2&gt;&lt;h3&gt;Get bzr&lt;/h3&gt;&lt;blockquote&gt;sudo apt-get install bzr&lt;br&gt;&lt;/blockquote&gt;&lt;h3&gt;Get the source&lt;/h3&gt;&lt;br /&gt;&lt;blockquote&gt;bzr branch http://bzr.savannah.gnu.org/r/gnash/trunk gnash&lt;br&gt;&lt;/blockquote&gt;&lt;h3&gt;Follow the build instructions&lt;/h3&gt;&lt;blockquote&gt;./autogen.sh&lt;br&gt;&lt;br&gt;./configure --enable-gui=gtk&lt;br&gt;&lt;br&gt;sudo apt-get install libboost-dev libboost-thread-dev libgstreamer0.10-dev libagg-dev libboost-date-time-dev dejagnu swftools csound (and whatever else configure asks for...)&lt;br&gt;&lt;br&gt;./configure --enable-gui=gtk&lt;br&gt;&lt;br&gt;&lt;br&gt;./configure --enable-gui=gtk --with-boost-incl=/usr/include/boost&lt;br&gt;&lt;br&gt;&lt;/blockquote&gt;Repeat untill it stops whining... This was a while in my case... but after resolving the dependencies then manually specifying the boost include directory we get a make file! Might as well run that:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;make&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;This took a long long time on my ppc...&amp;nbsp; but eventually the usual:&lt;br&gt;&lt;blockquote&gt;sudo make install&lt;br&gt;&lt;/blockquote&gt;to finish up. &lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-6743455541885922117?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/6743455541885922117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/01/flash-on-ubuntu-ppc.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6743455541885922117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/6743455541885922117'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/01/flash-on-ubuntu-ppc.html' title='Flash on Ubuntu PPC'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9102179255330637934.post-626808874991219335</id><published>2009-01-28T19:15:00.000-08:00</published><updated>2009-01-28T22:19:55.585-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='scipy'/><category scheme='http://www.blogger.com/atom/ns#' term='plans'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Current state of the art</title><content type='html'>Hello and welcome to my dev blog!&lt;br /&gt;So this blog is to track what I am up to in my developing...&lt;br /&gt;&lt;br /&gt;I am a python convert - when ever I can I now use python.&lt;br /&gt;At this very moment I am working as an engineering intern for &lt;a href="http://tait.co.nz/"&gt;Tait Electronics&lt;/a&gt;. My research project here is "Using Python as a replacement to Matlab in the field of signal processing".&lt;br /&gt;To this end I am using &lt;a href="http://scipy.org/"&gt;scipy&lt;/a&gt; and &lt;a href="http://www.blogger.com/matplotlib.sourceforge.net"&gt;matplotlib&lt;/a&gt; daily. I have a iBook G4 (ppc) and run linux - precompiled binaries for closed source apps like skype and adobe flash simply don't get realeased for the powerpc. This makes life far more interesting!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Work environment&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Windows 2000 - eek&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Eclipse (Version: 3.4.1)&lt;br /&gt; &lt;ul&gt;&lt;li&gt;Pydev (1.4)&lt;/li&gt;    &lt;li&gt;Pydev Extensions&lt;/li&gt;&lt;li&gt;svn&lt;/li&gt;&lt;li&gt;mylyn&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Enthought Python Distribution (Py 2.5 + scipy + numpy + matplotlib)&lt;/li&gt;&lt;li&gt;Python 2.3 -&gt; 3.0 (and svn trunk)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;Home environment&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Ubuntu 8.10 (ppc)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Eclipse&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pydev&lt;/li&gt;&lt;li&gt;svn&lt;/li&gt;&lt;li&gt;mylyn&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;django (svn)&lt;/li&gt;&lt;li&gt;django-command-extensions (svn)&lt;/li&gt;&lt;li&gt;Python 2.5, 2.6, 3.0&lt;/li&gt;&lt;li&gt;scipy, numpy and matplotlib, pil...&lt;/li&gt;&lt;li&gt;gammu, python-gammu (No wammu - due to Segfault on startup)&lt;/li&gt;&lt;li&gt;Sony Ericson 880i + usb cable&lt;/li&gt;&lt;li&gt;MythTV/ftp/trac/svn/ssh server&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:180%;"&gt;Projects&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;txt-watch&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Not open source (at this stage) This project involves making a sms server for interacting with an alarm via txt messages or web interface. Making heavy use of python-gammu for the phone side of it, and django for the web side.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;eptidy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What does it do? Tidy up all your tv episodes. Rename and move your files in the way and location of your choice. Downloads episode names from imdb and renames them in the format you specify all from a cross platform native looking gui. Easily extended and editable to support other tv shows. Eptidy supports proxy setting&lt;br /&gt;Project Page: &lt;a href="http://eptidy.googlecode.com/"&gt;http://eptidy.googlecode.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;mailite&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Someone emails some_name@yourdomain.com This program reads the "to" address of the incoming email and searches through your sites members for anyone matching "some name", then looks up the email address of that user. It resends the email, from the original sender to the actual email address looked up. If the user wasn't found it optionally looks through a jobs database then at groups. If still not found the mail is returned to sender with a user not found error.&lt;br /&gt;Project Page: &lt;a href="http://mailite.googlecode.com/"&gt;http://mailite.googlecode.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;University of Canterbury Canoe Club Webpage&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Site: &lt;a href="http://uccc.org.nz/"&gt;http://uccc.org.nz&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;Custom php framework driven site... currently getting redesigned and one day I will redo in a real language...&lt;br /&gt;&lt;a href="http://code.google.com/p/mega8-hob/source/browse/websites/?r=238#websites/uccc%3Fstate%3Dclosed"&gt;Old version of the Code&lt;/a&gt; is online at my misc repo for all my shared uni code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Bev's Tramping Gear Hire and Ana's Place Websites&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Ditto uccc.org.nz - same framework...&lt;br /&gt;Tramping Information and Gear Hire: &lt;a href="http://bevs-hire.com/"&gt;http://bevs-hire.com&lt;/a&gt;&lt;br /&gt;Ana's Bed and Breakfast Te Anau: &lt;a href="http://anasplace.co.nz/"&gt;http://anasplace.co.nz&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Misc&lt;/span&gt;&lt;br /&gt;Usually have a few small projects for the flat server as well&lt;br /&gt;&lt;br /&gt;Getting a multi project trac install was the last thing I did. We have ordered new parts and are probably going to do a fresh server install of ubuntu tho, so not entirely sure about going through that again! Although it is very nice to have when its up!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Voipstunt&lt;/span&gt; - One of the more recent ones was making a script that logs into voipstunts free calling homeline to homeline. So we could go to the flat website and enter in a phone number and then our phone would ring as voipstunt connects us to the number we dialed...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Future Things&lt;/span&gt;&lt;br /&gt;A future project will be going from ubuntu to gentoo on my ppc because to many things are broken in the repository at the moment. Ekiga didn't work untill I compiled from source. Wx programs in general seem to fail. Filezilla flashes onto the screen before dieing a miserable death...&lt;br /&gt;Want to have a good play with &lt;a href="http://ompc.juricap.com/"&gt;ompc&lt;/a&gt;.&lt;br /&gt;A media manager for keeping track of what episodes you are up to in a series... in the very early stages of development for that...&lt;br /&gt;I want to get django going on my current webhost: http://x10hosting.com&lt;br /&gt;&lt;br /&gt;That should just about do it for now!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9102179255330637934-626808874991219335?l=bitsofpy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bitsofpy.blogspot.com/feeds/626808874991219335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bitsofpy.blogspot.com/2009/01/current-state-of-art.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/626808874991219335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9102179255330637934/posts/default/626808874991219335'/><link rel='alternate' type='text/html' href='http://bitsofpy.blogspot.com/2009/01/current-state-of-art.html' title='Current state of the art'/><author><name>Brian Thorne</name><uri>https://profiles.google.com/107068564517285727953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-kNNqpS5nH1g/AAAAAAAAAAI/AAAAAAAACmI/SWC9QhGXaX8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
