Bicubic resampling by Pixel Bender

August 25th, 2009  |  Published in Uncategorized

There is bilinear resampling by Pixel Bender already, why not bicubic too?

With the very helpful Java implementation, I can get bicubic resampling running in Pixel Bender in hours.

Here is my result, along with the resampling results in PhotoShop as a comparison:

Source image (4x4), scaled by your browser)

Source image (size 4x4, scaled by your browser)

Source image enlarged in PS (nearest neighbor)

Source image enlarged by PS (nearest neighbor)

Bicubic resampling by Pixel Bender

Bicubic resampling by Pixel Bender

There is some difference with PhotoShop’s versions (below), hope it’s not my mistake…

Bicubic resampling by PhotoShop.

Bicubic resampling by PhotoShop.

Bicubic smoother in PhotoShop

Bicubic smoother by PhotoShop

Bicubic sharper in PhotoShop

Bicubic sharper by PhotoShop

My codes can be downloaded below:
Bicubic resampling sample program source (with PB source)


Update:
Notified by author of the Java version, the Java code was wrong and has been updated. Here below is my updated code:
Bicubic resampling sample program source (with PB source)

updated output of PB

Tags: , ,

Playing with chroma key and thresholding in Flash (with Pixel Bender)

August 18th, 2009  |  Published in Uncategorized

While traveling with my gf in Europe, I’m planning to develop a better technique to use color marker in FLARtoolkit (which I’ve tried before).

YouTube Preview Image

For the first step of doing so is to find a algorithm of matching colors. Using blend mode “difference” on the image is not flexible and may not fit all situations. I decided to calculate the difference by comparing hue, saturation and brightness of the colors and then threshold the image.

This is very similar to (if not exactly) doing chroma key. Maybe there is some awesome beautiful chroma key algorithm but I can’t find a fast and flexible enough to do so. If you know one, please tell me. :)

One problem I faced is choosing between color space models. RGB surely wouldn’t be the choice since it do not give hue value directly. There are HSV and HSL I found to be quite suitable. The two models share the same algorithm to calculate hue but have different ones for saturation and brightness. After reading the algorithms, my decision is… try both. :P

Another problem is how to preform thresholding. First method is after calculating the pixel difference, add the difference in hue, saturation and brightness altogether with weightings and do a one-time threshold to the gray-scale image. Second method is calculate the difference and give threshold limits to the three channels (H,S,V or H,S,L), only the pixels pass all the three thresholds will be white. First method should be more easily to incorporate with other filters developed for AR (like the very hot adaptive thresholding), but the second method can be more precise.  Finally I tried both too…

Here is the result. While I have set some default values to the filters, be sure to play around with the values when you change the target color. There wouldn’t be a set of values that fits all methods and situations. :)

I’ll try integrate it with FLARtoolkit and release the source when it is ready, be sure to check back soon. :)

Update:
Source and new demo is here!

Tags: , , ,

FLARtoolkit trick: use a colored marker

May 23rd, 2009  |  Published in Uncategorized

YouTube Preview Image

Reasons why should we use colored marker instead of standard black and white only marker

Using a black and white only marker is boring

There are more and more AR applications in the world, but seems everybody use only the black square marker. May be the public is not yet bored by the black square yet, but if can use other color for the square, we can integrate the marker into real-life objects more beautifully and more flexible.

Increase marker detection performance

The internal algorithm of AR marker detection has a characteristic that, the less pixels’ color is the same of the marker, faster the detection can be done. When we use black square marker, the detector will waste a lot of time to process non-marker pixels as you can imagine that it is common to have black objects in real-life (especially we the Chinese people have black hair). So if we target less common color, the detector will be able to ignore most of the non-marker area.

How to achieve this in FLARtoolkit

We will create a custom detector class since we need to work at lower level of the FLARtoolkit. If you have not look into the internal classes of FLARtoolkit (because the FLARmanager is so much easier to work with ;-) ), there are two detectors: FLARSingleMarkerDetector and FLARMultiMarkerDetector. As their names suggest, one is for single marker detection and the other one can detect multiple markers. For simplicity, I will go through only the single detection for a red marker (if you want me to cover the other ones too, leave comment).

First we just copy all the codes inside FLARSingleMarkerDetector to a new class, I named it FLARSingleRedMarkerDetector.

To detect markers, we use the detectMarkerLite method, which is:

public function detectMarkerLite(i_raster:IFLARRgbRaster, i_threshold:int):Boolean

IFLARRgbRaster wraps a BitmapData, we can get it by:

var srcImg:BitmapData = (i_raster as FLARRgbRaster_BitmapData).bitmapData;

Originally, the method uses a threshold filter to extract black areas and give the result to other classes to process. As you might think of, we can simply swap the filter code. Originally the black areas will be turned to white pixels and others will be turned black and be ignored. We now want to detect red markers, so just try to turn everything black except the red regions to white. You may use ColorTransform if you want, but I am now obsessed with PixelBender. My version of kernel is:

kernel extractRedARMarker
<   namespace : "net.onthewings.filters";
    vendor : "Andy Li";
    version : 1;
    description : "used for FLARtoolkit, pre-proccess for red marker.";
>
{
    input image4 src;
    output pixel4 dst;
 
    parameter float threshold<
        minValue: 0.0;
        maxValue: 1.0;
        defaultValue: 0.4;
        description:"decrease to increase likelihood of marker detection.";
    >;
 
    void
    evaluatePixel()
    {
        float4 p = sampleNearest(src,outCoord());
        float sum = p.r+p.g+p.b;
        float val = p.r - (p.g + p.b)*0.5;
 
        if (val+(1.0-(sum/3.0))*0.1 <= threshold) {
            val = 0.0;
        } else {
            val = 1.0;
        }
        dst = float4 (val,val,val,1);
    }
}

Note that I let the dark red pass the threshold easier since I find it is common the web cam image is too dark.

To use the finished detector class:

tempFLARRgbRaster_BitmapData.bitmapData.draw(videoDisplay);
if (detector.detectMarkerLite(tempFLARRgbRaster_BitmapData,170)){
	detector.getTransformMatrix(lastDetectionResult);
	//FLARPVGeomUtils is from FLARmanager
	overlay3dObj.transform = FLARPVGeomUtils.convertFLARMatrixToPVMatrix(lastDetectionResult);
	overlay3dObj.visible = true;
} else {
	overlay3dObj.visible = false;
}
render();

Now you get all the concepts. So let’s skip all the boring stuff and see it in action. Or get the finished codes.

Happy AR!


Update: Here I have a PB kernel that works with any color. Try it!

Tags: , , ,