如何检测图像是否像素化

时间:2013-01-19 21:17:48

标签: java algorithm image-processing opencv

有一个类似的问题早先问过:Detecting a pixelated image in python以及quora

我试图找出用户上传的图像是否可以被检测为“像素化”。通过像素化我的意思是图像like these:在我的情况下,我无法访问原始(非像素化)版本。

我的方法

不确定这种方法的效果如何,但是如果我可以获得图像中每个像素的RGB然后将其与其邻居进行比较以查看它们是否相似,那么我可以检测到图像是像素化的?我可以获得像素的RGB,但不知道如何将它们与邻居进行比较。

是否有可用于执行此类操作的算法?我可以采取其他一些方法吗?我不受任何特定语言的束缚。

3 个答案:

答案 0 :(得分:8)

这是一个可行的相当简单的方法:

  1. 从x和y中翻译为1像素的副本中减去图像。
  2. 对列和行中的像素求和(我只显示下面的列)。
  3. 计算出峰值位置的频率和标准偏差。
  4. 如果标准偏差低于某个阈值,则图像会被像素化。
  5. 第1步之后的图片:

    enter image description here

    显示清晰的网格图案。现在,如果我们以列为单位对像素求和,我们得到:

    enter image description here 现在,如果我们能够找出峰值列间距的规律性,并将其用作阈值来确定图像是否像素化。

    这是一些快速而粗略的python代码,用于概述一种方法:

    import numpy as np
    import Image, ImageChops
    
    im = Image.open('fireworks-pixelate-02.gif')    
    im2 = im.transform(im.size, Image.AFFINE, (1,0,1,0,1,1))
    im3 = ImageChops.subtract(im, im2)
    im3 = np.asarray(im3)
    im3 = np.sum(im3,axis=0)[:-1]
    mean = np.mean(im3)
    peak_spacing = np.diff([i for i,v in enumerate(im3) if v > mean*2])
    mean_spacing = np.mean(peak_spacing)
    std_spacing = np.std(peak_spacing)
    print 'mean gap:', mean_spacing, 'std', std_spacing
    

    输出:

    mean gap: 14.6944444444 std: 3.23882218342
    

    低std =像素化图像

    此未删除图片: enter image description here

    有相应的图表:

    enter image description here yeilding更高的标准:

    mean gap: 16.1666666667 std: 26.8416136293
    

    请注意,“平均差距”是没有意义的,因为标准要高得多。

    希望这足以说明这种方法可以很好地运作。

答案 1 :(得分:6)

一些方法:

1)实施精确或其他边缘检测并改变边缘阈值以查看结果是否为网格。可以通过将霍夫线检测器应用于得到的边缘图像来检测网格。见下文(2)。

2)(这实际上是在边缘检测之前对图像进行阈值处理;还建议使用中值滤波器或其他噪声消除滤波器来平滑图像)。从左到右扫描,每个像素的颜色变化为像素分配黑色或白色。继续使用黑/白直到颜色发生变化,并从黑色切换为白色或从白色切换为黑色。如果像素化,你将最终得到一个类似网格的图像。您可以在iamge上运行标准线检测(您可以对1执行此操作)并查看生成的线的斜率是垂直的还是平行的,以及线是否相当等距。互联网上有样本线检测算法(甚至是Java实现)。

website引用了线路检测和边缘检测算法。

编辑:在回答mmgp的问题时(挑战+1,我喜欢!),这就是我对问题中的示例图片所做的: 1)边缘检测 2)灰度 3)Hugh-transform(高阈值) 随附的是变换输出。通过评估具有水平/垂直斜率并计算它们之间距离的所有线,可以辨别网格图案。这并不意味着图像是像素化的(棋盘会显示为像素化)。可能存在误报。

enter image description here

答案 2 :(得分:2)

