二张JPG图片请问如何对比它的相似度,例如:90% ,100% ,,60%?
我给图片,请看一下,是二张监控图片,请问相似度如何计算?通过C#来实现。
c# 的话 用OpenCVSharp 会简单些
float Similar(Mat src, Mat src2)
{
Mat gray1 = new Mat(src.Size(), src.Type()),
gray2 = new Mat(src2.Size(), src2.Type());
Cv2.CvtColor(src, gray1, ColorConversionCodes.BGR2GRAY);
Cv2.CvtColor(src2, gray2, ColorConversionCodes.BGR2GRAY);
var size = new OpenCvSharp.Size(512, 512);
using (var scaledImg1 = gray1.Resize(size))
using (var scaledImg2 = gray2.Resize(size))
{
Cv2.Threshold(scaledImg1, scaledImg1, 128, 255, ThresholdTypes.BinaryInv);
Cv2.Threshold(scaledImg2, scaledImg2, 128, 255, ThresholdTypes.BinaryInv);
Mat res = new Mat(size, scaledImg1.Type());
Cv2.Absdiff(scaledImg1, scaledImg2, res);
var all = (float)scaledImg1.Sum();
var result = (float)res.Sum();
return (1 - result / all);
}
}
拿走不谢:
using System;
using System.IO;
using System.Drawing;
namespace SimilarPhoto
{
class SimilarPhoto
{
Image SourceImg;
public SimilarPhoto( string filePath)
{
SourceImg = Image.FromFile(filePath);
}
public SimilarPhoto(Stream stream)
{
SourceImg = Image.FromStream(stream);
}
public String GetHash()
{
Image image = ReduceSize();
Byte[] grayValues = ReduceColor(image);
Byte average = CalcAverage(grayValues);
String reslut = ComputeBits(grayValues, average);
return reslut;
}
// Step 1 : Reduce size to 8*8
private Image ReduceSize( int width = 8, int height = 8)
{
Image image = SourceImg.GetThumbnailImage(width, height, () => { return false ; }, IntPtr.Zero);
return image;
}
// Step 2 : Reduce Color
private Byte[] ReduceColor(Image image)
{
Bitmap bitMap = new Bitmap(image);
Byte[] grayValues = new Byte[image.Width * image.Height];
for ( int x = 0; x<image.Width; x++)
for ( int y = 0; y < image.Height; y++)
{
Color color = bitMap.GetPixel(x, y);
byte grayValue = ( byte )((color.R * 30 + color.G * 59 + color.B * 11) / 100);
grayValues[x * image.Width + y] = grayValue;
}
return grayValues;
}
// Step 3 : Average the colors
private Byte CalcAverage( byte [] values)
{
int sum = 0;
for ( int i = 0; i < values.Length; i++)
sum += ( int )values[i];
return Convert.ToByte(sum / values.Length);
}
// Step 4 : Compute the bits
private String ComputeBits( byte [] values, byte averageValue)
{
char [] result = new char [values.Length];
for ( int i = 0; i < values.Length; i++)
{
if (values[i] < averageValue)
result[i] = '0' ;
else
result[i] = '1' ;
}
return new String(result);
}
// Compare hash
public static Int32 CalcSimilarDegree( string a, string b)
{
if (a.Length != b.Length)
throw new ArgumentException();
int count = 0;
for ( int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
count++;
}
return count;
}
}
}
看一下https://blog.csdn.net/jiangxinyu/article/details/7968139
不用sift吗?
phash相似度
看看这个怎么样:
public Bitmap Resize(string imageFile, string newImageFile)
{undefined
img = Image.FromFile(imageFile);
Bitmap imgOutput = new Bitmap(img, 256, 256);
imgOutput.Save(newImageFile, System.Drawing.Imaging.ImageFormat.Jpeg);
imgOutput.Dispose();
return (Bitmap)Image.FromFile(newImageFile);
}
public int[] GetHisogram(Bitmap img)
{undefined
BitmapData data = img.LockBits(new System.Drawing.Rectangle( 0 , 0 , img.Width , img.Height ),ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
int[ ] histogram = new int[ 256 ];
unsafe
{undefined
byte* ptr = ( byte* )data.Scan0;
int remain = data.Stride - data.Width * 3;
for( int i = 0 ; i < histogram.Length ; i ++ )
histogram[ i ] = 0;
for( int i = 0 ; i < data.Height ; i ++ )
{undefined
for( int j = 0 ; j < data.Width ; j ++ )
{undefined
int mean = ptr[ 0 ] + ptr[ 1 ] + ptr[ 2 ];
mean /= 3;
histogram[ mean ] ++;
ptr += 3;
}
ptr += remain;
}
}
img.UnlockBits( data );
return histogram;
}
//计算相减后的绝对值
private float GetAbs(int firstNum, int secondNum)
{undefined
float abs = Math.Abs((float)firstNum - (float)secondNum);
float result = Math.Max(firstNum, secondNum);
if (result == 0)
result = 1;
return abs / result;
}
//最终计算结果
public float GetResult(int[] firstNum,int[] scondNum)
{undefined
if (firstNum.Length != scondNum.Length)
{undefined
return 0;
}
else
{undefined
float result = 0;
int j = firstNum.Length;
for (int i = 0; i < j; i++)
{undefined
result += 1 - GetAbs(firstNum[i], scondNum[i]);
Console.WriteLine(i + "----" + result);
}
return result/j;
}
}