在PIL或Imagemagick中为图像应用彩色覆盖层
我对图像处理完全是个新手,感觉这应该很简单,但我就是不太懂相关的术语。
简单来说,我有一张黑白图片,我想在这张图片上加一个彩色的覆盖层,让它看起来有蓝色、绿色、红色和黄色的效果,就像下面的图片那样(不过我不能展示这些图片,因为我的信誉不够 - 真让人烦)。可以想象一下,我有一张实体图片,然后在上面放一个绿色/红色/蓝色/黄色的覆盖层。
理想情况下,我想用Python的PIL库来实现这个效果,但如果用ImageMagik也没问题。不过无论用哪种方法,我都需要能编写脚本来处理,因为我有大约100张图片需要进行这个操作。
3 个回答
6
请查看我的分享 https://gist.github.com/Puriney/8f89b43d96ddcaf0f560150d2ff8297e
下面是通过 opencv
实现的核心功能描述。
def mask_color_img(img, mask, color=[0, 255, 255], alpha=0.3):
'''
img: cv2 image
mask: bool or np.where
color: BGR triplet [_, _, _]. Default: [0, 255, 255] is yellow.
alpha: float [0, 1].
Ref: http://www.pyimagesearch.com/2016/03/07/transparent-overlays-with-opencv/
'''
out = img.copy()
img_layer = img.copy()
img_layer[mask] = color
out = cv2.addWeighted(img_layer, alpha, out, 1 - alpha, 0, out)
return(out)
可以在RGB图像或灰度图像上添加彩色和透明的覆盖层,效果如下:


20
我最终找到了解决办法,使用了PIL这个库。简单来说,就是创建了一张新的图片,填充了一种颜色,然后把原来的图片和这张新图片合成在一起,使用一个定义透明度的遮罩。下面的代码是为了处理一个叫做data的文件夹里的每张图片,并把结果输出到一个叫做output的文件夹里:
from PIL import Image
import os
dataFiles = os.listdir('data/')
for filename in dataFiles:
#strip off the file extension
name = os.path.splitext(filename)[0]
bw = Image.open('data/%s' %(filename,))
#create the coloured overlays
red = Image.new('RGB',bw.size,(255,0,0))
green = Image.new('RGB',bw.size,(0,255,0))
blue = Image.new('RGB',bw.size,(0,0,255))
yellow = Image.new('RGB',bw.size,(255,255,0))
#create a mask using RGBA to define an alpha channel to make the overlay transparent
mask = Image.new('RGBA',bw.size,(0,0,0,123))
Image.composite(bw,red,mask).convert('RGB').save('output/%sr.bmp' % (name,))
Image.composite(bw,green,mask).convert('RGB').save('output/%sg.bmp' % (name,))
Image.composite(bw,blue,mask).convert('RGB').save('output/%sb.bmp' % (name,))
Image.composite(bw,yellow,mask).convert('RGB').save('output/%sy.bmp' % (name,))
很遗憾,由于没有足够的权限,无法发布输出的图片。
30
更新:正如Matt在评论中提到的,这个功能现在可以在 skimage.color.label2rgb
中使用。
在最新的开发版本中,我们还新增了一个 saturation
参数,这样你就可以给彩色图像添加覆盖效果了。
下面是一个代码示例,展示了如何使用 scikit-image 在灰度图像上添加颜色覆盖。这个方法的思路是将两幅图像都转换到HSV颜色空间,然后用彩色遮罩的色调和饱和度值替换灰度图像的相应值。
from skimage import data, color, io, img_as_float
import numpy as np
import matplotlib.pyplot as plt
alpha = 0.6
img = img_as_float(data.camera())
rows, cols = img.shape
# Construct a colour image to superimpose
color_mask = np.zeros((rows, cols, 3))
color_mask[30:140, 30:140] = [1, 0, 0] # Red block
color_mask[170:270, 40:120] = [0, 1, 0] # Green block
color_mask[200:350, 200:350] = [0, 0, 1] # Blue block
# Construct RGB version of grey-level image
img_color = np.dstack((img, img, img))
# Convert the input image and color mask to Hue Saturation Value (HSV)
# colorspace
img_hsv = color.rgb2hsv(img_color)
color_mask_hsv = color.rgb2hsv(color_mask)
# Replace the hue and saturation of the original image
# with that of the color mask
img_hsv[..., 0] = color_mask_hsv[..., 0]
img_hsv[..., 1] = color_mask_hsv[..., 1] * alpha
img_masked = color.hsv2rgb(img_hsv)
# Display the output
f, (ax0, ax1, ax2) = plt.subplots(1, 3,
subplot_kw={'xticks': [], 'yticks': []})
ax0.imshow(img, cmap=plt.cm.gray)
ax1.imshow(color_mask)
ax2.imshow(img_masked)
plt.show()
这是输出结果: