【问题标题】:How to extract the layers from an image (jpg,png,etc)如何从图像中提取图层(jpg,png等)
【发布时间】:2012-09-30 19:03:27
【问题描述】:

给定一个图像,例如 CakePHP 徽标,如何将这个图像转换回带有图层的 PSD。作为人类,我可以很容易地弄清楚如何将其转换回具有图层的 PSD。我可以看出背景是带有星形边缘的圆形。所以圆形星形部分在后面,蛋糕图像在上面,CakePHP 字样在这两个图像之上。

我可以使用 Photoshop/Gimp 工具将这些图像分成三张图像并填充中间的区域。然后我有三层。

作为人类,很容易计算出大多数徽标和图像的分层,并且许多图像具有多个层次,CakePHP 徽标只是一个示例。现实世界中的图像也有层次感,在草的背景上可能会有树的层次。我需要一种将图像转换回分层表示的通用方法,最好是一种软件解决方案。

在没有程序解决方案的情况下,是否有任何论文或研究解决了这个问题或与这个问题相关?我最感兴趣的是将人工构建的图像(例如徽标或网站标题)转换回分层表示。


我想指出这样做的一些好处,如果您可以自动将此图像分层表示,那么修改图像会更容易。例如,也许你想让蛋糕变小,如果计算机已经在红色背景上分层了蛋糕,你可以缩放蛋糕层。这允许在还没有图层信息的网站上对图像进行图层调整。

【问题讨论】:

  • 嗯...有趣的问题。我会注意到 Cake 中的“k”非常清楚地表示 z 顺序。 OTOH,如何提取用于“Cake”的文本层使用红色笔划(特别是从“C”中明显,但在“e”中几乎完全不明显)?而且我认为,判断“PHP”是在“Cake”之上还是之下是没有依据的。

标签: image image-processing artificial-intelligence computer-vision layer


【解决方案1】:

当您从图层表示转换为图像时,您会丢失信息。例如,您不知道蛋糕后面背景层的像素值。此外,您不确定图像的哪个部分属于哪个层。

但是,在某些情况下,至少可以部分恢复或估计此信息。例如,您可以尝试使用segmentation 算法将图像分成“层”。在您的示例中,基于颜色的简单分割可能会起作用。

至于在背景中恢复丢失的像素值,有所谓的inpainting 技术,它试图根据其周围环境来估计图像中的丢失区域。

最后,要恢复图像中文本的位置和内容,您可以依赖 Optical Character Recognition (OCR) 方法。

请记住,没有简单的算法可以解决您的问题,而且比看起来更复杂。但是,使用上述信息,您可以尝试至少部分自动化您的问题。

【讨论】:

    【解决方案2】:

    如前所述,这是一项不平凡的任务。最终,它可能是最 简单地表述为:给定一个由以下组成的图像(或场景,如果是真实照片) 像素N,如何分配给M层?

    对于细分,一切都与您可以承担的先验知识有关 关于像素和像素组的哪些属性给出“提示”(和 我建议使用这个词!)关于它们所属的层。

    即使是在图像中仅使用颜色的最简单情况也是如此。我能 生成这 5 个“层”(对于色调值 0、24、90、117 和 118):

    使用此代码(在 python/opencv 中)

    import cv 
    
    # get orginal image
    orig = cv.LoadImage('cakephp.png')
    
    # show original 
    cv.ShowImage("orig", orig)
    
    # convert to hsv and get just hue
    hsv = cv.CreateImage(cv.GetSize(orig), 8, 3) 
    hue = cv.CreateImage(cv.GetSize(orig), 8, 1) 
    sat = cv.CreateImage(cv.GetSize(orig), 8, 1) 
    val = cv.CreateImage(cv.GetSize(orig), 8, 1) 
    cv.CvtColor(orig, hsv, cv.CV_RGB2HSV)
    cv.Split(hsv,hue,sat,val,None)
    #cv.ShowImage("hue", hue)
    
    # loop to find how many different hues are present...
    query = cv.CreateImage(cv.GetSize(orig), 8, 1) 
    result = cv.CreateImage(cv.GetSize(orig), 8, 1) 
    for i in range(0,255):
      cv.Set(query,i)
      cv.Cmp(query,hue,result,cv.CV_CMP_EQ)
      # if a number of pixels are equal - show where they are 
      if (cv.CountNonZero(result)>1000): # <-what is signficant?
        cv.ShowImage(str(i),result)
        cv.SaveImage(str(i)+".png",result)
        cv.WaitKey(-1)
    

    但是,即使在这里,我们也必须根据 属于掩码的像素数(在某种程度上我们可能会错过一些 颜色)。我们可以开始聚集相似的颜色——但是在什么时候 集群的密度是否变得重要?如果它不仅仅是纯色, 但是有纹理,我们怎么能描述这个呢?或者,如何推断 一层是另一层的一部分,还是在它前面?或者,最终,一些 这些层似乎是我们人类所说的“字母”,因此可能应该是 所有相关...

    计算机视觉中的许多分割研究通常都试图采取 这个问题并在一个可以编码和应用它的框架内改进它 先验知识有效...

    【讨论】:

    • 嗨蒂姆,这是什么脚本?我的意思是,什么语言、什么工具、什么库?
    • 我猜它的 Python 使用的是 OpenCV。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 2013-01-24
    • 2022-08-21
    • 1970-01-01
    • 2017-03-27
    • 2018-01-04
    • 2020-06-24
    相关资源
    最近更新 更多