图像相似度比较
#!/usr/bin/env python################################################################################# AverageHash################
·
#!/usr/bin/env python
################################################################################
# AverageHash #
################################################################################
# A program to calculate a hash of an image based on visual characteristics. #
# Author: David J. Oftedal. #
# #
# Depends on Python Imaging Library: http://www.pythonware.com/products/pil/ #
# #
# Thanks to: #
# http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html #
# for the algorithm. #
################################################################################
from sys import argv
from sys import exit
from PIL import Image
from PIL import ImageStat
def AverageHash(theImage):
# Squeeze the image down to an 8x8 image.
theImage = theImage.resize((8,8), Image.ANTIALIAS)
# Convert it to 8-bit grayscale.
theImage = theImage.convert("L") # 8-bit grayscale
# Remove two bits to make it 6-bit grayscale.
theImage = theImage.point(lambda pixel: pixel >> 2)
# Calculate the average value.
averageValue = ImageStat.Stat(theImage).mean[0]
# Go through each pixel, from (0,0) to (0,1), (0,2), (0,3) etc.
# Return 1-bits when the tone is equal to or above the average,
# and 0-bits when it's below the average.
averageHash = 0
for row in xrange(8):
for col in xrange(8):
averageHash <<= 1
averageHash |= 1 * ( theImage.getpixel((col, row)) >= averageValue)
return averageHash
def loadImage(filename):
try:
theImage = Image.open(filename)
theImage.load()
return theImage
except:
print "\nCouldn't open the image " + filename + ".\n"
exit(1)
if __name__ == '__main__':
if len(argv) == 2 or len(argv) == 3:
image1 = loadImage(argv[1])
hash1 = AverageHash(image1)
print "\n" + hex(hash1).replace("0x","").replace("L","") + "\t" + argv[1]
if len(argv) == 3:
image2 = loadImage(argv[2])
hash2 = AverageHash(image2)
print hex(hash2).replace("0x","").replace("L","") + "\t" + argv[2] + "\n"
# XOR hash1 with hash2 and count the number of 1 bits to assess similarity.
print argv[1] + " and " + argv[2] + " are " + str(((64 - bin(hash1 ^ hash2).count("1"))*100.0)/64.0) + "% similar."
if len(argv) < 2 or len(argv) > 3:
print "\nTo get the hash of an image: python " + argv[0] + " <image name>"
print "To compare two images: python " + argv[0] + " <image 1> <image 2>\n"
exit(1)
print
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
public class Imghash
{
// Calculate a hash of an image based on visual characteristics.
// Described at http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
// The exact value of the resulting hash depends on the scaling algorithms used by the runtime.
public static ulong AverageHash(System.Drawing.Image theImage)
{
// Squeeze the image down to an 8x8 6-bit grayscale image.
// Chant the ancient incantations to create the correct data structures.
Bitmap squeezedImage = new Bitmap(8, 8, PixelFormat.Format32bppRgb);
Graphics drawingArea = Graphics.FromImage(squeezedImage);
drawingArea.CompositingQuality = CompositingQuality.HighQuality;
drawingArea.InterpolationMode = InterpolationMode.HighQualityBilinear;
drawingArea.SmoothingMode = SmoothingMode.HighQuality;
drawingArea.DrawImage(theImage, 0, 0, 8, 8);
byte[] grayScaleImage = new byte[64];
uint averageValue = 0;
ulong finalHash = 0;
// Reduce the colour to 6-bit grayscale and calculate the average value.
for(int y = 0; y < 8; y++)
{
for(int x = 0; x < 8; x++)
{
// Add together the red, green and blue
// components and reduce them to 6 bit grayscale.
uint pixelColour = (uint)squeezedImage.GetPixel(x,y).ToArgb();
uint grayTone = (pixelColour & 0x00FF0000) >> 16;
grayTone += (pixelColour & 0x0000FF00) >> 8;
grayTone += (pixelColour & 0x000000FF);
grayTone /= 12;
grayScaleImage[x + y*8] = (byte)grayTone;
averageValue += grayTone;
}
}
averageValue /= 64;
// Return 1-bits when the tone is equal to or above the average,
// and 0-bits when it's below the average.
for(int k = 0; k < 64; k++)
{
if(k % 8 == 0)
Console.WriteLine();
if(grayScaleImage[k] >= averageValue)
{
finalHash |= (1UL << (63-k));
Console.Write(" ");
}
else
Console.Write("#");
}
Console.WriteLine();
Console.WriteLine();
return finalHash;
}
public static int Main(string[] argv)
{
if(argv.Length == 1)
{
Bitmap theImage;
try
{
theImage = new Bitmap(argv[0]);
}
catch(Exception e)
{
Console.WriteLine("Couldn't open the image " + argv[0] + ".");
return 1;
}
Console.WriteLine(AverageHash(theImage).ToString("x16") + "\t" + argv[0]);
}
else if(argv.Length == 2)
{
Bitmap theImage;
Bitmap theOtherImage;
try
{
theImage = new Bitmap(argv[0]);
}
catch(Exception e)
{
Console.WriteLine("Couldn't open the image " + argv[0] + ".");
return 1;
}
try
{
theOtherImage = new Bitmap(argv[1]);
}
catch(Exception e)
{
Console.WriteLine("Couldn't open the image " + argv[1] + ".");
return 1;
}
ulong hash1 = AverageHash(theImage);
ulong hash2 = AverageHash(theOtherImage);
Console.WriteLine(hash1.ToString("x16") + "\t" + argv[0]);
Console.WriteLine(hash2.ToString("x16") + "\t" + argv[1]);
Console.WriteLine("Similarity: " + ((64 - BitCount(hash1 ^ hash2))*100.0)/64.0 + "%");
}
else
{
Console.WriteLine("To get the hash of an image: Imghash.exe <image name>");
Console.WriteLine("To compare two images: Imghash.exe <image 1> <image 2>");
return 1;
}
return 0;
}
// Count the number of 1-bits in a number.
// We use a precomputed table to hopefully speed it up.
// Made in Python as follows:
// a = list()
// a.append(0)
// while len(a) <= 128:
// a.extend([b+1 for b in a])
static byte[] bitCounts = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,
2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,
4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,
3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 };
static uint BitCount(ulong theNumber)
{
uint count=0;
for(;theNumber > 0;theNumber >>= 8)
{
count+= bitCounts[(theNumber & 0xFF)];
}
return count;
}
}
gmcs -r:System.Drawing -r:System.Windows.Forms *.cs
#!/usr/bin/env python
################################################################################
# DifferenceHash #
################################################################################
# A program to calculate a hash of an image based on visual characteristics. #
# Author: David J. Oftedal. #
# #
# Depends on Python Imaging Library: http://www.pythonware.com/products/pil/ #
# #
# Thanks to: #
# http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html #
# for the algorithm which formed the inspiration for this algorithm. #
################################################################################
from sys import argv
from sys import exit
from PIL import Image
from PIL import ImageStat
def DifferenceHash(theImage):
# Squeeze the image down to an 8x8 image.
theImage = theImage.resize((8,8), Image.ANTIALIAS)
# Convert it to 8-bit grayscale.
theImage = theImage.convert("L") # 8-bit grayscale
# Remove two bits to make it 6-bit grayscale.
theImage = theImage.point(lambda pixel: pixel >> 2)
# Go through the rows from left to right, then right to left.
# Return 1-bits when the pixel is equal to or brighter than the previous
# pixel, and 0-bits when it's below.
# Use the last pixel as the 0th pixel.
previousPixel = theImage.getpixel((0, 7))
differenceHash = 0
for row in xrange(0, 8, 2):
for col in xrange(8):
differenceHash <<= 1
pixel = theImage.getpixel((col, row))
differenceHash |= 1 * (pixel >= previousPixel)
previousPixel = pixel
row += 1
for col in xrange(7, -1, -1):
differenceHash <<= 1
pixel = theImage.getpixel((col, row))
differenceHash |= 1 * (pixel >= previousPixel)
previousPixel = pixel
return differenceHash
def loadImage(filename):
try:
theImage = Image.open(filename)
theImage.load()
return theImage
except:
print "\nCouldn't open the image " + filename + ".\n"
exit(1)
if __name__ == '__main__':
if len(argv) == 2 or len(argv) == 3:
image1 = loadImage(argv[1])
hash1 = DifferenceHash(image1)
print "\n" + hex(hash1).replace("0x","").replace("L","") + "\t" + argv[1]
if len(argv) == 3:
image2 = loadImage(argv[2])
hash2 = DifferenceHash(image2)
print hex(hash2).replace("0x","").replace("L","") + "\t" + argv[2] + "\n"
# XOR hash1 with hash2 and count the number of 1 bits to assess similarity.
print argv[1] + " and " + argv[2] + " are " + str(((64 - bin(hash1 ^ hash2).count("1"))*100.0)/64.0) + "% similar."
if len(argv) < 2 or len(argv) > 3:
print "\nTo get the hash of an image: python " + argv[0] + " <image name>"
print "To compare two images: python " + argv[0] + " <image 1> <image 2>\n"
exit(1)
print
http://folk.uio.no/davidjo/programming.php
更多推荐
已为社区贡献3条内容
所有评论(0)