如何检测图像是否像素化

bir*_*rdy 6 java algorithm opencv image-processing

在早些时候有一个像这样问的问题:在pythonquora中检测像素化图像

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

我的方法:

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

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

fra*_*xel 8

这是一个相当简单的方法,可以工作:

  1. 从x和y中的1个像素平移的副本中减去图像.
  2. 对列和行中的像素求和(我只显示下面的列).
  3. 计算出峰值位置的频率和标准偏差.
  4. 如果标准偏差低于某个阈值,则图像被像素化.

您在第1步之后的图片:

在此输入图像描述

显示清晰的网格图案.现在,如果我们按柱状汇总像素,我们得到:

在此输入图像描述 现在,如果我们能够找出峰值列间距的规律性,并将其用作阈值来确定图像是否像素化.

下面是一些快速而粗略的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
Run Code Online (Sandbox Code Playgroud)

输出:

mean gap: 14.6944444444 std: 3.23882218342
Run Code Online (Sandbox Code Playgroud)

低std =像素化图像

这个未被混合的图像: 在此输入图像描述

有这样的对应图:

在此输入图像描述 yeilding更高的标准:

mean gap: 16.1666666667 std: 26.8416136293
Run Code Online (Sandbox Code Playgroud)

请注意,"平均差距"是没有意义的,因为std要高得多.

希望这足以说明这种方法可以很好地工作.


Καr*_*hικ 6

一些方法:

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

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

网站提供了线路检测和边缘检测算法.

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

在此输入图像描述