使用 PIL 用附近的颜色填充空白图像空间(也称为修复)

发布于 2024-11-30 06:11:15 字数 1615 浏览 1 评论 0原文

我使用 PIL 创建图像:

example image

我需要填充空白区域(显示为黑色)。我可以轻松地用静态颜色填充它,但我想做的是用附近的颜色填充像素。例如,边框之后的第一个像素可能是填充像素的高斯模糊。或者可能是 The Lumigraph、Gortler 等中描述的推拉型算法.

我需要一些不太慢的东西,因为我必须在许多图像上运行它。我可以访问其他库,例如 numpy,并且您可以假设我知道外部区域或内部区域的边界或掩码。关于如何解决这个问题有什么建议吗?

更新:

根据belisarius的建议,opencv的修复< /a> 方法非常适合此目的。这是一些使用 opencv 来实现我想要的效果的 python 代码:

import Image, ImageDraw, cv

im = Image.open("u7XVL.png")
pix = im.load()

#create a mask of the background colors
# this is slow, but easy for example purposes
mask = Image.new('L', im.size)
maskdraw = ImageDraw.Draw(mask)
for x in range(im.size[0]):
    for y in range(im.size[1]):
        if pix[(x,y)] == (0,0,0):
            maskdraw.point((x,y), 255)

#convert image and mask to opencv format
cv_im = cv.CreateImageHeader(im.size, cv.IPL_DEPTH_8U, 3)
cv.SetData(cv_im, im.tostring())
cv_mask = cv.CreateImageHeader(mask.size, cv.IPL_DEPTH_8U, 1)
cv.SetData(cv_mask, mask.tostring())

#do the inpainting
cv_painted_im = cv.CloneImage(cv_im)
cv.Inpaint(cv_im, cv_mask, cv_painted_im, 3, cv.CV_INPAINT_NS)

#convert back to PIL
painted_im = Image.fromstring("RGB", cv.GetSize(cv_painted_im), cv_painted_im.tostring())
painted_im.show()

以及生成的图像:

painted image

I create an image with PIL:

example image

I need to fill in the empty space (depicted as black). I could easily fill it with a static color, but what I'd like to do is fill the pixels in with nearby colors. For example, the first pixel after the border might be a Gaussian blur of the filled-in pixels. Or perhaps a push-pull type algorithm described in The Lumigraph, Gortler, et al..

I need something that is not too slow because I have to run this on many images. I have access to other libraries, like numpy, and you can assume that I know the borders or a mask of the outside region or inside region. Any suggestions on how to approach this?

UPDATE:

As suggested by belisarius, opencv's inpaint method is perfect for this. Here's some python code that uses opencv to achieve what I wanted:

import Image, ImageDraw, cv

im = Image.open("u7XVL.png")
pix = im.load()

#create a mask of the background colors
# this is slow, but easy for example purposes
mask = Image.new('L', im.size)
maskdraw = ImageDraw.Draw(mask)
for x in range(im.size[0]):
    for y in range(im.size[1]):
        if pix[(x,y)] == (0,0,0):
            maskdraw.point((x,y), 255)

#convert image and mask to opencv format
cv_im = cv.CreateImageHeader(im.size, cv.IPL_DEPTH_8U, 3)
cv.SetData(cv_im, im.tostring())
cv_mask = cv.CreateImageHeader(mask.size, cv.IPL_DEPTH_8U, 1)
cv.SetData(cv_mask, mask.tostring())

#do the inpainting
cv_painted_im = cv.CloneImage(cv_im)
cv.Inpaint(cv_im, cv_mask, cv_painted_im, 3, cv.CV_INPAINT_NS)

#convert back to PIL
painted_im = Image.fromstring("RGB", cv.GetSize(cv_painted_im), cv_painted_im.tostring())
painted_im.show()

And the resulting image:

painted image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦在夏天 2024-12-07 06:11:15

效果良好的方法是Navier-Stokes 图像恢复. 我知道OpenCV有它,不知道PIL。

您的示例:

在此处输入图像描述 在此处输入图像描述

我是用 Mathematica 完成的。

编辑

根据您的请求,代码为:

i = Import["https://i.sstatic.net/uEPqc.png"];
Inpaint[i, ColorNegate@Binarize@i, Method -> "NavierStokes"]

ColorNegate@ ... 部分创建替换蒙版。
只需使用 Inpaint[] 命令即可完成填充。

A method with nice results is the Navier-Stokes Image Restoration. I know OpenCV has it, don't know about PIL.

Your example:

enter image description here enter image description here

I did it with Mathematica.

Edit

As per your reuquest, the code is:

i = Import["https://i.sstatic.net/uEPqc.png"];
Inpaint[i, ColorNegate@Binarize@i, Method -> "NavierStokes"]

The ColorNegate@ ... part creates the replacement mask.
The filling is done with just the Inpaint[] command.

迷迭香的记忆 2024-12-07 06:11:15

根据您部署此应用程序的方式,另一个选择可能是使用 Gimp 的 python 接口< /a> 进行图像处理。

我链接到的文档页面更倾向于在 python 中编写 GIMP 插件,而不是与 python 应用程序中的后台 gimp 实例交互,但我很确定这也是可能的(自从我使用 gimp 以来已经有一段时间了/ python接口,我有点模糊)。

Depending on how you're deploying this application, another option might be to use the Gimp's python interface to do the image manipulation.

The doc page I linked to is oriented more towards writing GIMP plugins in python, rather than interacting with a background gimp instance from a python app, but I'm pretty sure that's also possible (it's been a while since I played with the gimp/python interface, I'm a little hazy).

雅心素梦 2024-12-07 06:11:15

您还可以使用函数 CreateImage() 创建遮罩,例如:

inpaint_mask = cv.CreateImage(cv.GetSize(im), 8, 1)

You can also create the mask with the function CreateImage(), for instance:

inpaint_mask = cv.CreateImage(cv.GetSize(im), 8, 1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文