How Jev Makes Decisions About Images, With 4 Python Examples
TL;DR · AI 摘要
JEV Image Processing in Python With 4 Practical Examples AI applications How Jev Makes Decisions About Images, With 4 Py...
核心要点
- 主题聚焦:How Jev Makes Decisions About Images, With 4 Pyt
- 来源:Towards Data Science,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
使用Python和4个实际示例进行JEV图像处理
AI应用
JEV如何通过4个Python示例对图像做出决策
用于分类织物与参考照片、评估产品清晰度、裁剪运输标签以及检测细微汽车损伤的实用代码。
Thomas Reid
2026年11月13日
11分钟阅读
在Google上推荐我们
分享
作者提供的图片
同一辆汽车车门并排的图像。左侧图像完好无损,右侧图像显示有细微划痕
我最近为TDS(文末有链接)撰写了一篇文章,介绍OpenAI新推出的Decision API。在摘要中,我将它的能力与JEV进行了比较,并指出尽管JEV比OpenAI更快,但OpenAI的优势在于能够处理图像。
我还表示,我认为这不是一个足够显著的优势,因为我认为JEV很快就会发布一个能够处理图像的系统。事实证明我的判断是正确的。在过去的几周里,JEV已经启用了图像处理功能,并引入了一个名为Box的新原语,根据Typesafe AI的网站描述:
…这是System One的一种问题类型,用于在图像中找到某物的位置。答案是围绕该物体的框的四个边,以图像宽度和高度的分数表示。
因此,基本上,当你需要知道图像中某物的位置时,应该使用Box。
#### 什么是JEV?
我不会在这里重复JEV的完整理论或理念,因为我在之前的文章中已经详细讨论过。简而言之,JEV是一种新型的AI系统,专门用于对文本做出选择、是/否等类型的决策——现在也可以处理图像。
你定义需要做出的决策原语并提供待评估的内容。这可能意味着判断客户消息是否是取消请求、文档是否包含个人信息,或者哪一类损坏最能描述照片中的包裹。然后,结果可以指导代码中的下一步操作,例如路由请求、标记文档以供审查或发送损坏包裹的索赔以供检查。
在本文中,我将向你展示JEV新图像处理功能的四个实际应用场景。
先决条件与限制
在使用JEV之前,你需要一个API密钥。你可以在https://console.typesafe.ai/keys 获取密钥。
使用图像时,JEV存在以下限制:
- 图像必须为JPEG或PNG格式
- 图像宽度或高度的最小尺寸为280像素
- 图像宽度或高度的最大尺寸为1568像素
- 单个图像的最大文件大小为16 MiB
- 请求体的最大大小为32 MiB,包括JSON、base64文本和多部分帧。
我正在使用Windows上的Jupyter Notebook运行所有示例代码。打开你的Notebook后,在单元格中输入并运行以下代码:
python
%pip install -U "typesafe-sdk[pil]"如果你使用的是常规Python脚本,请先在环境中运行上述pip命令。
此外,运行几个辅助函数。其中一个会提示你输入API密钥,其他则确保你的图像方向正确且尺寸适合输入JEV。
from getpass import getpass
from PIL import Image as PILImage, ImageOps
from typesafe_sdk import (
TypeSafeClient,
Image as JevImage,
Choice,
Noul,
Score,
Box,
)
client = TypeSafeClient(
api_key=getpass("TypeSafe API key: "),
model="jev-1.14.0",
headers={"TypeSafe-Danger-Zone-Images": "true"},
)
def load_photo(path):
"""Rotate upright and fit within a square without stretching."""
with PILImage.open(path) as original:
upright = ImageOps.exif_transpose(original).convert("RGB")
return ImageOps.pad(
upright,
(1024, 1024),
color="white",
)
def image_asset(path):
return JevImage.from_pil(load_photo(path), format="jpeg")用例 1 — 使用参考照片对织物图案进行分类
假设一家在线服装零售商希望对上传的织物照片进行分类。与其用文字完整描述每种图案,不如提供示例图片作为分类标准。在此示例中,我们将有 3 张示例图案图片,以及一张需要分类的图片,具体如下。
由 AI 生成的图片
我们试图分类的织物图片是左上角的条纹图案图片,名为 to_classify.png。
以下是分类所需的代码。实现起来相对简单。它要求 JEV 通过与参考照片进行比较,忽略颜色、光照和拍摄角度的差异,将织物图片分类为条纹、格子、花卉或其他。它会输出分类结果、置信度和选项概率,如果结果为“其他”或置信度低于 80%,则建议将其标记到目录标签或标记为需要审核。
response = client.system_one(
state={
"sample": image_asset(r"d:\images\jev-test\to_classify.png"),
},
questions={
"pattern": Choice(
instructions=(
"哪张参考图案最符合 `sample` 中的织物?比较图案结构,忽略 "
"颜色、光照和拍摄角度的差异。"
),
criteria={
"striped": {
"description": "重复的平行条纹。",
"reference": image_asset(r"d:\images\jev-test\stripes.png"),
},
"checked": {
"description": "重复的格子图案。",
"reference": image_asset(r"d:\images\jev-test\check.png"),
},
"floral": {
"description": "重复的花卉或植物图案。",
"reference": image_asset(r"d:\images\jev-test\floral.png"),
},
"other": (
"纯色织物、其他图案、无可见织物,"
"或细节不足无法识别图案。"
),
},
),
},
)
answer = response.choices["pattern"]
print("Pattern:", answer.choice)
print("Confidence:", answer.confidence)
print("Option probabilities:", answer.probabilities)
if answer.choice == "other" or answer.confidence < 0.80:
print("Action: send to the catalogue review queue")
else:
print(f"Action: suggest the catalogue tag '{answer.choice}'")输出结果是什么?
text
Pattern: striped
Confidence: 1.0
Option probabilities: {'striped': 1.0, 'checked': 0.0, 'floral': 0.0, 'other': 0.0}
Action: suggest the catalogue tag 'striped'为了验证这不是偶然,我创建了一张波点织物图片,并将其替换到现有 to_classify.png 图片的位置,输入到代码中。
这次运行的结果如下。
plaintext
Pattern: other
Confidence: 1.0
Option probabilities: {'striped': 0.0, 'checked': 0.0, 'floral': 0.0, 'other': 1.0}
Action: send to the catalogue review queue用例 2 — 评估产品照片的清晰度
在接收产品照片之前,需要评估主体是否足够清晰。这个示例评估的是一个具体维度——对焦效果,而不是将照明、构图和清晰度综合成一个模糊的质量评分。
我将使用同一物品(茶壶)的两张图片进行演示。左边的图片是清晰的(product_photo_1.png),右边的图片则略微模糊(product_photo_2.png)。以下是输入图片。
处理这两张图片时,可以使用如下代码。它通过一次请求将两张照片发送给JEV,要求其分别评估每张图片是否能明确识别出主体产品,并在0到3分之间对清晰度进行评分,同时忽略有意的背景模糊。代码会输出结果,并通过可见性、置信度和清晰度阈值推荐更清晰的照片、人工审核、重新拍摄或通过检查。
images = {
"photo_1": r"d:\images\jev-test\product_photo_1.png",
"photo_2": r"d:\images\jev-test\product_photo_2.png",
}
criteria = [
"严重模糊:产品边缘难以区分。",
"明显模糊:边缘可见但细节丢失。",
"基本清晰:边缘清晰但存在轻微模糊的细部。",
"清晰:边缘和可见细部都清晰可辨。",
]
questions = {}
for name in images:
questions[f"{name}_visible"] = Noul(
instructions=(
f"在 `{name}` 中是否能明确识别出单一主体产品? "
"仅评估当前图片。"
),
)
questions[f"{name}_sharpness"] = Score(
instructions=(
f"评估 `{name}` 中主体产品的对焦清晰度。 "
"仅评估当前图片。忽略有意的背景模糊。 "
"判断可见的产品边缘和表面细节。"
),
criteria=criteria,
)
response = client.system_one(
state={
name: image_asset(path)
for name, path in images.items()
},
questions=questions,
)
for name, path in images.items():
visible = response.nouls[f"{name}_visible"].noul
sharpness = response.scores[f"{name}_sharpness"]
print(f"\nImage: {path}")
print(f"产品可见概率: {visible:.3f}")
print(f"清晰度: {sharpness.score:.2f} / 3")
print(f"置信度: {sharpness.confidence:.3f}")
print("等级概率:", sharpness.probabilities)
if visible < 0.85:
print("操作: 要求提供一张主体明确的照片")
elif sharpness.confidence < 0.80:
print("操作: 人工审核照片")
elif sharpness.score < 2.0:
print("操作: 建议重新拍摄")
else:
print("操作: 通过对焦检查")我们得到的输出结果如下:
Image: d:\images\jev-test\product_photo_1.png
产品可见概率: 0.990
清晰度: 2.88 / 3
置信度: 0.870
等级概率: {0: 0.0, 1: 0.01, 2: 0.11, 3: 0.88}
操作: 通过对焦检查
Image: d:\images\jev-test\product_photo_2.png
产品可见概率: 0.970
清晰度: 1.04 / 3
置信度: 0.870
等级概率: {0: 0.04, 1: 0.88, 2: 0.07, 3: 0.01}
操作: 建议重新拍摄用例3 — 定位并裁剪运输标签
在第三个用例中,我们将使用JEV新提供的Box原语来识别图片的不同部分。JEV会以边界框的形式作答,边界框是包含目标的最小矩形,由四条边定义。每条边都是图像尺寸的比例,从左上角开始测量。左右边是宽度的比例,上下边是高度的比例,因此相同的答案适用于任何尺寸的图片。
假设一个仓库应用程序接收包裹照片。我们希望找到运输标签,并保存裁剪后的图像以供后续的条形码或OCR步骤使用。
实际上,对于这个示例,我们还将使用内置的Noul JEV原语。这将回答以下问题:"包裹上甚至有运输标签吗?"只有在确认这一点后,我们才会继续尝试找到标签并裁剪到标签区域。
这是我们的输入图像。
我们询问JEV是否能在包裹上看到运输标签。如果找到标签,我们要求它围绕最大的可见标签绘制一个框。
在裁剪之前,代码会检查两个分数:标签存在的概率必须至少为90%,框的置信度必须至少为80%。当两者都满足时,代码将框坐标转换为像素,在标签周围保留一个小边距,并将裁剪后的图像保存为JPEG格式。如果任一分数不达标,它会报告不确定性或标记照片以供人工审查。
from pathlib import Path
from math import floor, ceil
# 保留准备好的图像:返回的坐标引用此版本。
photo = load_photo(r"d:\images\jev-test\parcel_photo.png")
response = client.system_one(
state={
"parcel_photo": JevImage.from_pil(photo, format="png"),
},
questions={
"label_present": Noul(
instructions=(
"在 `parcel_photo` 中的包裹上是否可见地附有运输标签?"
"寻找地址或配送标签,而不是仅仅制造商的标志。"
),
),
"label_location": Box(
instructions=(
"定位 `parcel_photo` 中附着在包裹上的最大可见运输标签。"
"包含整个标签。"
),
),
},
)
present = response.nouls["label_present"].noul
location = response.boxes["label_location"]
if present < 0.90:
print("未检测到足够确定的运输标签")
elif location.confidence is None or location.confidence < 0.80:
print("标签位置需要人工审查")
else:
edges = location.box
width, height = photo.size
# 添加小边距以减少裁剪标签的可能性。
padding = 0.02
bounds = (
floor(max(0, edges.left - padding) * width),
floor(max(0, edges.top - padding) * height),
ceil(min(1, edges.right + padding) * width),
ceil(min(1, edges.bottom + padding) * height),
)
output = Path(r"d:\images\jev-test\shipping_label_crop.jpg")
photo.crop(bounds).save(output, quality=95)
print("已保存:", output.resolve())
print("框置信度:", location.confidence)以下是保存为shipping_label_crop.jpg的裁剪图像。
用例4 —— 找出两张相似图像之间的差异
假设我们有一个汽车租赁公司,想要检查汽车是否以客户最初租用时的相同状况归还。我们可以使用JEV来发现细微差异,例如车身上的轻微凹痕和划痕。
考虑这两张汽车门的图像。第一张图像是完美的,第二张图像在中间位置有一个非常微弱的水平划痕。
AI生成的完美汽车门
AI生成的轻微划痕
让我们将它们通过JEV图像处理。以下是要求JEV比较两张汽车门照片中可见差异、检查是否有新划痕并用边界框定位它的代码。它会打印概率和框置信度,如果划痕的概率至少为80%且框置信度至少为70%,则绘制、保存并显示一个红色矩形;否则,报告不确定性。
from pathlib import Path
from PIL import ImageDraw
from IPython.display import display
from typesafe_sdk import Image as JevImage, Noul, Box
folder = Path(r"d:\images\jev-test")
# 保留准备好的图像,以便之后在其上绘制。
comparison_photo = load_photo(folder / "car-door-3.png")
response = client.system_one(
state={
"original": image_asset(folder / "car-door-1.png"),
"comparison": JevImage.from_pil(
comparison_photo,
format="jpeg",
),
},
questions={
"visible_difference": Noul(
instructions=(
"比较 `original` 和 `comparison`。 "
"物体、标记、文本、形状或排列是否存在可见差异?查找细微变化,"
"包括添加、删除或修改的细节。 "
"忽略仅由光照、压缩或轻微相机移动引起的差异。"
),
),
"scratch_present": Noul(
instructions=(
"`comparison` 中的汽车门漆面是否显示了 `original` 中不存在的划痕? "
"区分划痕与反光和面板接缝。"
),
),
"scratch_location": Box(
instructions=(
"在 `comparison` 中定位汽车门漆面中 `original` 中不存在的划痕。 "
"返回一个紧密包围整个划痕的矩形框。 "
"在 `comparison` 中定位,而非 `original`。"
),
),
},
)
probability = response.nouls["visible_difference"].noul
scratch_probability = response.nouls["scratch_present"].noul
location = response.boxes["scratch_location"]
print(f"可见差异的概率: {probability:.3f}")
print(f"存在划痕的概率: {scratch_probability:.3f}")
print("框置信度:", location.confidence)
# 示例阈值:请在自己的图像对上测试这些值。
if probability >= 0.85:
print("很可能存在可见差异")
elif probability <= 0.2:
print("未检测到可见差异")
else:
print("不确定:请手动检查图像")
# Box 总是返回坐标,即使目标不存在。
# 仅当划痕及其位置足够确定时才绘制。
if (
scratch_probability >= 0.8
and location.confidence is not None
and location.confidence >= 0.70
):
edges = location.box
width, height = comparison_photo.size
# 将归一化坐标转换为像素,添加小边距。
padding = 6
rectangle = (
max(0, int(edges.left * width) - padding),
max(0, int(edges.top * height) - padding),
min(width - 1, int(edges.right * width) + padding),
min(height - 1, int(edges.bottom * height) + padding),
)
annotated = comparison_photo.copy()
draw = ImageDraw.Draw(annotated)
draw.rectangle(rectangle, outline="red", width=3)
output_path = folder / "car-door-3-boxed.png"
annotated.save(output_path)
print(f"带注释的图像已保存至: {output_path}")
display(annotated)
else:
print("划痕检测或定位不确定;未绘制框。")这是我的输出结果。
可见差异的概率: 0.830 存在划痕的概率: 0.830 框置信度: 0.77 不确定:请手动检查图像 带注释的图像已保存至: d:\images\jev-test\car-door-3-boxed.png
根据图像差异程度,可能需要调整各种概率阈值以获得所需的输出效果。
## 总结
JEV的图像功能为我们提供了一种实用方法,可以将视觉评估转化为软件可执行的决策。我们可以将图像与参考照片进行分类比较,评估特定质量,检查某物是否存在,或使用新的Box原语定位它。
我对“找不同”这个例子印象特别深刻。虽然年纪渐长,但那个划痕对我来说还挺难发现的——即使我知道它在哪里!
我的四个例子只是展示了JEV图像处理所能提供的机会的一小部分。类似的方法还可以支持设备检测、零售货架监控、农作物损伤评估和制造质量检查等应用场景。
重要的是,应用程序仍然控制后续操作。概率或置信度值可以决定是接受图像、请求重新拍摄还是发送案例进行人工检查。
对感兴趣的朋友,这里是我在文章开头提到的关于OpenAI Decisions API的上一篇TDS文章链接:
/think