验证图像序列

时间:2010-10-21 00:56:28

标签: c# image-processing computer-vision

问题

问题形成

图像序列位置尺寸是预先固定且已知的(未缩放)。它将非常短,最多20帧并且处于闭环状态。我想验证(由按钮点击驱动的事件),我以前见过它。

假设我有一些图像序列,例如:

http://img514.imageshack.us/img514/5440/60372aeba8595eda.gif

如果看到,我想看到与之相关的ID,如果没有 - 它将被分析并添加为已经看到的图像序列的新实例。我有很长一段时间,但我承认,这可能是一个难题。我似乎很难将这些全部放在一起,有人可以协助(在C#中)吗?

限制和用途

尝试重新创建版权检测系统,就像Youtube实施的内容ID系统一样(Margaret Gould Stewart在TED( link ))。可以将图像序列视为(.gif)文件,但它不是,并且没有直接的方法来获取二进制文件。可以使用类似的方法,以避免“图像共享数据库”中的重复,但它不是我想要做的。

我的努力

高斯模糊

用于生成高斯模糊内核的Mathematica函数:

getKernel[L_] := Transpose[{L}].{L}/(Total[Total[Transpose[{L}].{L}]])
getVKernel[L_] := L/Total[L]

alt text alt text alt text
事实证明,使用2遍矢量核,然后矩阵核更有效。你的基于Pascal triangle不均匀的行:

{1d/4, 1d/2, 1d/4}
{1d/16, 1d/4, 3d/8, 1d/4, 1d/16}
{1d/64, 3d/32, 15d/64, 5d/16, 15d/64, 3d/32, 1d/64}

数据输入,散列,灰度和灯箱

源位的示例,可能有用:

  • 已知矩形周围的灯箱:FrameX
  • 使用MD5CryptoServiceProvider获取已知矩形atm内的内容的md5哈希值。
  • 使用ColorMatrix进行灰度图像

来源示例

来源示例(GUI; code):

获取定义的矩形内的当前内容。

        private Bitmap getContentBitmap() {
            Rectangle r = f.r;
            Bitmap hc = new Bitmap(r.Width, r.Height);
            using (Graphics gf = Graphics.FromImage(hc)) {
                gf.CopyFromScreen(r.Left, r.Top, 0, 0, //
                    new Size(r.Width, r.Height), CopyPixelOperation.SourceCopy);
            }
            return hc;
        }

获取位图的md5哈希。

        private byte[] getBitmapHash(Bitmap hc) {
            return md5.ComputeHash(c.ConvertTo(hc, typeof(byte[])) as byte[]);
        }

获取图像的灰度。

        public static Bitmap getGrayscale(Bitmap hc){
            Bitmap result = new Bitmap(hc.Width, hc.Height);
            ColorMatrix colorMatrix = new ColorMatrix(new float[][]{   
                new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0},
                new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0,0,0,1,0,0},
                new float[]{0,0,0,0,1,0}, new float[]{0,0,0,0,0,1}});

            using (Graphics g = Graphics.FromImage(result)) {
                ImageAttributes attributes = new ImageAttributes();
                attributes.SetColorMatrix(colorMatrix);
                g.DrawImage(hc, new Rectangle(0, 0, hc.Width, hc.Height),
                   0, 0, hc.Width, hc.Height, GraphicsUnit.Pixel, attributes);
            }
            return result;
        }

4 个答案:

答案 0 :(得分:3)

我认为你有一些问题:

  1. 并非所有图像序列[视频]都相同[但很多相似]
  2. 您的数据来自哪里?
  3. 您如何重复与观看相关的数据?
  4. 数据大小
  5. 问题#1:

    许多图像可能因压缩,水印,缺帧和添加剪辑而略有不同。我建议对视频进行采样。例如,您可能需要考虑对视频中图像的小部分进行子采样。此外,为了避免噪声图像和压缩算法的问题。您可能需要考虑对采样的帧进行灰度调整,并进行高斯模糊处理。 [Guassian因为它的“更自然”(简答)]一旦你有足够的子样本到你对视频的相似性很有信心,那么将它存储在数据库中。使用样本,您可以对它们进行哈希处理,或者将它们存储为稍后进行%相似性。

    问题#2

    您的数据源将影响您使用的工具包和库。 我建议保持这个简单[保留它与GIF并创建一个自定义查看器,不要'尝试在开发逻辑时编写浏览器插件]

    问题#3

    使用像Postgres这样的东西[如果有很多大型对象]或SQLLite,建议用于索引,存储和调用过去的元数据。

    问题#4

    数据的大小将对召回,抽样,查询数据库等有很大的决心。

    总体建议:在这个阶段,不要咬得太多。从小处开始然后成长。

    另请参阅计算机视觉算法,以获得有关对象表示/召回的更多帮助。

答案 1 :(得分:2)

问题本身肯定非常有趣和具有挑战性,但是@monksy说明了许多实际问题。

我的机会主义务实会退后一步,看看大局,看看是否有另一种解决问题的方法。例如,如果您正在构建某种“图像共享社区”并希望避免在数据库中出现重复,那么您可以对文件执行简单的md5(Web上的GIF动画通常始终相同,人们很少修改它们它们)。

另一个例子:如果你正在分析科学样本(比如meteo序列),那么在生成它们时可能更容易在每个文件中直接嵌入某种哈希值。

答案 2 :(得分:2)

这取决于你是否只想知道你再看过一部绝对完全相同的电影,或者你也想要识别非常相似但有点改变的电影(做得更轻,添加了水印,压缩)改变等。)

在第一种情况下,只需获取文件的任何类型的哈希并使用它(因为文件在二进制级别上是相同的。

在第二种情况下(我认为你想要的)你手上有一个有趣的图像处理问题。如果你想要的话,你可以发现自己处于图像处理科学的前沿。如果是这种情况,我建议您开始阅读SURFOpenCV,并继续阅读。

如果您想匹配非常相似但不完全相同的视频,并且不想采用超级科学路线,那么我建议采用以下过程:

  1. 你已经做过的高斯模糊。
  2. 将每张图片分成几个大小相同的矩形(你必须测试最佳数字,但我建议你从9开始。
  3. 对于每个帧中的每个矩形,计算全色直方图,然后找到该矩形中出现最多的颜色。这给你9 * 20 = 180个数字。这是这部电影的“指纹”。
  4. 在数据库中找到最相似的指纹,如果它已经足够相似,那么你就不知道了。
  5. 第4步有点模糊,因为我并没有真正进入这个领域。您当前正在使用MD5哈希作为一种指纹,但在这种情况下这是不合适的,因为良好的加密哈希函数输入的细微差别会在哈希中产生非常大的差异。这意味着两个非常相似的帧将具有完全不同的MD5哈希,因此从哈希中你永远不会知道它们是相似的。

    只要数据库查找的速度不是问题,我只需要sum of square differences作为指纹相似性的度量,并设置一个阈值来识别相同的电影。但是,这对于大型数据集来说并不是非常快,在这些情况下,您可能需要将指纹转换为能够更快地找到类似指纹的指纹。你可以做的一件事是从选择所有已知电影的整个视频的平均颜色非常相似,然后从那里选择每帧中具有非常相似的平均颜色的电影,并在那一点保留的电影做完整的矩形指纹匹配。但我确信有更快的选项来匹配180个数字。

答案 3 :(得分:1)

也许您可以找到一种方法来获取变量中每个帧的图像数据的二进制副本。哈希那个数据(md5?)并存储每个哈希值。然后你可以看看你以前是否见过那个哈希。如果你还没有,那就是一个新的框架。