Thursday, December 25, 2008

My First Digital Frame

Yesterday I bought my first digital photo frame. It's a Kodak W1020. It has its ups and downs (imho), and I've been stirring up some ideas for this new gizmo of mine.

The major ups:
  • It's wireless
  • It reads from media rss streams

Without too much hassle I plugged in the power, latched into my home wireless network, and had connected to my Flickr account. Soon after I connected to the open net the frame asked if I wanted to upgrade my firmware - I did so and it was painless and easy; I would reccomend doing this.

My major downs:

  • My second button on the vertical menu does not work. Darnit!! Most of the time it is used as a play button and I can get around not having it... but its just damned annoying.
  • Minimum change time of 3 seconds... would like it to be smaller (I'll explain why later).
  • I cannot get my (vertical) images to 'Fill screen'? (Image's can either leave space either side or get cropped in order to fill display real estate.. I prefer fill screen)

So I'm happy with the purchase but I think they've got a couple things to fix for the firmware upgrades.

Congrats and crits aside.. Here's my latest idea: Since the frame can read and display images from a properly formatted media-RSS feed, host such an RSS service on a machine on the same local network as the frame.

This RSS feed could/would be the aggregation of interesting media sources such as my Flickr stream, my contacts photos, youtube videos, etc. Further more I would like to be able to plugin RSS feeds that provide small amounts of textual info, like microblogging feeds or news headlines. The textual info should be rendered to an image, which is then cached on the stream server, and can then be picked up by the digital frame.

This is all a means to an end. The main idea here is that now I can write a small app that polls my email accounts. Then when I get an email I can push an alert to a text rss stream, which will feed into my RSS engine thingy, render the relevant picture, and ultimately get displayed on my digital picture frame sitting in front of me on my desk.

Further down the line I thought it would be great to hook the frame up to my VOIP client. So as I get a call, the frame should display who's calling me with a pretty picture of them. The problem here is latency of the picture change on the frame. 3 second changes for something more realtime as this is not practical. One last idea,.. Winamp plugin: on song change - display song details?..

The more I develop this idea in my head the faster it grows - cant wait to make this (or for someone else to make it first).

Tuesday, December 2, 2008

I want a web desktop

It seems the web is awaking to the concept of interoperability between service providers. I read somewhere, and so true it is, that it's ironic how, in a sense service provision is returning to the 'mainframe'. The web as a platform offers so many advantages over the desktop platform, but in many regards the desktop is still the home to the user. So; how can we get the web up to speed - not to replace the desktop, but to be as comfortable, secure and integrated as the desktop? What do we need? What does the user want? What do I want?
Here's a couple of ideas... It's not an exhaustive list; It's just some ideas.
The web in the future:
  • Everything is open
  • Everything is decentralized
  • User space is shared and accessible
  • The user has control of their own information

So How do we decentralize our systems in an open manner?
Security and data integrity is a critical issue shaping the web. Decentralization and openness always comes coupled with policies and procedures. So how do we share personal and business intelligence in a fair and controlled manner? If a user has permission to view or mash information on one system, how can we securely let him reference that information from another system? (I realize this is a paragraph of questions,...)
It is becoming more frequent to perform more of our daily work functions online; The trend of remote storage and processing is undeniable. The internet computing cloud is storming. I myself do not store email, pictures, video or music on my local computer; All of these are provided by -free- online services. In my work environment 4 out of the 6 regular applications I use all reside on the intranet.
Another interesting thing to watch is the commercial adoption of social engineering (or more generally any 'Web2.0') platforms. Work environments, at least the ones I've worked in, either embrace the evolving web, or try and firewall it out. I always enjoy hearing of success stories from organisations that have embraced the evolving web; One of the examples that spring to mind is that of the micromessaging arena. Many companies now use Twitter et al to communicate within their organisation - and find it very effective. There are now many comercial micromessaging platforms that offer packages to willing corporates that want the paid support. So what - Why am I mentioning this?

I believe the web is the dominant application domain now - and if your industry doens't fit into this rather swooping statement then, I beg to argue, that it most likely will in the future. Now I can either be in the company that waits to see what happens with the web and design my business around accordingly, or I can storm ahead and be on the forefront of the evolving web platform. Gotto admit - I prefer setting trends rather than following them.
What do I want my web platform to be? As a starting point I'm just going to throw together another list. This will be a few things that I would like to see out of a web framework, and the web in general. [Some are slightly redundant, but I thought it coloured in the picture nicely]

  • I, as a user, want control.
  • As a user, when I open my browser (or log on to the internet per say), I want to have access to all my information, all the time.
  • I need a clear entry point or a mechanism to manage my online life.
  • I want a platform that will abstract (hence simplify) the communication between different flavours of the same product type.
    Example: Which Instant Messenger do you use? AIM, Gtalk, Skype, SIP, Gizmo, XMPP? What about your friends? This issue has been cordially addressed with the applicaiton of XMPP and multi-protocol clients, but this is an example of the open web and the need to find common ground between service providers.
  • I want to be able to choose where I store my personal data and for that data to be seemlessly accessible from everywhere else I go.
    Exmaple: If I'm at work, I do infact want to set my web-desktop background to that picture of my wife and kids. Sure some business policies will prohibit personal data accessability, but for those work environments that aren't so, dare I say 'old-school', as to lock down everything, I want this accessability.
  • I want clear ownership of some of my information.
    Example: I want to store my financials and budgets on my FTP server at home, but these should be as readily available to myself, as my online photo album. [And no,.. I don't want to carry around a portable FTP client on USB.] I want a web-desktop that seemlessly integrates with my online data, and my personal data at home.
  • Some people are technical,... some are not. This is a fact of life. If the system does fit a decentralized model, the take-home installer should be simple to setup.
    I want to addon to my web desktop system and code new plugins - My sister does not; She just wants to click once and install - Furthermore, my mother doesn't understand what installing is, she just wants to logon to a hosted solution.
  • My web-desktop system I host at home, the one I subscribe to online, and the one we use at work should in some manner communicate and synchronize.
  • I want to access my web-desktop from a plethora of different devices; Such as my computer, mobile phone, UMPC, or any other capable computing device.

Well some might say that these things are highly improbable. How will the world accept such infusion between all of a persons online life?

Will business's ever let me have access to my personal desktop (or portions thereof) at work?

How many end users actually understand the concept of decentralization? (Few would be my guess.) I tried to explain OpenID's to my wife once and she could not see the purpose of it.Worst case scenario,.. lets just wait for my generation to pass. I would put money on it that in ten years every site will be OpenID enabled. The problem with most users in this 'internet generation', is that even though we all know how to use a computer , unless there's a need to know, we don't want to. It seems the best time to teach a generation of users new concepts, is in their infancy. In some ways this makes me sad that the digital-experience I yearn to have will only really become a reality for the next generation.

So what do I want?
I want a desktop for the web. A platform for integrating all my online escapades into a web platform. My very own personal web desktop.

Tuesday, November 18, 2008

Java Image Comparison - Motion Detection

So this is what I've managed to do with some simple image comparison thus far... I've repackaged it all to try make some sense of it; The sample apps reside in com.b22222.app.webcam; The most informative app probably being WebCamState.java

I've simply zipped my source folder. I use eclipse at this present time and have left my project settings file in the archive. The sample apps require java's JMF to be installed on the system.


What are my goals?
I want to design some kind of (physical) contact free input system; This system should be as functional as, or more than the standard keyboard and mouse. Now that's the main goal... A bunch of other possibilities have come alive since I've been tinkering around. I can now set my camera facing the front door and get email alerts at work (with pictures of the culprit) when motion is detected at home. I've also got plans in the pipe to design a kinetic sculpture that reacts to motion in front of it. The list continues.

Where am I now?
I can continually read from a live stream of webcam video and dismantle the picture into more pliable data. With this data I can pick up motion hotspots, primitive edge detection (particularly bad on blunt edges), and some noise reduction. All this is demo'ed in the attached library of code. Please keep this in mind that I develop in spare time by myself who has never studied image or video in large depth - I mostly only design as much I need to progress onto my next goal.

Most general application settings end up in my settings.ini file. This might be a good place to start tinkering with values if you want to poke and prod my library. I had tried to use a neural network to interpret webcam input but it never really worked. I have left my code there in case I revisit that idea. The neural net library I used is called Joone and is freely downloadable.

Details of how I dismantle an image:
Although I have copied the code in several places throughout, the best piece of code to reference this process is probably com.b22222.routine.ImageHelper.
A BufferedImage (Raw Image pixel data) is drawn from the webcam source. This image is converted into what I called a State object. A State is simply a 2d array of integers. At the moment this array represents the brightness on the pixels from the image. (I plan to somehow incorporate hue difference into this as well in the future.) From here you should partly forget that you are working with images, but rather arrays of numbers. I did this so that from here our code could be used for any map of numbers - Say cloud patterns, or temperature maps. (Not that I ever intend to go down this road myself)

A Comparison is an object drawn from the difference of two States. If I remember correctly I just subtracted one array from the other. We now have a new array of numbers representing the difference between to images. This may help two fold; a) I'm obviously searching for motion, and b) if 70% of an image rarely changes then we want to consciously ignore it.

Next a primitive EdgeDetector object can process the change map to emphasize the edges of island and lines. This is not an essential stage and could quite likely be taken out if it is silencing too much useful data.

After that I found two statistics of the data in the array: The average, and the *standard-deviation. Then using these multiplied by factors specified in the settings file, if the value in the array is not greater than the average + std-dev, then it is set to zero. This helps clean up small noise generated through subtle light differences, etc.

The array that is now left contains data that is somewhat usefull to me. And hopefully you :-)

*Ps: I always mixed up standard deviation and variance. It's one of the two. I think.

This can all be seen in action in the com.b22222.app.webcam.WebCamState class.
Instructions for use: Run the app. Wait for the video feed to register in the left window. (Mine usually takes a few seconds). Then click the left button titled 'Capture Base Image'. This will set the image to compare against for motion detection. Now click the right button titled 'Start Compare...'.

Here is a demo of when I tuned my settings to pick up my black pen against a white wall. (The red circles are rendered onto the image in areas of interest. The double green circle is the center of gravity of the points of interest)


What do I plan on doing next?
Creating a more 'opaque' input interface. This interface would expose some events and hide all of the workings by the libraries described above. This interface will most likely provide some kind of coordinate information. I would also like to provide, but have no idea how, a polygon best representing the image input.

Long term?
I'm thinking of a menu/list based input system. A user would navigate from menu to menu choosing options which would either automate keyboard input or mouse input. This is in part a resignation because I don't think getting pixel perfect mouse positioning will be viable with webcam input; but storing keyboard/mouse inputs in templates, sequences and menus could reduce work for repetitive actions normally done on these devices.

In case you missed it up top, this is the source code.

Thursday, August 28, 2008

Mootools Block Fx

So I found http://gruppler.dojotoolkit.org/ - It looks really great - Only problem is I'm a proud Mootools fan... So I whipped together a mimic - Fx.Block.

Fx.Block is a simple way of applying morphs to a set of clipped blocks achieving a greater effect. I thought it might add consistency to use a similar build up as morph and tween. I know my code will serve as an abomination to the general Mootools community; I've most likely transgressed every second Mootools design pattern. The effects are slow and coded ugly. But I achived what I wanted: a start. I encourage everyone to please try do better and leave links to your work in the comments. Hopefully someone else can take this and reshape it into something more production ready.

Ideas moving forward:
  • Chaining effects to produce even more complex animations.
  • Better code and class structure that facilitates extending effects.
  • Fx.Block isnt my favourite name - How about Fx.Compund? Fx.Anim?

An example of using this code:
new Fx.Block($('element'), { effect: Fx.Block.Explode }).start();

If you didn't catch it up top, the code and examples can be found at:
http://b22222.com/files/mooblock.html

Thursday, July 17, 2008

Java Image Comparison / Motion Detection

I've recently purchased a wireless security camera which is very conveniently smaller than a cubic inch. Well the imagination runs wild once you've got this device,... Who can I spy on? What can I monitor? What does the domestic worker actually do when I'm at work?.. and so the list continues.

I played around in java's JMF for a day and soon had a small app that recorded one still frame per second. Now I could review the recorded images when getting home at the end of the day. Hovever, 1 frame per second equates to 36000 images over the 10 hour work day that I'm not at home! I don't really want to record motion video - yet. I'm still happy with working with images,.. albeit a lot of them. So now I've got a haystack of images, and presumably somewhere inside of them is the needle of interesting footage.

I searched pretty hard for a Java image comparison class or library and could not find anything. Just a whole bunch of forum posts declaring how advanced the topic can get. So sleeves up, I created my own rudimentary ImageCompare class. (Download Link). It's not bulletproof, and its not lightspeed, but for my purposes it's done the job perfectly.

The class breaks up the images into smaller regions and compares the brightness of each corresponding region. If any particular pair of regions are vastly different then something must have changed in that part of the image.

How to use:

// Create a compare object specifying the 2 images for comparison.
ImageCompare ic = new ImageCompare("c:\\test1.jpg", "c:\\test2.jpg");
// Set the comparison parameters.
// (num vertical regions, num horizontal regions, sensitivity, stabilizer)
ic.setParameters(8, 6, 5, 10);
// Display some indication of the differences
in the image.
ic.setDebugMode(2);
// Compare.
ic.compare();
// Display if these images are considered a match according to our parameters.
System.out.println("Match: " + ic.match());
// If its not a match then write a file to show changed regions.
if (!ic.match()) saveJPG(ic.getChangeIndicator(), "c:\\changes.jpg");


The setParameters() accepts four parameters.
  1. The number of vertical columns in the comparison grid.
  2. The number of horizontal rows in the comparison grid.
  3. A threshold value. If the difference in brightness exceeds this then the region is considered different.
  4. A stabilization factor. In future I will calculate this automatically since it is proportional to parameters 1 and 2.
setDebugMode() is completely optional and only really usefull while designing your parameters.

After running compare(), match() will hold the result.

Example:
The above code was run on the following two images:




The console output looked like this:
|0,0,0,0,0,0,1,0|
|0,0,0,0,0,0,0,1|
|0,0,0,0,0,0,0,3|
|0,0,0,0,0,1,1,8|
|0,0,0,0,0,0,0,8|
|0,0,0,0,0,1,0,0|
Match: false
... and the image output (changes.jpg) looked like this:



On my todo list:
  • Provide an array/vector of changed regions, or number of changed regions.
  • Heuristically determine a stabilizing factor, thus not having to specifying one.
  • Allow for the input of area vectors before comparison for the purpose of excluding or only checking these areas.
  • I'd also like to integrate this into a more real time solution that then exposes events and the like.

What you see here is a very alpha stage development. Take it and use it if you like, but do so at your own risk,.. or frustration. I'll try post some updates to this code as and when significant changes have been made.

Follow-up post: http://mindmeat.blogspot.com/2008/11/java-image-comparison.html

Friday, June 6, 2008

Google Treasure Hunt - Question 3 & 4

I grouped my solutions to questions 3 and 4 together for two reasons.
a) Life is short - I'm saving time.
b) Question 3 didn't involve me writing a program to solve it and there's not much to talk about anyway.