这会有问题,有许多方法可以像素化图像。即使使用单一方法,您也可以任意旋转。从理论上讲,这种旋转不应该影响Hough这样的方法,但实际上它的确是因为你不能在任意角度都有完美的光栅化线条。我的方法很简单,每次都不会起作用(大部分时间都可能失败),但你必须更好地定义你想做的事情。你打算告诉用户:“嘿,你的图像是像素化的,我不想要它”?你想做的事情不明确,范围也不清楚。

所以这就是方法。将图像分割为其颜色通道,您的示例是一个托盘GIF,但可以很容易地将其视为RGB图像。如果它是灰度,那么你最喜欢有一个频道,这很好。如果您的图像具有Alpha通道,请将其混合或忽略它。使用这些分离的颜色通道,在每个颜色通道中应用形态渐变,通过Otsu将每个颜色二进制化(因为它是自动的,相对好的,容易获得的),并通过添加它们将n个二进制通道组合成一个。形态梯度将对强边缘(包括噪声)产生高响应,并且二值化步骤将保持它们。现在,您删除太小的组件并进行细化以获得一个像素宽的边缘。以下是我们在完成以下步骤后使用示例图像获得的内容:

enter image description here enter image description here

f = Import["http://www.caughtinthefire.com/wp-content/uploads/2009/03/\
     fireworks-pixelate-02.gif"]
split = Binarize[ImageSubtract[Dilation[#, 1], Erosion[#, 1]]] & /@ 
  ColorSeparate[f, "RGB"]
thin = Thinning[SelectComponents[Fold[ImageAdd, split[[1]], split[[2 ;;]]], 
  "Count", # > 10 &]]

现在我们继续检测这个稀疏二进制图像中的线条。期望的是,当图像像素化时,它将形成许多矩形区域,但不能保证我们实际上可以形成这些矩形区域。假设我们可以将这些区域中的每一个视为一个连通组件。然后,如果我们执行简单的分量分析:如果其凸包的面积与其边界框的面积之间的比率大于某个值,则该区域是矩形区域。如果我们最终得到许多矩形区域,那么你说你的图像是像素化的(但实际上没有信心说这样的事情)。接下来,我们看到原始图像,其中检测到的线被覆盖,在右边,我们看到在考虑使用比率>提到的分析之后剩余的连通分量(非黑色的点)。 95%。在这种情况下,总共有542个连接组件,减少到483.这意味着近90%的组件是矩形的。你也可以考虑其余组件的面积,或者将这个分析与其他组件结合起来,但我不是在这里做的。

enter image description here enter image description here

lines = ImageLines[thin, 0.05, Method -> "RANSAC"];
Show[f, Graphics[{Thick, Blue, Line /@ lines}]] (* The left image above. *)
blank = Image[ConstantArray[255, Reverse@ImageDimensions[thin]]];
blankcc = ImagePad[Binarize[Image[Show[blank, 
  Graphics[{Thick, Black, Line /@ lines}]]]], 1, Black]
ccrect = SelectComponents[MorphologicalComponents[blankcc], {"BoundingBoxArea", 
  "ConvexArea"}, #2/#1 > 0.95 &];
Colorize[ccrect, ColorFunction -> "DarkRainbow"] (* The right image above. *)

这是你对“像素化”的指示。

以下是考虑其他图像的其他结果。这始终是按以下顺序排列的三个图像的序列:原始,上述结果如上所述,不改变任何内容,更改线检测阈值后的结果如上所述。

一切都被检测为矩形。但是,线检测的阈值0.05在此处过高,在将其降低到0.01后,我们可以更好地划分组件。

enter image description here enter image description here enter image description here

接下来我们会考虑一个超出我们预期的图像,因此我们最终得到的组件非常少。行检测没有阈值可以提供更多的矩形分量,因此第三个图像为空(或者全黑,因为没有任何分量)。

enter image description here enter image description here

最后,旋转正方形的像素化。生成以下图像的过程可能与示例图像中使用的过程不同,但我不知道,因为我不是作者。右图是将行阈值提高到0.08的结果。这里的问题是区域相对较大,我不会考虑检测像素化图像。

enter image description here enter image description here enter image description here