思路:
1、原图,缩到,10*10大小;
2、去色(灰化),重置每个点的颜色,算法为:(color=(red*30+green*59+blue*11)/100;color=(color<<16)+(color<<8)+color;)
3、取图片所有像素颜色的非透明值的平均值,算法为:
(
w=h=10;
total=0;
for(i<w){
for(j<h){
total+=bmd.getPixel(i,j)&0x00ffffff;
}
}
return total/(w*h);
)
4、再对10*10的缩小图的每个点,的每个像素颜色值,相与:0x00ffffff;(ARGB,非A部份的所有值);
如果结果值大于第3点所求的平均值,则为1,否则为0;
这样就得出一组数组:我就暂时叫:Hash-SN
这样,同一张图,经过两次该算法的结果肯定是一样的;
即使两张不一样的图,但相似度很高的,这时,就要给Hash-SN设置容差个数的比较;
以上是自己简单总结:
原文链接:http://www.limbo-nova.com/blog/similar-image-searching-algorithm-as3/
原文主要代码:
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import mx.controls.Alert;
public class PHAImage
{
public function PHAImage()
{
}
public static function process(bmpData:BitmapData):String
{
//processing the image
trace("Start processing...\n");
//scaling and converting
var resizedData:BitmapData = reduceSize(bmpData,8,8);
//转换为灰度
var greyBmp:BitmapData = reduceColor(resizedData);
//计算灰度平均值
var avgGrey:uint = calcAvgGrey(greyBmp);
trace("Average GreyScale:0x"+avgGrey.toString(16)+"\n");
//比较灰度值与平均值,建立哈希指纹
var hashArr:Array = calcAvgHash(greyBmp, avgGrey);
trace("hashArr: ",hashArr.join(""));
return hashArr.join("");
}
private static function reduceSize(source:BitmapData,width:Number = 8, height:Number=8):BitmapData
{
var newData:BitmapData = new BitmapData(width,height);
var matrix:Matrix = new Matrix();
//缩小至 8x8
matrix.scale(newData.width/source.width, newData.height/source.height);
newData.draw(source,matrix);
return newData;
}
private static function reduceColor(source:BitmapData):BitmapData
{
var result:BitmapData = new BitmapData(source.width,source.height);
for(var i:int = 0; i < source.height; i++)
{
for(var j:uint = 0; j < source.width; j++)
{
var color:uint = source.getPixel(i, j);
var red:uint = (color & 0xFF0000) >> 16;
var green:uint = (color & 0x00FF00) >> 8;
var blue:uint = (color & 0x0000FF) >> 0;
//var bwColor:uint = (red + green + blue) / 3;
var bwColor:uint = (red * 30 + green * 59 + blue * 11) / 100;
// puts the average in each channel
bwColor = (bwColor << 16) + (bwColor << 8) + bwColor;
result.setPixel(i, j, bwColor);
}
}
return result;
}
private static function calcAvgGrey(bmpData:BitmapData):uint
{
var vecGrey:Vector.<uint> = bmpData.getVector(bmpData.rect);
var total:uint = 0;
var length:uint = vecGrey.length;
for(var i:int = 0; i< length;i++)
{
total += (vecGrey[i] & 0x00FFFFFF);
}
return uint(total/vecGrey.length);
}
//计算哈希
private static function calcAvgHash(bmpData:BitmapData, avgValue:uint):Array
{
var vecGrey:Vector.<uint> = bmpData.getVector(bmpData.rect);
var length:uint = vecGrey.length;
var hashArr:Array = [];
for(var i:int = 0; i< length;i++)
{
//ARGB 32位数据,只取RGB
var pxColor:uint = vecGrey[i] & 0x00FFFFFF;
//是否小于灰度均值,小于记0,否则记0
var value:uint = pxColor < avgValue ? 0:1;
hashArr.push(value);
}
return hashArr;
}
}
}