繁体   English   中英

如何使用 Python PIL 裁剪给定比例坐标的图像?

[英]How to crop an image given proportional coordinates with Python PIL?

我有一张尺寸为 (1920x1080) 的图像,其比例坐标提供了对检测到的人物区域的描述。 我只想使用提供的比例坐标从图像中裁剪检测到的人。 我查阅了PIL crop 文档并尝试了以下操作:

在集成文档中提供:

x0, y0 人物检测框右下角对应的x, y坐标。 它们与图像左上角的距离成比例。

x1, y1 人物检测框左上角对应的x, y坐标。 它们与图像左上角的距离成比例。

提供的示例集成说明:

在此处输入图像描述

def img_crop(url, box):
    box = {
            'x0': 0.974, 
            'x1': 0.922, 
            'y0': 0.502, 
            'y1': 0.315
    }
    img = Image.open(requests.get(url, stream=True).raw)
    h, w = img.size
    print(img.size)
    return img.crop((box['x0']*h, box['y0']*w, box['x1']*h, box['y1']*w))

这会导致以下错误

ValueError: Coordinate 'right' is less than 'left'

但是您的绘图与您自己对 x0,y0,x1,y1 的描述相矛盾。 据说(顺便说一句, 在文字图片中;最好避免这种情况)x0,y0 是右下角,x1,y1 是左上角。

只需反转 x0、y0 和 x1、y1。

另外,请注意,PIL 中的坐标系(通常在大多数图像处理系统中都是如此。因为图像格式也是这样做的)从左上角开始。 就像英文文本一样:像素是从左到右,从上到下组织的。

编辑:(回答您的评论)

一种方法是真正地交换它们并将.crop行替换为

    return img.crop((box['x1']*h, box['y1']*w, box['x0']*h, box['y0']*w))

这将在您的代码中起作用。 尽管如此,还有一些其他更可取的更改。 首先,您将图像的宽度称为h ,将图像的高度称为w 当然,从 python 的角度来看这不是问题,但它无助于可读性(我猜你这样做是因为当图像是 np.array 时,例如 opencv 图像,要获得 w 和 h,你会h,w,_=img.shape 。但是 PIL .size首先返回w ,然后返回h 。然后,你在crop线中反转wh以保持一致。

其次,靠x0和y0是box最大的x和y,x1,y1是最小的,还是比较奇怪的。 最好在调用代码中进行反转。 您没有提供它,我没有尝试显示更正的原因:必须在未提供的代码中进行更正。 (你确实提供了一个盒子,来覆盖传递的内容。所以在那个盒子里你也可以进行交换)

    box = {
            'x1': 0.974, 
            'x0': 0.922, 
            'y1': 0.502, 
            'y0': 0.315
    }

但最安全的方法,特别是因为您似乎不确定所有角点在哪里,并且考虑到有时x0可能小于x1 ,而y0大于y1 ,计算哪个是最小值,哪个是最大值。

像这样:

from PIL import Image
import matplotlib.pyplot as plt

def img_crop(url, box):
    box = {
            'x0': 0.216,
            'x1': 0.419,
            'y0': 0.237,
            'y1': 0.697
    }
    img = Image.open(requests.get(url, stream=True).raw)
    w, h = img.size
    print(img.size)
    xmin=min(box['x0'], box['x1'])
    xmax=max(box['x0'], box['x1'])
    ymin=min(box['y0'], box['y1'])
    ymax=max(box['y0'], box['y1'])
    return img.crop((xmin*w, ymin*h, xmax*w, ymax*h))

在那里,没问题。 只需按x,y,x,y的顺序传递两个 x 和两个 y,而不必担心先发送哪个 x 和先发送哪个 y。

在你的照片上,它得到了box的版本在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM