python - 使用 PIL 在 Python 中进行图像浮雕——添加深度、方位角等

标签 python image-processing python-imaging-library

我正在尝试使用 PIL 对图像进行浮雕处理.

PIL 提供了一种对图像进行浮雕的基本方法(使用 ImageFilter.EMBOSS)。

在像 GIMP 这样的图像编辑包中,您可以改变此浮雕图像中的方位角、深度和仰角等参数。

如何使用 PIL 做到这一点?至少我想调整浮雕图像的“深度”。

更新:我尝试了 Paul 的建议(修改 filterargs,例如 scale、offset 和矩阵),但我做不到不要改变“深度”效果。所以还在寻找答案。

这是使用 PIL(左)和 GIMP(右)的浮雕效果对比。原图在这里,http://www.linuxtopia.org/online_books/graphics_tools/gimp_advanced_guide/gimp_guide_node74.html .

alt text

最佳答案

如果您无法通过使用或组合操作(如旋转,然后应用 EMBOSS 滤镜,重新旋转)(或增强对比度然后压花)来实现您的目标,那么您可以求助于更改(或创建自己的) 过滤矩阵。

在 ImageFilter.py 中你会发现这个类:

##
# Embossing filter.

class EMBOSS(BuiltinFilter):
    name = "Emboss"
    filterargs = (3, 3), 1, 128, (
        -1,  0,  0,
        0,  1,  0,
        0,  0,  0
        )

将 -1 放置在矩阵的不同角落将改变方位角并将其设为 -2 可能具有您正在寻找的效果。

矩阵是逐像素应用的。矩阵中的每个元素对应当前像素和周围像素;表示当前像素的中心值。新的、转换后的当前像素将创建为所有 9 个像素的组合,由矩阵中的值加权。例如,一个全为 0 而中心为 1 的矩阵不会改变图像。

其他参数是scaleoffset。对于内置 EMBOSS,值为 1(缩放)和 128(偏移)。更改这些将改变结果的整体强度。

来自 ImageFilter.py:

# @keyparam scale Scale factor.  If given, the result for each
#    pixel is divided by this value.  The default is the sum
#    of the kernel weights.
# @keyparam offset Offset.  If given, this value is added to the
#    result, after it has been divided by the scale factor.

因为我不熟悉 GIMP 的“深度”参数的效果,所以我不能说哪个最有可能达到您想要的效果。

您还可以使矩阵具有不同的大小。将 (3,3) 替换为 (5,5),然后创建 25 元素矩阵。

要在不重新保存源代码的情况下对过滤器进行临时更改,只需执行以下操作:

ImageFilter.EMBOSS.filterargs=((3, 3), 1, 128, (-1, 0, 0, 0, 1, 0, 0, 0, 0))

编辑:(采用 NumPy 方法)

from PIL import Image
import numpy

# defining azimuth, elevation, and depth
ele = numpy.pi/2.2 # radians
azi = numpy.pi/4.  # radians
dep = 10.          # (0-100)

# get a B&W version of the image
img = Image.open('daisy.jpg').convert('L') 
# get an array
a = numpy.asarray(img).astype('float')
# find the gradient
grad = numpy.gradient(a)
# (it is two arrays: grad_x and grad_y)
grad_x, grad_y = grad
# getting the unit incident ray
gd = numpy.cos(ele) # length of projection of ray on ground plane
dx = gd*numpy.cos(azi)
dy = gd*numpy.sin(azi)
dz = numpy.sin(ele)
# adjusting the gradient by the "depth" factor
# (I think this is how GIMP defines it)
grad_x = grad_x*dep/100.
grad_y = grad_y*dep/100.
# finding the unit normal vectors for the image
leng = numpy.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/leng
uni_y = grad_y/leng
uni_z = 1./leng
# take the dot product
a2 = 255*(dx*uni_x + dy*uni_y + dz*uni_z)
# avoid overflow
a2 = a2.clip(0,255)
# you must convert back to uint8 /before/ converting to an image
img2 = Image.fromarray(a2.astype('uint8')) 
img2.save('daisy2.png')

希望对您有所帮助。我现在明白您为什么对 PIL 的结果感到失望了。 Wolfram Mathworld 是复习矢量代数的好资源。

之前

alt text

之后

alt text

关于python - 使用 PIL 在 Python 中进行图像浮雕——添加深度、方位角等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2034037/

相关文章:

java - 如何区分图像中的两条线

python - 使用 Python 和 pillow (PIL) 填充空心形状

python - 将 tensorflow 检查点保存到 .pb protobuf 文件

python - 总结 Python Pandas 中两列(双向)的组合计数

algorithm - 寻找图像失真算法

java - 隐写术出了问题

python - Image.open() 给出纯白色图像

python - 在Flask API上处理opencv图像(字节,编码为jpg)

python - 在不同大小的框架之间切换

python - 与 MySQL 通信时,我的 Python 脚本没有错误,仍然没有变化