创建一个";聚光灯“;在图像中使用Python

创建一个";聚光灯“;在图像中使用Python,python,image-processing,Python,Image Processing,以下是我想做的: 我有一个形象 我想在图像中取一个圆形区域,并使其显示为正常 图像的其余部分应该显得更暗 这样,就好像圆形区域被“突出显示”一样 我非常感谢您对如何在Python中实现这一点的反馈 在Gimp中,我将手动创建一个颜色为灰色(小于中灰色)的新层。然后,我将在该层上创建一个圆形区域,并使其为中灰色。然后我会将混合模式更改为柔和灯光。从本质上讲,顶层中灰色的任何东西都会显示出来而不进行修改,而比中灰色暗的任何东西都会显示得更暗 (理想情况下,我也会模糊顶层,这样过渡就不会突然) 如何在

以下是我想做的:

我有一个形象

我想在图像中取一个圆形区域,并使其显示为正常

图像的其余部分应该显得更暗

这样,就好像圆形区域被“突出显示”一样

我非常感谢您对如何在Python中实现这一点的反馈

在Gimp中,我将手动创建一个颜色为灰色(小于中灰色)的新层。然后,我将在该层上创建一个圆形区域,并使其为中灰色。然后我会将混合模式更改为柔和灯光。从本质上讲,顶层中灰色的任何东西都会显示出来而不进行修改,而比中灰色暗的任何东西都会显示得更暗

(理想情况下,我也会模糊顶层,这样过渡就不会突然)

如何在Python中通过算法实现这一点?我考虑过使用枕头库,但它没有这些混合模式。我也考虑过使用Blit库,但我无法导入(不确定它是否已被维护)。我对scikit图像也持开放态度。我只需要有关库和一些相关函数的指针

如果没有合适的库,我愿意从Python代码中调用命令行工具(例如imagemagick)


谢谢

我终于用ImageMagick完成了,用Python计算各种坐标等等

此命令将创建所需的圆(半径400,以(600600)为中心):

convert-尺寸1024x102xc:none-笔划黑色-填充钢蓝色-笔划宽度1-绘制“平移600600圆0,0 400,0”绘制。png

然后,此命令将其转换为B/W,以获得基本的掩码:

convert draw.png-alpha extract mask.png

此命令将模糊遮罩(半径180,西格玛16):

convert-channel RGBA-blur 100x16 mask.png mask2.png

以上三个命令为我提供了所需的掩码

此命令将使整个图像变暗(不带遮罩):

convert image.jpg-级别0%、130%、0.7暗.jpg

此命令将把所有3个图像放在一起(原始图像、变暗图像和遮罩):


composite image.jpg dark.jpg mask2.png out.jpg

您也可以使用Python图像库来完成。这是一种有效的方法,但可能会得到优化,因为其中仍然有一个双for循环

from PIL import Image
import math

def spotlight(img: Image, center: (int, int), radius: int) -> Image:
    width, height = img.size
    overlay_color = (0, 0, 0, 128)
    img_overlay = Image.new(size=img.size, color=overlay_color, mode='RGBA')
    for x in range(width):
        for y in range(height):
            dx = x - center[0]
            dy = y - center[1]
            distance = math.sqrt(dx * dx + dy * dy)
            if distance < radius:
                img_overlay.putpixel((x, y), (0, 0, 0, 0))
    img.paste(img_overlay, None, mask=img_overlay)
    return img


if __name__ == '__main__':
    orig_file_name = 'amsterdam_1900x1500'
    img = Image.open('{}.jpg'.format(orig_file_name))
    spotlight_img = spotlight(img, (475, 900), 400)
    spotlight_img.save('spotlight_{}.jpg'.format(orig_file_name))
从PIL导入图像
输入数学
def聚光灯(图像,中心:(int,int),半径:int)->图像:
宽度、高度=img.size
叠加颜色=(0,0,0,128)
img\u overlay=Image.new(size=img.size,color=overlay\u color,mode='RGBA')
对于范围内的x(宽度):
对于范围内的y(高度):
dx=x-中心[0]
dy=y-中心[1]
距离=数学sqrt(dx*dx+dy*dy)
如果距离<半径:
img_叠加像素((x,y),(0,0,0,0))
img.paste(img\u覆盖,无,掩码=img\u覆盖)
返回img
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
原始文件名='amsterdam_1900x1500'
img=Image.open(“{}.jpg.”格式(原始文件名))
聚光灯\u img=聚光灯(img,(475900),400)
spotlight\u img.save('spotlight\u{}.jpg'.格式(原始文件名))
之前:

之后:

您需要使用alpha频道。这可以通过PIL来完成。我会尝试为您制作一些东西