The competition can be found here: http://treasurehunt.appspot.com/

Question 3
A packet is sent out from host H with a destination of 41.196.52.48. Which nodes does the packet pass through on its way to the destination? (include start and final node in your answer)
They then provide you with a diagram and a routing table.

Personally I thought writing a program for this would be more labor than automation. So I pulled out the local handy spreadsheet application and pasted in the routing table. Then node by node, traced the path of the packet going through the network. My solution passed through 8 or 9 nodes to reach its destination. Waiting the 8 hours for my confirmation was more challenging than the question.

Question 4
Find the smallest number that can be expressed as
the sum of 3 consecutive prime numbers,
the sum of 23 consecutive prime numbers,
the sum of 999 consecutive prime numbers,
the sum of 1489 consecutive prime numbers,
and is itself a prime number.

For example, 41 is the smallest prime number that can be expressed as
the sum of 3 consecutive primes (11 + 13 + 17 = 41) and
the sum of 6 consecutive primes (2 + 3 + 5 + 7 + 11 + 13 = 41).
A funny story here: This question, if my calculations were correct, was released around 11:15pm GMT, around 01:15am in Durban ZA where I live. I couldn't wait for morning so I set my clock for 01:30am to specially get up and read the question. The funny thing about this is the next day someone said to me; 'I bet there are people that get up in the middle of the night to solve these things'. I just kept quiet.

