public static SimilarPhoto _Instance;
/ <summary>
/ 需要被对比的哈希值
/ </summary>
//public string ContrastValue;
/ <summary>
/ 服务器图片
/ </summary>
//public List<Texture2D> ServerImage = new List<Texture2D>();
public List<string> SimilarPhotoHash = new List<string>();
//public Button btn;
void Awake()
{
_Instance = this;
//DCT变换
//float[,] A = creatDCTMatrix(size);
//float[,] Aa = Transpose(A);
//float[,] DCT = Multiply(Multiply(A, ima1F), Aa);
//texS = (Texture2D)Resources.Load("aruco_sample1");
//for (int i = 0; i < ServerImage.Count; i++)
//{
// StartUpLoadImageData(ServerImage[i], 10);
//}
//for (int i = 0; i < NewHash.Count; i++)
//{
// CountSimilarity(ContrastValue, NewHash[i]);
//}
}
/// <summary>
/// 开始对比并计算哈希值
/// </summary>
/// <param name="tex"></param>
/// <param name="size"></param>
public void StartUpLoadImageData(Texture2D tex, int size)
{
image2F(Tex2Gray(ReduceSize(tex, size)));
}
/// <summary>
/// 压缩图片
/// </summary>
/// <param name="tex"></param>
/// <param name="size"></param>
/// <returns></returns>
Texture2D ReduceSize(Texture2D tex, int size)
{
if (tex == null || size <= 0)
{
Debug.Log("图片错误");
return null;
}
Texture2D newTexture = new Texture2D(size, size, TextureFormat.RGB24, false);
float ratioX = tex.width / size;
float ratioY = tex.height / size;
Color color;
for (int i = 0; i < newTexture.height; i++)
{
for (int j = 0; j < newTexture.width; j++)
{
color = tex.GetPixel(Mathf.RoundToInt(j * ratioX), Mathf.RoundToInt(i * ratioY));
newTexture.SetPixel(j, i, color);
}
}
return newTexture;
}
/// <summary>
/// 转灰度
/// </summary>
/// <param name="tex"></param>
/// <returns></returns>
Texture2D Tex2Gray(Texture2D tex)
{
Color color;
for (int i = 0; i < tex.height; i++)
{
for (int j = 0; j < tex.width; j++)
{
color = tex.GetPixel(j, i);
float gray = (color.r * 30 + color.b * 59 + color.b * 11) / 100;
tex.SetPixel(j, i, new Color(gray, gray, gray));
}
}
return tex;
}
/// <summary>
/// 图片转矩阵
/// </summary>
/// <param name="tex"></param>
/// <returns></returns>
float[,] image2F(Texture2D tex)
{
int size = tex.width;
float[,] f = new float[size, size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
f[i, j] = tex.GetPixel(i, j).r;
}
}
float[,] A = creatDCTMatrix(size);
float[,] Aa = Transpose(A);
float[,] DCT = Multiply(Multiply(A, f), Aa);
getHash(DCT, averageDCT(DCT));
return f;
}
/// <summary>
/// 计算DCT矩阵
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
float[,] creatDCTMatrix(int size)
{
//Debug.Log((float)Mathf.Cos(Mathf.PI));
float[,] ret = new float[size, size];
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
float angle = ((y + 0.5f) * Mathf.PI * x / size);
ret[x, y] = cfunc(x, size) * (float)Mathf.Cos(angle);
}
}
return ret;
}
float cfunc(int n, int size)
{
if (n == 0)
{
return Mathf.Sqrt(1f / size);
}
else
{
return Mathf.Sqrt(2f / size);
}
}
/// <summary>
/// 矩阵转置
/// </summary>
/// <param name="C"></param>
/// <returns></returns>
float[,] Transpose(float[,] C)
{
int size = C.GetLength(0);
float[,] ret = new float[size, size];
for (var x = 0; x < size; x++)
{
for (var y = 0; y < size; y++)
{
ret[y, x] = C[x, y];
}
}
return ret;
}
/// <summary>
/// 矩阵相乘
/// </summary>
/// <param name="C1"></param>
/// <param name="C2"></param>
/// <returns></returns>
float[,] Multiply(float[,] C1, float[,] C2)
{
int size = C1.GetLength(0);
float[,] ret = new float[size, size];
for (var y = 0; y < size; y++)
{
for (var x = 0; x < size; x++)
{
float sum1 = 0;
for (int k = 0; k < size; k++)
{
sum1 += C1[x, k] * C2[k, y];
}
ret[x, y] = sum1;
}
}
return ret;
}
/// <summary>
/// DCT均值
/// </summary>
/// <param name="dct"></param>
/// <returns></returns>
float averageDCT(float[,] dct)
{
int size = dct.GetLength(0);
float aver = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
aver += dct[i, j];
}
}
return aver / (size * size);
}
/// <summary>
/// 获取当前图片感知哈希值
/// </summary>
string getHash(float[,] dct, float aver)
{
string hash = string.Empty;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
hash += (dct[i, j] >= aver ? "1" : "0");
}
}
// Debug.Log("哈希值添加中");
SimilarPhotoHash.Add(hash);
return hash;
}
/// <summary>
/// 计算两图片哈希值的汉明距离
/// </summary>
/// <param name="hash1"></param>
/// <param name="hash2"></param>
/// <returns></returns>
public float computeDistance(string hash1, string hash2)
{
float dis = 0;
for (int i = 0; i < hash1.Length; i++)
{
if (hash1[i] == hash2[i])
{
dis++;
}
}
// Debug.Log(dis / hash1.Length);
return dis / hash1.Length;
}