You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从OpenCV image_hash模块PHashImpl获取哈希并转为字符串表示?

嘿,刚好之前用Emgu CV做过pHash的相关开发,给你详细说说这两个问题的解决思路:

1. 从PHashImpl获取哈希值

Emgu CV里的PHashImpl的Compute方法接收的IOutputArray参数,其实可以直接用Mat来承接(因为Mat实现了IOutputArray接口)。具体步骤如下:

  • 首先实例化pHash算法对象:
    using Emgu.CV;
    using Emgu.CV.ImageHash;
    
    var pHashAlgorithm = new PHashImpl();
    
  • 准备好输入图像(如果你的图像是彩色的,pHash内部会自动转为灰度处理,但如果遇到异常,也可以手动转灰度:CvInvoke.CvtColor(colorImg, grayImg, ColorConversion.Bgr2Gray);)
  • 创建一个Mat来存储哈希结果,然后调用Compute方法:
    Mat hashMat = new Mat();
    pHashAlgorithm.Compute(grayImg, hashMat);
    
    这里的hashMat就是存储pHash结果的矩阵,它是一个8x8的单通道矩阵,每个元素的值是0或255(对应哈希的0和1)。
2. 将哈希转为字符串表示

有两种常见的字符串表示方式:二进制字符串或十六进制字符串,你可以根据需求选择:

方式一:转为二进制字符串

遍历hashMat的每个像素,将大于阈值(比如127)的像素视为1,否则视为0,拼接成字符串:

using System.Text;

StringBuilder binaryHashBuilder = new StringBuilder();
for (int y = 0; y < hashMat.Rows; y++)
{
    for (int x = 0; x < hashMat.Cols; x++)
    {
        // 获取当前像素的字节值
        byte pixelValue = hashMat.GetData(y, x)[0];
        binaryHashBuilder.Append(pixelValue > 127 ? "1" : "0");
    }
}
string binaryHash = binaryHashBuilder.ToString();

方式二:转为十六进制字符串

先把二进制哈希转为64位无符号整数,再转成十六进制字符串,这样更简洁:

ulong hashValue = 0;
for (int y = 0; y < hashMat.Rows; y++)
{
    for (int x = 0; x < hashMat.Cols; x++)
    {
        byte pixelValue = hashMat.GetData(y, x)[0];
        if (pixelValue > 127)
        {
            // 计算当前位的偏移量,将对应位设为1
            hashValue |= 1UL << (y * 8 + x);
        }
    }
}
// 转为16位大写十六进制字符串,小写用"x16"
string hexHash = hashValue.ToString("X16");

注意事项

  • 确保你引用了正确的Emgu CV NuGet包,比如Emgu.CV和Emgu.CV.ImageHash,版本要匹配
  • 如果hashMat的通道或尺寸不对,可以检查输入图像是否正确,或者手动转为灰度图后再计算

内容的提问来源于stack exchange,提问作者Diego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:14:57