Well I slept on it -literally- and made this Java app the next day.
To run:
java.exe GoogleQ4 40 1489 999 23 3

The first argument is the certainty factor for testing primes. The rest of the arguments are obviously the parameters from the question.
For the parameters quoted above my program gave the following output: (I haven't verified this result..)
********************************************
9491851 -> computed in 141 seconds.
********************************************
A further explanation of my logic:
Now I'm no mathematician so I'm not aware of any direct formula to solve this puppy; So I'll resort to a mechanism of over complicated logic. I visualized this problem as a set of 'Slide Rule Thing-a-ma-gigs' sliding over the prime number set.


The example in the image above doesn't balance but use it to visualize this process:
1) Drag the first slide to its next offset.
2) Calculate the slides new total. (All the numbers it hovers over)
3) Move to the next slide above it.
4) Drag this slide from an offset where the slides total will be smaller than the previous slides total, to somewhere where the slides total is greater. If a matching total is found then we can recurse to steps 3 and 4 for all our other slides.
5) When a similar total is found for all slides then we have our answer.

The method I have used requires a lot of array manipulation. I figure it makes sense to enter your arguments greatest to smallest as this will greatly reduce the amount of work the machine will have to do.

Other things that might help to speed up the slide rule machine:
- The use of vectors or linked lists (something not fixed array based) would probably help.
- A better algorithm to position the initial offset of each slide when recursing to that next slide. Originally I just started each slide from 2 everytime. gasp!. After a while I realized I was moving every slide 1000 odd positions before it was even close to solving the answer. Currently it starts the next slide where the previous left off.

