FLaser on Youtube
Hi there,
Just posted 2 videos from my FLaser Ver 1.0 (2 years ago) on Youtube. You can view it here:
An excerpt:
Preamble:
This project proposes a cost-effective solution of interacting with a projector screen using a laser pointer, via an ordinary webcam.
The system was deployed and scripted in Flash Actionscript 3.0, back in Dec 2007 to Jan 2008.
It subsequently won the Most Innovative Award and Best Exhibit at the Singapore Shell Science Fair 2008, was shortlisted by MOE to represent Singapore in the Taiwan International Science Fair (TISF) 2008, in addition to being an exhibited finalist at the A*STAR Singapore Science and Engineering Fair (SSEF) 2009.
For more information, please checkout http://blog.joeltong.org/ .
Method:
The system comprises of a screen image from a projector. A webcam is positioned to track the projector screen area.
The steps for successful detection are as follows:
1. Calibration - 4 Red dots are shown on-screen. Thresholding red, the system is able to pick out the distance between the four red dots, demarking the tracked active area by the webcam. A ratio is then computed which is used to position the mouse.
2. A red laser dot is then shone onscreen. Minor adjustment knobs compensate for the offset in terms of the computed position of the laser dot and its actual position, similar to zeroing in using a crosshair.
3. The system is ready to track the laser pointer. In this case, a much high threshold is used, from the fact that red laser beams have a much higher intensity from the surrounding background.
System has been shown to detect laser dot despite showing red noise. However, alternative algorithms are being devised fo9r the system for better background noise tolerance.
Do checkout the version shown at Shell Science Fair @ LINK. System is targeted at rhe Flash platform, and for home users.
For more enquiries,
Email: me {at} joeltong {dot} org.
Thanks!
Best regards,
Joel Tong
http://blog.joeltong.org/
Improved Image Viewer
Happy Chinese New Year!! Been dabbling around with my image viewer class during my free time in the past few days. Still purely AS3, albeit with more stuff like:
- Navigational bar
- Caption support
- Page left-page right flipping motion
- Varied animations to choose from. If you can't decide, leave it blank and it will randomize it for you.
- Quite dynamic, and (compiled in CS3) it's only 15kB! xD
- Auto screen-fit resizing
Screenshot as above! =D Enjoy!
So, proprietary or open-source? =D
XML Powered Gallery / Display Header (TOTALLY IN AS3)
Hey,
Currently I am at work doing a custom utils library for Flash. Of course, totally (or mostly) written in AS3 xDD. Just came up with the basic skeleton of an XML-powered header. Something like what I did for E Club, except this time it will be much more customizable and easier to use for people w/o Flash. Elegant - 12kB and I hope to put it more features too! =D
See this site for a live demonstration.
Since source is rather short, I shall post it here as well. Look forward to a ver. 2 in the future! =)
package org.joelTong.utils.displayImages { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.Sprite; import flash.net.*; import flash.events.*; import flash.utils.Timer; import caurina.transitions.*; /** * joeltong.org * @author JOELTONG * joel [dot] tong [at] gmail [dot] com */ public class ImageBanner extends Sprite { private var WIDTH :uint; private var HEIGHT :uint; private var _images :Array; //this is the image that is shown on stage private var _imageList :Array; //this is the loader for the images i.e. precached private var _xmlList :XML; //this is the xml file private var _timer :Timer; //switching purposes private var _topIndex :uint; //the index of the topmost image currently (1 or 0). private var _curPic :uint; //the current index in imageList (up to the size of array). public function ImageBanner(w:uint = 0, h:uint = 0 ):void { super(); var loader:URLLoader = new URLLoader(); _images = new Array(); _imageList = new Array(); _timer = new Timer(4000, 0); WIDTH = w; HEIGHT = h; _images = [new Bitmap(new BitmapData(WIDTH, HEIGHT, true, 0xFFFF0000)), new Bitmap(new BitmapData(WIDTH, HEIGHT, true, 0xFF00FF00))]; loader.dataFormat = URLLoaderDataFormat.TEXT; loader.addEventListener(Event.COMPLETE, onXmlLoaded); loader.load(new URLRequest("bannerList.xml")); //add to container addChild(_images[1]); addChild(_images[0]); //set up boundable area var mask:Sprite = new Sprite(); mask.graphics.beginFill(0xFF0000); mask.graphics.drawRect(0, 0, WIDTH, HEIGHT); this.mask = mask; this.addEventListener(MouseEvent.CLICK, onClick); } private function onXmlLoaded(e:Event):void { _xmlList = new XML(e.target.data); trace(_xmlList.entry.length()); precacheImages(); } private function precacheImages():void { for (var i:uint = 0; i < _xmlList.entry.length(); i++) { _imageList.push(new Image(WIDTH,HEIGHT)); _imageList[i].setLoading(_xmlList.entry[i].location); } this.addEventListener(Event.ENTER_FRAME, preloadImgs); } private function preloadImgs(e:Event):void { if (checkLoading()) { removeEventListener(Event.ENTER_FRAME, preloadImgs); setupTimer(); } } private function checkLoading():Boolean { for (var i:uint = 0; i < _xmlList.entry.length(); i++) { if (!_imageList[i].isLoaded()) { return false; } } return true; } private function setupTimer():void { _timer.addEventListener(TimerEvent.TIMER, onTimer); _timer.start(); _topIndex = 0; _curPic = 1; _images[0].bitmapData.draw(_imageList[0]); _images[1].bitmapData.draw(_imageList[1]); } private function onTimer(e:TimerEvent = null):void { Tweener.addTween(_images[_topIndex], { x: WIDTH, time: 1, transition:"easeInElastic", onComplete: swap } ); } private function swap():void { trace("called"); this.swapChildren(_images[0], _images[1]); _topIndex = (_topIndex + 1) % 2; _curPic = (_curPic + 1) % _xmlList.entry.length(); trace("CURPIC: " + _curPic); trace("INDEX: " + _topIndex); trace(_imageList.length); //TODO: FIX THIS BUG _images[(_topIndex+1) % 2].bitmapData.draw(_imageList[_curPic]); _images[(_topIndex+1) % 2].x = 0; _images[(_topIndex+1) % 2].y = 0; } private function onClick(e:MouseEvent = null):void { navigateToURL(new URLRequest(_xmlList.entry[_curPic].url), "_blank"); } /* private function onComplete(e:Event):void { var bit:Bitmap = new Bitmap(new BitmapData(500, 200, true, 0xFFFF0000)); bit.bitmapData.draw(e.target.content); addChild(bit); }*/ } }
package org.joelTong.utils.displayImages { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.events.Event; import flash.net.URLRequest; /** * joeltong.org * @author JOELTONG * joel [dot] tong [at] gmail [dot] com */ public class Image extends Bitmap { private var WIDTH :uint; private var HEIGHT :uint; private var loader :Loader; private var state :String; public function Image(w:uint = 100, h:uint = 100):void { WIDTH = w; HEIGHT = h; super(new BitmapData(WIDTH, HEIGHT, true, 0xFFFF0000)); state = "LOADING"; } public function setLoading(url:String):void { loader = new Loader(); loader.load(new URLRequest(url)); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImgLoaded); } private function onImgLoaded(e:Event):void { this.bitmapData.draw(e.target.content); state = "COMPLETE"; } public function isLoaded():Boolean { if (state == "COMPLETE") { return true; } else { return false; } } //getters and setters--------------------------------- } }
package { import flash.display.Sprite; import org.joelTong.utils.displayImages.ImageBanner; /** * joeltong.org * @author JOELTONG * joel [dot] tong [at] gmail [dot] com */ public class Main extends Sprite { private var imageBanner:ImageBanner = new ImageBanner(1024,768); public function Main():void { addChild(imageBanner); } } }
Crossdomain.xml woes
Hey,
After much trying, it seems that there's not much that can be done implementing an online radio station player in Flash due to the security sandbox. Realised that crossdomain.xml has to be implemented on the radio station server's side, not mine. AKA, the best would be to run it in adobe Air or within the Flash IDE itself. =(
On a lighter note, I just passed my BTT. Meaning that I can commence my driving lessons. =D
Shall go read up on group theory for machine vision.
Rgds,
Joel Tong
Reflection
Hey,
I think the screen isn't as reflective as it should be. Hopefully it will work better on a wall? Haha. Anyways, thinking of doing this:
max contrast -> max saturation -> greyscale -> gaussian blur -> threshold -> final img.
Rgds,
Joel Tong
FLaser
Hi,
Been busy the past few days trying to do a Ver. 2.0 of my Science Fair project. So original name from "STUDY OF LUMINOUS INTENSITY AND ITS APPLICATIONS IN LASER-AIDED VIRTUAL ON-SCREEN IMAGE INTERACTION SYSTEMS", changed it to FLaser. (Obviously, FL being Flash). xD
Managed to get clearance from my mentor @ A* STAR DSI to further develop it. You can read more of it here:
- http://temasek.wetpaint.com/page/DSI:+Creation+of+LASER-aided+virtual+on-screen+image+interaction+systems
- http://www.science.edu.sg/ssc/ssef-ats/publicview.jsp
Apparently, IHPC is doing something similar for the Mac called Lightdraw. Will see if I can port / improve some of the algos and source code in their project. Link here:
And something I stumbled upon for augmented reality in Flash (FLAR):
Pretty cool huh? =D
Cheers,
Joel Tong
Labs @ JoelTong.org
Hi,
If you've been wondering what I been doing for the past few days, here's this: Labs. Will upload it soon.
Update on Today
Hey there,
Well spent some time looking at getid3() . Was trying to make a customized PHP to XSPF converter for Dingle using the getid3() package, but didn't manage to do so after staring 5 hours at the documentation. Haha. Probably would source for another library (if I have the time =P).
Anyways, came up with an auto-gen using PHP. So upload songs to directory, access localhost, and tada. =D
Anyone want to help convert the ID3 tags to XSPF format using PHP? PM me =D
See you @ the ASFUG meeting if you are going! It's this Sat.
PS Something to remember:
9 A man’s heart plans his way,
But the LORD directs his steps.
[Proverbs 16:9]
Dingle MP3 Music player
Hey,
Just done with cleaning up the Dingle MP3 music player. Now comes with a comprehensive configuration that allows you to color and set just about anything (including the visualizations, fonts, glow, dimensions, etc.). =P Final file size? 33kb (w/o embedded fonts). If you are gonna embed fonts, 120kb =P
Global variables file can be found in Config.as .
Enjoy! =D
Made a color scheme called fiery:
