在Python中检测像素化图像

5

我正在尝试确定一张图片是否为正方形(像素化)。

我听说过可以使用Numpy或SciPy进行2D Fourier变换,但这有点复杂。

目标是确定由于压缩不良而导致的正方形区域的数量,就像这张图片(img a)一样:


2
这只是我想到的,所以它只是一条评论。你有原始的、未压缩的图像吗?如果是这样,你可以尝试对这两个图像进行颜色计数。如果其中一个明显低于另一个,那么你几乎肯定出现了像素化/海报效应。 - Peter Rowell
很遗憾,我无法访问原始图像。 - kollo
2个回答

2

我不确定这个方法是否有效,但你可以尝试获取像素周围的最近邻。在某个区域周围,RGB值的变化会呈现出一个可见的跳跃。

你可以使用类似以下方式找到图像中每个像素的最近邻:

def get_neighbors(x,y, img):
    ops = [-1, 0, +1]
    pixels = []
    for opy in ops:
        for opx in ops:
            try:
                pixels.append(img[x+opx][y+opy])
            except:
                pass
    return pixels

这将为您提供源图像区域内最近的像素。
要使用它,您可以执行以下操作:
def detect_pixellated(fp):
    img = misc.imread(fp)
    width, height = np.shape(img)[0:2]

    # Pixel change to detect edge
    threshold = 20

    for x in range(width):
        for y in range(height):
            neighbors = get_neighbors(x, y, img)

            # Neighbors come in this order:
            #  6   7   8
            #  3   4   5
            #  0   1   2

            center = neighbor[4]
            del neighbor[4]

            for neighbor in neighbors:
                diffs = map(operator.abs, map(operator.sub, neighbor, center))
                possibleEdge = all(diff > threshold for diff in diffs)

经过进一步思考,使用OpenCV进行边缘检测并获取轮廓大小会更加易于操作和稳定。


最后一段:“......使用OpenCV进行边缘检测并获取轮廓尺寸......”真的很有帮助!谢谢。 - Hamed
非常抱歉这么晚才提问,但我最近发现了这篇帖子,而且我也遇到了完全相同的问题。当你谈论轮廓大小时,你是指像在这里提到的使用轮廓面积吗? - jruivo

1
如果你扫描它的行,那么处理线性图形比2D图像图形更容易,这总是更简单一些。
解决方案:
在像素上扫描一条线,如果访问速度更快,则将该线放入数组中进行计算,然后在该行(行)上运行算法以确定块状:
1/遍历您行中的每个像素,并通过减去两个像素之间的值来将其与前一个像素进行比较。制作先前像素值的数组。如果在规则间隔处存在大量像素值跳跃,则为块状。如果值的大量跳跃与小值的跳跃相结合,则为块状……您可以假设如果有许多相等的像素差异,则为块状,特别是如果您在2和4个相邻像素间隔和多条线上重复分析两次。
您还可以制作像素差异图表,以便了解所选图片的渐变变化的其他信息。如果相邻像素和第5个相邻像素的像素差异比例相似,则还表示颜色不平滑。

有许多算法可以使用,包括在线性图上使用快速傅里叶变换,就像音频一样,您可以使用来自图片的线条进行处理,这比2D图像算法更简单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接