Well thats all there is to my solution. Probably not the best, but I got the answer right first time. Whoopee.

Thursday, May 29, 2008

Google Treasure Hunt 2008 - Question 2

This is a continuation of my solutions to Google's treasure hunt. My post on question 1 can be found here.

The Question:
Here is a random zip archive for you to download:
GoogleTreasureHunt08_123456123456123456.zip

Unzip the archive, then process the resulting files to obtain a numeric result. You'll be taking the sum of lines from files matching a certain description, and multiplying those sums together to obtain a final result. Note that files have many different extensions, like '.pdf' and '.js', but all are plain text files containing a small number of lines of text.

Sum of line 2 for all files with path or name containing foo and ending in .xml
Sum of line 4 for all files with path or name containing mno and ending in .pdf
Hint: If the requested line does not exist, do not increment the sum.

Multiply all the above sums together and enter the product below.

Well this question begs for a [program,script,bash stmt] to be written. It doesn't even begin to make sense to do this manually..

Here's my Java source: http://b22222.com/files/GoogleQuestion2.java
One just needs to modify the set of rules and the location of the unzipped folder.

I just posted my answer for question 3; I have to wait 8 hours for the result! Oh well, fingers crossed.

Happy Googling!

Monday, May 19, 2008

Google Treasure Hunt 2008

So Google is running a treasure hunt. 1 puzzle a week for 4 weeks. I love puzzles.

The first puzzle they have up goes something like this:
A robot is located at the top-left corner of a 52 x 52 grid. The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid. How many possible unique paths are there?


For a while I tried to picture the mechanics of this problem in my head. It was too much,.. I would soon get lost trying to keep track of a dozen different paths and shapes all at once. So i resorted to paper. Not too long and I was having good progress. I would draw grids with numbers in each cell representing how many paths could be made from that cell to the bottom right. The trick was to start small.

I drew grids for 2x2 and 3x3. I still couldnt work out the pattern,.. Then I drew 2x3 and 3x2 grids; Bingo.



Overlay/Imageine a 3x2 and 2x3 grid at the bottom-right of the grid above; To work out the total number of paths from the last missing cell (of 3x3) is simply all paths available in both the 2x3 and 3x2 grids. Still dont understand,..
Simply put: The number of unique paths from any cell to the finish is equal to the sum of, the number of paths from the cell on the right, and the cell below it.

Here is the Java source I used to calculate my grid (55 x 60). My answer was 696940125414123253093858308567840.

I would be interested in looking over the mathematical formula that calculates this directly incase anyone happens to know it.

Happy treasure hunting!

PS: My code calculates the map upside down and other way around... In other words, the robot is going from bottom right to top left. Not the same as the picture above.

