使用 PIL 用附近的颜色填充空白图像空间(也称为修复)
我使用 PIL 创建图像:
我需要填充空白区域(显示为黑色)。我可以轻松地用静态颜色填充它,但我想做的是用附近的颜色填充像素。例如,边框之后的第一个像素可能是填充像素的高斯模糊。或者可能是 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()
以及生成的图像:
I create an image with PIL:
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:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
效果良好的方法是Navier-Stokes 图像恢复. 我知道OpenCV有它,不知道PIL。
您的示例:
我是用 Mathematica 完成的。
编辑
根据您的请求,代码为:
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:
I did it with Mathematica.
Edit
As per your reuquest, the code is:
The ColorNegate@ ... part creates the replacement mask.
The filling is done with just the
Inpaint[]
command.根据您部署此应用程序的方式,另一个选择可能是使用 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).
您还可以使用函数
CreateImage()
创建遮罩,例如:You can also create the mask with the function
CreateImage()
, for instance: