Recently in Flash Category

(Flash) abstraction of water

| No Comments | No TrackBacks
I came up with an idea of making a flat and abstract animation from a video.
I choosed an ocean scene form a movie of galapagos islands and tried to extract the colors and movements and make it into another movie that looks totally different. I also made three more videos using the same method and uploaded them to vimeo and youtube.

abstraction of water from kynd on Vimeo.



cycling in the woods from kynd on Vimeo.



SMOKE from kynd on Vimeo.



drive in the night from kynd on Vimeo.

(Flash) Finding objects from a photo

| No Comments | No TrackBacks
  1. Find the edge of the objects by superimposing slightly displaced images in DIFFERENCE mode and then remove noise with ConvolutionFilter and the threshold method.
  2. Separate the edges into blocks using the getColorBoundsRect method.
  3. Draw lines around the edges in each of blocks(Voila!)
(This sample only works well with a photo with a rather simple background)



Sample code

Not very organized yet and for demonstration purposes only.
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.filters.*;

public class Detector {
private var s:BitmapData;
private var r:BitmapData;
private var blocks:Array;

public function Detector() {
}

public function proccess(s:BitmapData):Array {
var r1:BitmapData,r2:BitmapData,r3:BitmapData,r4:BitmapData;
r1 = getDiffImage(s);
r2 = getBlocks(r1);
r3 = drawBlobs(s);
return [r1,r2,r3];
}

public function getDiffImage(s:BitmapData):BitmapData {
var r:BitmapData = new BitmapData(s.width,s.height);
var r2:BitmapData = new BitmapData(s.width,s.height);
var rect:Rectangle = new Rectangle(0,0,s.width,s.height);
var pt:Point = new Point(0,0);
r.draw(s);
r2.draw(s);
var mtx = new Matrix();
mtx.translate(2,0);
r.draw(s, mtx, new ColorTransform(), BlendMode.DIFFERENCE);
mtx.translate(-2,2);
r2.draw(s, mtx, new ColorTransform(), BlendMode.DIFFERENCE);

r.copyPixels(r, new Rectangle(2,0,2,s.height), pt);
r2.copyPixels(r2, new Rectangle(0,2,s.width,2), pt);

r.draw(r2, new Matrix(), new ColorTransform(), BlendMode.ADD);

var filter:ConvolutionFilter = new ConvolutionFilter(3,3,
[0.1,0.1,0.1,
0.1,0.1,0.1,
0.1,0.1,0.1]);
r.applyFilter(r,rect,pt,filter);
r.threshold(r, rect, pt, "<", 0xff111111, 0xff000000);
r.threshold(r, rect, pt, "!=", 0xff000000, 0xffffffff);
return r;
}

public function getBlocks(s:BitmapData):BitmapData {
blocks = new Array();
var i:uint=0;
var o:Object;
var size:uint;
var r:BitmapData=new BitmapData(s.width,s.height);
r.draw(s);
var sp:Sprite = new Sprite();
var g:Graphics=sp.graphics;
var rect1:Rectangle,rect2:Rectangle;
while (true) {
i++;
if (i>1000) {
break;
}
rect1=r.getColorBoundsRect(0xffffffff,0xffffffff);
if (rect1.isEmpty()) {
break;
}

var x=rect1.x;
for (var y:uint = rect1.y; y < rect1.y + rect1.height; y++) {
if (r.getPixel32(x,y)==0xffffffff) {
r.floodFill(x, y, 0xffff00ff);
rect2=r.getColorBoundsRect(0xffffffff,0xffff00ff);
size=rect2.width*rect2.height;
if (size>300) {
o = new Object();
o.size=size;
o.rect=rect2;
o.bmpd=new BitmapData(o.rect.width,o.rect.height);
o.bmpd.copyPixels(r, o.rect, new Point(0,0));
blocks.push(o);
}
r.floodFill(x, y, 0xff00ffff);
}
}
}

for (i = 0; i<blocks.length; i ++) {
g.lineStyle(0,0x00FF00);
g.drawRect(blocks[i].rect.x, blocks[i].rect.y, blocks[i].rect.width, blocks[i].rect.height);
}

r.draw(sp);
return r;
}

public function drawBlobs(s:BitmapData):BitmapData {
var sp:Sprite = new Sprite();
var g = sp.graphics;
var r:BitmapData=new BitmapData(s.width,s.height);
r.draw(s);
var pts:Array;
var b:Object;
var mid1:Point,mid2:Point;
var x:int,y:int,i:uint,j:uint;
for (i = 0; i < blocks.length; i++) {
pts = [];
b = blocks[i];
for (y = 0; y < b.rect.height; y += 5) {
for (x = 0; x < b.rect.width; x += 1) {
if (b.bmpd.getPixel(x,y)==0xff00ff) {
pts.push(new Point(x,y));
break;
}
}
}
for (y = b.rect.height -1; y >= 0; y -=5) {
for (x = b.rect.width - 1; x >=0; x -= 1) {
if (b.bmpd.getPixel(x,y)==0xff00ff) {
pts.push(new Point(x,y));
break;
}
}
}
g.beginFill(0xFF0000,0.2);
g.lineStyle(0,0xFF0000);
for (j = 0; j < pts.length; j ++) {
if (j==0) {
mid1 = Point.interpolate(pts[j], pts[(j + 1) % pts.length], 0.5);
g.moveTo(b.rect.x + mid1.x, b.rect.y + mid1.y);
}
mid2 = Point.interpolate(pts[(j + 2) % pts.length], pts[(j + 1) % pts.length], 0.5);
g.curveTo(b.rect.x + pts[(j + 1) % pts.length].x, b.rect.y + pts[(j + 1) % pts.length].y, b.rect.x + mid2.x, b.rect.y + mid2.y);
}
g.endFill();
}
r.draw(sp);
return r;
}

}
}
I made new automated painter with Flash.
What it does is basically finds sets of several points from a photograph and connects the points with marker-strokes. I wasn't really expecting many results from this simple algorithm, but I found out that this's kind of fun. Changing the parameters slightly can create various images from one that looks like a water color to another looks like colored pencil.
My favorite is the headless peacock that stands still like it's in a mirage. I attached some examples here. Others can also be seen on flickr.

peacock

untitled

double cherry blossoms

cloud