Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何检测图像是否像素化_Java_Algorithm_Image Processing_Opencv - Fatal编程技术网

Java 如何检测图像是否像素化

Java 如何检测图像是否像素化,java,algorithm,image-processing,opencv,Java,Algorithm,Image Processing,Opencv,早些时候有人问过这样一个问题:还有 我试图找出用户上传的图像是否可以被检测为“像素化”。我所说的像素化是指图像:在我的情况下,我无法访问原始(非像素化)版本 我的方法: 不知道这种方法有多有效,但如果我能得到图像中每个像素的RGB,然后将其与相邻像素进行比较,看看它们是否相似,那么我就能检测到图像是像素化的?我可以得到像素的RGB,但不知道如何将它们与相邻像素进行比较 已经有这样的算法了吗?我还可以采取其他方法吗?我不受任何特定语言的约束 一些方法: 1) 执行canny或其他边缘检测,并改变边

早些时候有人问过这样一个问题:还有

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

我的方法

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

已经有这样的算法了吗?我还可以采取其他方法吗?我不受任何特定语言的约束

一些方法:

1) 执行canny或其他边缘检测,并改变边缘阈值以查看结果是否为网格。通过将Hough线检测器应用于生成的边缘图像,可以检测网格。见下文(2)

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

这对直线检测和边缘检测算法有参考价值

编辑:为了回答来自mmgp的问题(+1表示挑战,我喜欢!),以下是我对问题中的示例图像所做的操作: 1) 边缘检测 2) 灰度 3) 休变换(高阈值) 附加的是休变换输出。通过计算所有具有水平/垂直坡度的线并计算它们之间的距离,可以识别网格模式。这并不自动意味着图像是像素化的(棋盘会显示为像素化)。可能存在误报


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

  • 从x和y平移1个像素的副本中减去图像
  • 对列和行中的像素求和(我只在下面显示列)
  • 计算出峰值位置的频率和标准偏差
  • 如果标准偏差低于某个阈值,则图像将被像素化
  • 步骤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
    
    输出:

    mean gap: 14.6944444444 std: 3.23882218342
    
    低标准=像素化图像

    此未固定图像:

    有这样一个对应的图表:

    你的性病要高得多:

    mean gap: 16.1666666667 std: 26.8416136293
    
    注意这里,“平均差距”是没有意义的,因为标准差要高得多


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

    这将是一个问题,有很多方法可以对图像进行像素化。即使使用单一方法,也可以任意旋转。理论上,这种旋转不应该影响像Hough这样的方法,但在实践中它确实会影响,因为不能以任意角度完全光栅化线。我的方法过于简单,它不会每次都有效(大多数时候可能会失败),但你真的必须更好地定义你想要做什么。你打算告诉用户:“嘿,你的图像是像素化的,我不想要它”?你想做什么不清楚,范围也不清楚

    这就是方法。将图像分割为彩色通道,示例之一是托盘GIF,但它很容易被视为RGB图像。如果它是灰度,那么你最喜欢有一个通道,这很好。如果图像具有alpha通道,请将其混合或忽略。使用这种分离的颜色通道,在每个通道中应用形态学梯度,通过大津对每个通道进行二值化(因为它是自动的、相对较好的、容易获得的),并通过添加它们将n个二值通道合并为一个通道。形态学梯度将为强边缘(包括噪声)提供高响应,二值化步骤将保持它们。现在删除太小的组件并进行细化以获得一个像素宽的边缘。以下是我们通过以下步骤获得的示例图像:

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

    这是你的印度菜
    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 &]]
    
    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. *)