以编程方式使图像的背景透明或白色

时间:2012-01-10 16:37:27

标签: java image image-processing image-manipulation

如果正在创建一个应用程序,其中一个人想要使图像的“背景”透明或白色,有没有办法做到这一点?

例如:

在图像http://upload.wikimedia.org/wikipedia/commons/b/b9/Bronze_Statuette_of_a_Veiled_and_Masked_Dancer_1.jpg中,我想以编程方式转换图像,以便只保留雕像,背景(即图像的其余部分)全部为白色或透明。

此外,用户可能会指出应该“保留”的图像部分,其余部分应全部为白色或透明。

如何做到这一点?此外,如果有一个合适的java库或一段代码,那将会有所帮助。

此致

2 个答案:

答案 0 :(得分:2)

您要求的是前景和背景的程序化细分。由于这是一个活跃的研究领域,您不太可能找到任何开箱即用的现成模式源代码(特别是在Java中)。

如果您有时间,请查看image segmentation并浏览Google学术搜索中的相关论文。您将会看到,在一般情况下,计算机解决这个问题并不容易。在特定情况下,您可以尝试利用某些条件。在您指定的图像中,背景非常模糊,因此图形的边缘非常突出。使用Canny operator进行边缘检测可以为您提供:

enter image description here

这不完美,但这是一个开始。使用边缘信息,您可以找到主要外部轮廓并提取舞者图。

答案 1 :(得分:2)

对于该特定图像,有几种方法可以解决部分问题。也许如果你结合多种方法提供用户交互选择,你可以在相当短的时间内开发出一个好的软件。我会用它!

你和Misha已经讨论了前两项:

  1. 使用Canny或其他方法进行边缘检测。我建议您应该使用“原始”边缘强度图像,而不是对边缘强度进行阈值处理以生成二值化图像。请注意,在这种情况下,图形处于清晰焦点,并且大部分背景都没有聚焦。虽然这不是一般解决方案,但对于这个特定图像,您可以过滤掉(a)属于线条的边缘(使用Hough或RANSAC),但(b)具有低于阈值陡度的渐变。
  2. 洪水填充。 Misha已经提供了链接。填充“静态”值的洪水不应太难实现(例如,相对于点击的像素填充值+/- N的所有相邻像素)。实现动态泛光填充可以解决由于光照和3D曲率引起的梯度问题。 。 。哎哟!
  3. 平均移位聚类。这可能甚至可以作为帮助将相同HSV值的像素聚集在一起的第一步。然而,只要注意图像,前景图形的色调和大部分背景的色调是相似的。 OpenCV实现了均值漂移。工作中有相关CAMSHIFT算法的视频:http://www.youtube.com/watch?v=iBOlbs8i7Og
  4. 边缘跟随强边缘。如果用户单击靠近边缘,则标识最近的强边,然后使用轮廓跟踪(或“轮廓跟踪”)算法。基本轮廓跟踪算法适用于二值图像;您可以调整算法以尝试遵循RGB空间中的强大边缘。整蛊!
  5. 由于您正在为用户编写软件,因此将一些时间用于软件可用性,而不仅仅是尝试解决一般图像处理问题。
  6. 检查背景曲线是否遮挡。确定项目是否是背景的一部分的另一种方法是确定它是否被前景对象遮挡(隐藏)。如果你发现两个线段是共线的并且具有平缓的渐变(即它们没有聚焦),那么它们可能是两个线段而不是一个,因为它们被前景对象遮挡。
  7. 如果你有可能使用相机而不是现有的图像,你可以通过在不同的焦距设置下拍摄多个连续的图像来模仿“光场”或全光相机(例如Lytro https://www.lytro.com/camera)。这可以帮助您根据渐变的变化识别不同深度的图形。如果雕像相对靠近相机,当相机对着无限远时,它将会失焦。
  8. 提高可用性

    1. 假设您可以将图像分割成相当不同的块,提示用户单击属于同一个感兴趣对象的块。每个块可以具有其自己的一组用于边缘强度,颜色接受范围等的调整参数。具有块特定参数可以帮助使软件可用,即使存在阴影,变化的光照等,这给分割带来问题。这样的东西可以通过组合选择在GIMP和Photoshop中完成,但它的可用性不如它。

    2. 对于已识别的块,实现“捕捉到边缘”功能,帮助用户将发现的边缘曲线移动到真实的边缘曲线上。如果用户抓取一个块状轮廓并将其拖向一个方向,则轮廓可以捕捉到该方向上的下一个强边缘。

    3. 提供批处理选项。如果用户具有在相同条件下拍摄的一系列照片,则用户选择的第一图像的块可以帮助引导软件设置连续图像的参数。这不是为了解决一般的分割问题,而是为某些图像组节省了一些时间和精力。

    4. 这是一个有趣的问题。祝你好运!