Tuesday, April 1, 2008

BR cleaner VS other cleaners

I've always got a bit of a mess on my hands when I'm finished CSS'ing an HTML form. With all the different forces shaping form development I sometimes find it difficult to get a form to look exactly the same in every browser, and to look pretty when degraded out of CSS.

Traditionally I've used divs or spans as a 'cleaner' element to clear the floats above it. I don't know where I learned this common trick, but for as long as I can remember now I've used the cleaner class and some empty divs round around the form to try correct line breaks and the form layout.

Completely randomely I tried something different today. I used a line break element as my cleaner. omg - Why have I never done this before? Now my line breaks act as line breaks when
CSS fails, and then they act as cleaners with CSS enabled. So far its been too good to be true,.. literally; I'm waiting to see why I haven't seen this elsewhere - Waiting to see where it breaks.

Here's a demo of what my cleaners now look like:

<style>
br {
display: none;
}
.cln {
display: block;
clear: both;
}
</style>
... blah blah fish paste ...
<div>My floated left element</div>
<div>My floated right element</div>
<br class="cln" />
<div>The rest of my content</div>



Some last notes:
I hide all line breaks by default because they are really there only for graceful degradation. If the client has CSS enabled then I don't want extra line breaks mucking up my presentation. On the other hand, when CSS is enabled then the linebreaks with the 'cln' class will be displayed and, simply put, line break over the above floated elements.

Wednesday, February 27, 2008

Time

For as long as I can remember now, time has only ever got faster. I never feel like I can do more than I used to - I'm always thinking how there just isn't as much time as there used to be.

Thursday, February 21, 2008

Powermate in C#

Well about four months ago I bought a Griffin Powermate. It's pretty much as good as they say except I think it could have been a little more solid. It looks a lot heavier in the pictures.

Now the only real gripe I had with the Powermate was the drivers. I battled for, I kid you not, days. I installed, connected, uninstalled, disconnected, reinstalled, reconnected this darn powermate so many times, that even by chance I should have got it to work.

The retailer I bought it from, SimplyMac.co.za in Johannesburg, wanted nothing to do with me. They simply denied me warranty on the item and told me to search Griffins site for help - Which I had already done by then! All I'm saying is that I will never buy from them again. Griffin was more helpfull,.. well nothing they suggested actually helped, but it didn't stop them from trying. I believe that if I carried on emailing their support team they probably would have got me to ship it over to get repaired.

I don't know how many people out there have battled with Powermates, but mine just seemed to move the cursor horizontally across the screen. The Powermate registers itself as a mouse-type device and thus without drivers will just cause the cursor to move slowly across the screen. With drivers and software you are meant to be able to assign more helpful actions to the Powermate; like changing the volume or scrolling your current document up and down. So since my Powermate made the mouse move without drivers, I reckon the problem must reside in the drivers. Surely if there was a fault in the Powermate itself then the device wouldn't register on the computer at all. Well whatever the problem is, shipping it over to the States is gonna cost be money. So some DIY was sounding good.

Yesterday I started snooping around C#, and hey,.. Presto! In half a day I managed to hack together a small app which:
1) Detects all the mouse HID's installed.
2) Links in to the data sent from the Powermate, and ..
3) Adjust the system volume or pump a page scroll.

Now I really did hack it together, I'm not even going to try take credit for the source. Having a good knowledge of Java and some C++ I managed to interpret the C# syntax without too much trouble but,... I'm not a C# guy so keep that in mind if you looking through the code.

Here's the source with binaries included: http://b22222.com/pmate.zip
Note: I coded this using MS Visual C# Express which I think uses dotNet 3.5

Directions for use:
Run PMate.exe (duh).
By default the Powermate then controls your volume.
If you press the Powermate it alternates to controlling page scroll.

The three thing's I'm not satisfied with yet in this solution are:
1) The program has a bit of delay while reading from the Powermate - Not ideal.
2) The Powermate still pumps regular mouse events. So pressing the Pmate still invokes context menus :/
3) I don't know how to properly hide the form, so it infact just minimised without a taskbar button. This allows you to still ALT-tab to the app.

At the end of the day though I'm quite happy with the solution. It gives me a bit of a geeky thrill turning the Powermate and knowing that I somehow got it to change my volume.