feat: Implement cutout tool and depth generation features
- Added a new cutout tool for selecting regions in images, allowing users to choose mesh shapes based on selected areas. - Introduced depth generation capabilities for rasterized images, including normal data extraction. - Created jobs for generating depth planes and region data, enhancing the AI data generation workflow. - Developed a selection refinement process for cutout regions, improving accuracy in generated outputs. - Established a new region module for handling rasterized image regions and their associated AI generation tasks. - Enhanced node graph builders for asset generation, facilitating smoother integration of new features.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Plane 转换
|
||||
|
||||
Plane 转换包含两条路径:普通 Plane 在 Blender 内同步完成;Depth Plane 先通过 `prepare-geometry-data` Job 取得深度场,再回到 Blender 构建面片。两者共享图片命名、材质与基础四边形能力,但使用不同的 Geometry Nodes。
|
||||
Plane 转换包含两条路径:普通 Plane 在 Blender 内同步完成;Depth Plane 先通过 `generate-depth-plane` Job 取得深度场,再回到 Blender 构建面片。两者共享图片命名、材质与基础四边形能力,但使用不同的 Geometry Nodes。
|
||||
|
||||
## 对应文件
|
||||
|
||||
@@ -13,7 +13,8 @@ operators/convert_to_plane/
|
||||
└── nodes.py # 运行时 O Image Depth Plane 节点图
|
||||
|
||||
server/
|
||||
├── jobs/prepare_geometry_data.py
|
||||
├── jobs/generate_depth_plane.py
|
||||
├── geometry/generate_depth.py
|
||||
├── models/da3.py
|
||||
├── models/moge2.py
|
||||
└── geometry/projection.py
|
||||
@@ -27,8 +28,8 @@ flowchart TD
|
||||
Kind -- "Plane" --> Copy["复制 Image 与材质"]
|
||||
Copy --> Quad["创建四边形 + O Mesh Plane"]
|
||||
Kind -- "Depth Plane" --> Input["准备颜色与分析输入"]
|
||||
Input --> Job["prepare-geometry-data"]
|
||||
Job --> Field["image.0001 + field.npz"]
|
||||
Input --> Job["generate-depth-plane"]
|
||||
Job --> Field["image.0001 + image_geometry.npz"]
|
||||
Field --> Anchor["按 Empty 范围锚定相机点"]
|
||||
Anchor --> Depth["创建深度 Image + 材质 + 节点修改器"]
|
||||
Quad --> Replace["替换源 Empty"]
|
||||
@@ -45,7 +46,7 @@ flowchart TD
|
||||
|
||||
`ConvertToDepthPlane` 当前只接受静态图片。深度模型和分辨率来自扩展 Preferences:MoGe-2 使用 Resolution Level,DA3 使用按原图尺寸换算并对齐到模型 Patch 的处理分辨率。
|
||||
|
||||
`GenerateDepthPlane` 把颜色输入、分析输入和模型参数提交给 `prepare-geometry-data`。Server 将模型结果统一为 `GeometryFrame`,写出包含相机点、深度、内参、有效区域和参考深度的 `field.npz`。这一步不创建网格。 `max_input_size` 同时传入 Job;Server 通过 `media/resolution.py` 在模型推理前限制分析图长边,默认 `2048`。颜色输入仍由未缩放的原图复制,受限分析图不会成为材质 Color。
|
||||
`GenerateDepthPlane` 把当前 Image 随模型参数提交给 `generate-depth-plane`。`jobs/generate_depth_plane.py` 负责单图协议,`geometry/generate_depth.py` 负责 AI 深度生成;Server 将模型结果统一为 `GeometryFrame`,写出包含相机点、深度、内参、有效区域和参考深度的 `image_geometry.npz`。Blender 侧通过公共 `load_image_geometry()` 读取为 `ImageGeometry`,与 Cutout 使用同一协议校验。这一步不创建网格。`max_input_size` 同时传入 Job;Server 通过 `media/resolution.py` 在模型推理前限制分析图长边,默认 `2048`。颜色输入仍按当前 Image 的未缩放分辨率复制,受限分析图不会成为材质 Color。
|
||||
|
||||
Blender 响应阶段执行三件事:
|
||||
|
||||
@@ -56,3 +57,5 @@ Blender 响应阶段执行三件事:
|
||||
Depth 节点组先复用 `O Mesh Plane` 完成细分与材质,再生成背面厚度、限制正面向内穿透,最后在 Thickness 为零时删除背面和侧面。`Depth Amount` 控制位移强度;`Depth Image` 与 `Material` 是由插件填入的内部输入。
|
||||
|
||||
与 Cutout 的 Depth Surface 不同,Depth Plane 只使用锚定后的 Z 高度,不在 Geometry Nodes 中重建完整相机空间 XYZ。它强调一张图上的可编辑浮雕,而不是局部透视表面。
|
||||
|
||||
颜色材质、Normal 导入和结果对象激活分别复用 `create_image_material()`、`load_normal_result_image()` 与 `finalize_object_result()`;普通 Plane 和 Depth Plane 不再各自维护对象替换步骤。
|
||||
|
||||
@@ -1,80 +1,76 @@
|
||||
# Cutout
|
||||
# Cutout Tool
|
||||
|
||||
Cutout 从一条图片空间套索生成规则三角基础面,再交给统一的 `O Image Cutout` Geometry Nodes 修改器形成 Surface、Balloon、Depth Balloon 或 Depth Surface。公开节点组用 Shape 菜单路由到四个原有内部节点组;轮廓和 Mesh 始终由 Blender 主线程创建,Server 只在需要时准备 Refine、深度或法线数据。
|
||||
Cutout 由两个核心 Operator 组成:
|
||||
|
||||
## 对应文件
|
||||
- `SelectCutoutRegion`(`select_region.py`)把 Viewport 手势转换为图片空间 Region,并弹出 Shape 菜单。
|
||||
- `CutoutRegionToShape`(`region_to_shape.py`)准备所需数据,再构建并创建 Shape。
|
||||
|
||||
```text
|
||||
operators/cutout_tool/
|
||||
├── selection_tool.py # 套索交互、设置与 Shape 饼菜单
|
||||
├── shape_conversion.py # 本地 / Job 路径选择和任务参数
|
||||
├── build_shapes.py # 裁切贴图、Mesh、材质与修改器
|
||||
├── shape_types.py # Shape 与节点组映射
|
||||
├── mask_regions.py # Alpha 外轮廓与孔洞
|
||||
├── planar_mesh.py # 规则采样与约束三角化
|
||||
├── balloon_profile.py # Poisson / Teddy profile
|
||||
├── depth_calibration.py # Reference 与 Direction
|
||||
└── node_assets.py # Cutout 节点资产加载
|
||||
路径约定:Blender 侧文件相对 `src/anyimage/operators/cutout_tool/`,Server 侧文件相对 `src/anyimage/server/`。
|
||||
|
||||
server/
|
||||
├── jobs/prepare_geometry_data.py # Cutout / Depth Plane 数据编排
|
||||
├── selection/
|
||||
│ ├── polygon_mask.py # Polygon 栅格化与选区裁切
|
||||
│ └── cutout_images.py # Refine 与 Cutout 局部图片
|
||||
└── geometry/normal_texture.py # 相机轴法线编码
|
||||
```
|
||||
|
||||
## 路径选择
|
||||
## 执行路径
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Lasso["套索 + Shape"] --> Refine{"Refine Selection?"}
|
||||
Refine -- "是" --> Ben2["BEN2 × 1"]
|
||||
Refine -- "否" --> Selection["套索 Selection"]
|
||||
Ben2 --> Selection
|
||||
Selection --> NeedMoge{"需要 Depth 或 Normal?"}
|
||||
NeedMoge -- "否" --> Mesh["轮廓 → 规则点 → 约束三角化"]
|
||||
NeedMoge -- "是" --> Moge["MoGe-2 × 1\\n同一 Prediction"]
|
||||
Moge --> Data["Depth Field / Camera Normal"]
|
||||
Data --> Mesh
|
||||
Mesh --> Profile["计算 o_balloon"]
|
||||
Profile --> Nodes["加载 O Image Cutout 并设置 Shape"]
|
||||
Nodes --> Bake["按需烘焙最终 Tangent Normal"]
|
||||
Select["圈定 Cutout Region<br/>选择 Shape"]
|
||||
Raster["栅格化 Region"]
|
||||
Route{"需要 AI 数据?"}
|
||||
Local["使用本地 Region 数据"]
|
||||
AI["生成 Refine / Depth / Normal"]
|
||||
Ready["汇总 Shape 输入"]
|
||||
Build["构建基础 Shape"]
|
||||
Create["创建 Blender 对象"]
|
||||
|
||||
Select --> Raster
|
||||
Raster --> Route
|
||||
Route -- "否" --> Local --> Ready
|
||||
Route -- "是" --> AI --> Ready
|
||||
Ready --> Build --> Create
|
||||
```
|
||||
|
||||
Cutout 只接受静态图片。Refine Selection 是网格生成前唯一可选的选区分析:开启时执行一次 BEN2,关闭时直接使用套索 Selection。Surface 与 Balloon 在不需要 Normal 时不运行 MoGe-2;两个 Depth Shape 和任意开启 Normal 的 Shape 都统一使用 MoGe-2。Depth 与 Normal 同时启用时只执行一次推理,同一个 Prediction 同时提供相机点、深度和图片空间法线。
|
||||
## 节点说明
|
||||
|
||||
Cutout 不使用 DA3。若全局 Depth Model 当前选择 DA3,Cutout 会回退到默认 MoGe-2;选择 MoGe-2 档位时则沿用该档位和 Resolution Level。DA3 仍可用于独立的 Depth Plane 流程。
|
||||
### 圈定 Cutout Region
|
||||
|
||||
## 选择与局部数据
|
||||
`SelectCutoutRegion` 将 Lasso 路径投射到图片像素坐标,形成 `RegionPath`,然后把 Region 和用户选择的 Shape 交给 `CutoutRegionToShape`。双击图片时,Region 使用完整图片范围。
|
||||
|
||||
Cutout 复用 `ImageMaskGesture` 的采点和屏幕预览,并复用 `operators/common/image_mask.py` 的可见选区语义:最终几何范围始终是套索、图片边界与源图 `Alpha > 0.1` 区域的交集。套索采用 NONZERO 填充规则,使反向内环可以表达孔洞。`Point Spacing` 先根据完整源图最长边换算为基础 `mesh_detail`;获得裁切 Selection 后,再按 `min(1, max_input_size / crop_long_edge)` 缩放有效 `mesh_detail`。因此只有裁切图超过全局上限时网格才会变稀,Color Image 仍使用原始裁切尺寸。
|
||||
`RegionPath` 定义在 `operators/common/image_region.py`,包含图片空间路径点、反选状态和填充规则。它既供 Cutout 使用,也供 Image Tool 使用。
|
||||
|
||||
Job 路径将数据拆成三层:源颜色、最终选择和只供模型分析的 RGBA。写出最终选择前会再次以 `Alpha > 0.1` 与源图求交,因此未 Refine、Refine 和双击全图遵循相同边界。`bounds.json` 把可见选区的局部矩形映射回源图,Blender 据此恢复局部平面范围和 UV。未走 Job 时,`build_shapes.py` 在内存中完成相同的求交、裁切与坐标换算。
|
||||
### 栅格化 Region
|
||||
|
||||
## 基础网格
|
||||
`CutoutRegionToShape` 把 `RegionPath` 栅格化为 `RegionMask`。`RegionMask` 只包含局部像素权重 `values` 和它在源图中的 `bounds`,后续几何、颜色裁切和 AI 输入都以它为范围。
|
||||
|
||||
最终 Alpha 先转为带包含关系的外轮廓与孔洞。`planar_mesh.py` 在内部生成近似六角排列的规则点,并用轮廓作为约束进行 Delaunay 三角化。边界按目标间距重采样,短轮廓会提高边界采样密度,内部点仍保持用户设置的间距。
|
||||
Surface 或 Balloon 在未启用 Refine 与 Normal 时直接使用本地 Region 数据;选择 Depth Shape,或启用 Refine、Normal 时进入 AI 路径。两条路径最终都调用 `region_to_shape()`。
|
||||
|
||||
四种 Shape 共享同一张单面基础网格、UV 和 `o_balloon` 点属性。创建阶段以目标 Point Spacing 的平方作为一个采样单元面积,再除以 Image Empty 图片平面从局部到世界的面积缩放,得到修改器局部坐标中的 Cleanup 阈值。这个值只取决于工具分辨率和图片尺寸/变换,不受碎片数量或碎面面积分布影响。Balloon Profile 由 Preferences 选择 Poisson 或 Teddy;节点组只消费计算后的属性,不再重复推导轮廓。
|
||||
### 生成 AI 数据
|
||||
|
||||
## 统一修改器与四种 Shape
|
||||
`generate-region-data` Job(`jobs/generate_region_data.py`)根据请求生成所需数据:
|
||||
|
||||
创建结果时始终添加 `O Image Cutout`,并按饼菜单选择写入 Shape。节点组先统一执行 Cleanup,再由 Menu Switch 仅求值当前 Shape 的内部节点组,最后统一执行 Smooth;因此四种 Shape 都可使用 Cleanup、Smooth 和 Smooth Iterations。各分支独有输入直接连接到对应内部组,Blender 4.5 会在修改器中隐藏当前 Shape 不使用的输入。Cleanup 直接比较 Mesh Island 总面积与创建时写入的绝对面积阈值,不再统计当前网格面的中位面积。
|
||||
- `generate_selection()`(`region/generate_selection.py`)使用 BEN2 收紧 Region;
|
||||
- `generate_depth(..., normal_mode=...)`(`geometry/generate_depth.py`)使用 MoGe-2 生成 Depth,并可从同一次 Prediction 派生 Tangent 或 Object Normal。
|
||||
|
||||
| Shape | 内部节点组 | 主要几何来源 |
|
||||
Blender 传入的已是带 Region Alpha 的局部 RGBA。Depth 与 Normal 同时启用时只运行一次 MoGe-2,颜色贴图仍使用 Region 的原始裁切分辨率。
|
||||
|
||||
### 构建基础 Shape
|
||||
|
||||
`region_to_shape()` 汇总 Region、Depth 和 Normal 输入,再依次执行几何构建与 Blender 数据创建。
|
||||
|
||||
`build_base_shape()` 从 `RegionMask` 构建纯内存 `BaseShape`:先由 `region_contours.py` 提取包含外轮廓与孔洞的 `RegionContours`,再由 `triangulation.py` 按 Point Spacing 采样并约束三角化,最后使用 `balloon.py` 计算 `o_balloon`。`depth_calibration.py` 负责把 AI Depth 标定为 Blender 中使用的深度基准与方向。四种 Shape 共用这张单面基础网格。
|
||||
|
||||
### 创建 Blender 对象
|
||||
|
||||
`create_shape_object()` 创建裁切后的 Color Image、Material、Mesh Object 和统一的 `O Image Cutout` Modifier。Shape 的差异由 Modifier 中对应的几何分支表达:
|
||||
|
||||
| Shape | 形成方式 | Shape 自身所需 AI 数据 |
|
||||
| --- | --- | --- |
|
||||
| Surface | `O Image Surface` | 基础薄片与可调 Thickness |
|
||||
| Balloon | `O Image Balloon` | `o_balloon` 鼓起高度 |
|
||||
| Depth Balloon | `O Image Depth Balloon` | Balloon profile + 相对基准面的非负深度高度 |
|
||||
| Depth Surface | `O Image Depth Surface` | MoGe-2 相机点的完整投影 |
|
||||
| Surface | 保持基础 Shape 的平面轮廓,并可增加真实厚度 | 无 |
|
||||
| Balloon | 使用 `o_balloon` 从轮廓向内部平滑鼓起 | 无 |
|
||||
| Depth Balloon | 在 Balloon 上叠加相对基准面的图片深度,并沿 Depth Direction 形成浮雕 | MoGe-2 Depth |
|
||||
| Depth Surface | 使用完整相机点 XYZ 重建带透视位移的表面,并可增加厚度 | MoGe-2 Camera Points |
|
||||
|
||||
四个内部节点组不再标记为 Modifier,也不再各自执行 Cleanup。原本只在 `O Image Depth Surface` 内的 Smooth 后处理已移到公开节点组;统一节点组的 Smooth 默认值为 `1`;外层 `Smooth Iterations` 默认值为 `0`,只有用户增加迭代次数后才执行平滑。两个 Depth 内部节点组也统一使用 `Reference Depth`,总节点组只暴露一个共用输入。
|
||||
四种 Shape 共用 Region、基础三角面、UV、材质、Cleanup 和 Smooth。Cleanup 的 UI 数值放大 `100` 倍,节点内部乘以 `0.01` 还原,因此显示尺度不会改变实际清理阈值。
|
||||
|
||||
两个 Depth 形状把相机点 RGB 写入 Packed 浮点 `_depth.exr`,并以隐藏的 `Uniform Scale` 匹配 Image Empty 尺寸。未启用 Refine 时 Reference 使用固定值,Depth Balloon Direction 使用默认轴向;启用 Refine 后,`calibration_valid` 限制在模型有效区域与最终选择的交集,Reference 使用其深度第 95 百分位,Depth Balloon 还拟合局部基准方向。
|
||||
### Depth 与 Normal
|
||||
|
||||
Depth Balloon 保留图片平面 XY,只使用相机 Z 形成向外高度;Depth Surface 将完整 XYZ 映射到 Cutout 局部轴,因此能表达透视位移。两者都只采样深度 Image 的 RGB,Alpha 仅保存有效性和深度跳变信息。
|
||||
Depth Shape 根据最终 Region Alpha 选择基准:透明像素比例达到 `5%` 时从有效内容自适应计算 Base Plane Depth;不足 `5%` 时使用固定基准。Depth Balloon 还会在自适应路径中拟合 Depth Direction。
|
||||
|
||||
## 法线空间
|
||||
|
||||
MoGe-2 在 Job 阶段输出图片空间的相机轴法线预测;这一步不依赖 Blender 网格。Depth Surface 在导入时将它重排到 Cutout 对象轴并以 Object Space 使用;Surface、Balloon 与 Depth Balloon 则先创建基础网格并完成 Geometry Nodes 求值,再根据成品网格 UV、法线和切线基底烘成 Tangent Space。也就是说,网格前产生的是模型 Prediction,最终法线贴图的空间转换仍发生在网格生成之后。
|
||||
Normal 是材质层的浮雕细节,与四种 Shape 都可组合。None 使用几何法线;Tangent 以完整图片平面为切线基准;Object 直接编码到 Cutout 对象局部轴。Geometry Nodes 负责大轮廓和深度,Normal 负责表面细节。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Image Tool
|
||||
|
||||
`operators/image_tool/` 对应工具栏中的 Box、Lasso、Line 与 Polyline。四个 WorkspaceTool 共用一个 `EditImageMask` Operator,把屏幕手势转换为图片 Alpha;只有 Box 与 Lasso 可以用 BEN2 细化选择。
|
||||
`operators/image_tool/` 对应工具栏中的 Box、Lasso、Line 与 Polyline。四个 WorkspaceTool 共用一个 `EditImageMask` Operator:手势先形成图片空间 Region,Region 栅格化为 Mask 后才修改图片 Alpha;只有 Box 与 Lasso 可以用 BEN2 执行 Refine Selection。
|
||||
|
||||
## 对应文件
|
||||
|
||||
@@ -20,20 +20,22 @@ operators/image_tool/
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Tool["Box / Lasso / Line / Polyline"] --> Gesture["ImageMaskGesture"]
|
||||
Gesture --> Polygon["图片像素 Polygon"]
|
||||
Polygon --> Refine{"Refine Selection?"}
|
||||
Refine -- "否" --> Mask["本地几何 Mask"]
|
||||
Refine -- "是" --> Job["refine-image-mask"]
|
||||
Tool["Box / Lasso / Line / Polyline"] --> Gesture["ImageRegionGesture"]
|
||||
Gesture --> Region["RegionPath"]
|
||||
Region --> Raster["栅格化 Region"]
|
||||
Raster --> Data["RegionMask"]
|
||||
Data --> Refine{"Refine Selection?"}
|
||||
Refine -- "否" --> Mask["Region Mask"]
|
||||
Refine -- "是" --> Input["带 Region Alpha 的裁切 RGBA"]
|
||||
Input --> Job["refine-image-mask"]
|
||||
Job --> Mask
|
||||
Mask --> Invert["可选反选"]
|
||||
Invert --> Alpha["源 Alpha × 最终 Mask"]
|
||||
Mask --> Alpha["源 Alpha × Mask"]
|
||||
Alpha --> Crop["紧裁切并写回 Empty"]
|
||||
```
|
||||
|
||||
`EditImageMask` 只接受静态图片。未启用 Refine 时,Polygon 在 Blender 侧直接栅格化;启用后,Operator 准备单图输入并提交 Job,响应阶段读取局部 Alpha 与源图 `bounds`,再映射回完整画布。反选始终在最终 Mask 上执行。
|
||||
`EditImageMask` 只接受静态图片。`ImageRegionGesture` 把屏幕路径投射为 `RegionPath`;`rasterize_region_path()` 再生成 `RegionMask`。未启用 Refine 时直接把 Region Mask 乘入源 Alpha;启用后,Operator 将 `RegionMask` 写成局部 RGBA 并提交 Job,响应阶段读取细化后的 Alpha 与 `bounds`,再映射回完整画布。
|
||||
|
||||
Box 和 Lasso 分别保存自己的 Refine 状态。Line 与 Polyline 强制关闭 Refine,只使用几何 Mask;Line 将有向线扩展为半平面,Polyline 显式闭合用户确认的顶点。
|
||||
Box 和 Lasso 分别保存自己的 Refine Selection 状态。Line 与 Polyline 强制关闭 Refine,只使用本地 Region Mask;Line 将有向线扩展为半平面 Path,Polyline 显式闭合用户确认的 Path。
|
||||
|
||||
## 手势与预览
|
||||
|
||||
@@ -43,4 +45,4 @@ Box 和 Lasso 分别保存自己的 Refine 状态。Line 与 Polyline 强制关
|
||||
|
||||
## 写回结果
|
||||
|
||||
最终像素保留源 RGB,只修改 Alpha,再按非零 Alpha 紧裁切。公共写回函数只替换当前 Empty 的 Image,并更新 `empty_display_size` 与 `empty_image_offset`,因此剩余像素继续对齐原图片平面,对象 `matrix_world` 不变。
|
||||
最终像素通过公共 `image_pixels()` / `image_rgba()` 读取,保留源 RGB,只修改 Alpha,再按非零 Alpha 紧裁切。公共像素写回函数创建结果后,通过统一的 Image Empty 替换入口处理共享引用,并更新 `empty_display_size` 与 `empty_image_offset`,因此剩余像素继续对齐原图片平面,对象 `matrix_world` 不变。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Operator 实现索引
|
||||
|
||||
`src/anyimage/operators/` 负责 Blender 侧交互、Job 请求组装和结果导入。内部实现按完整功能包或顶层业务模块拆页;只提供共享能力的 `common/` 不单独成页,其职责统一放在[程序架构](../architecture.md)中说明。
|
||||
`src/anyimage/operators/` 负责 Blender 侧交互、Job 请求组装和结果导入。内部实现按完整功能包或顶层业务模块拆页;`common/` 的边界见[程序架构](../architecture.md),实际公开入口见[Common 公共函数](../common.md)。
|
||||
|
||||
| Operator 路径 | 实现页 | 主要职责 |
|
||||
| --- | --- | --- |
|
||||
@@ -8,11 +8,11 @@
|
||||
| `operators/ai_setup.py` | [AI 环境管理](ai-setup.md) | 环境安装、模型下载与缓存释放 |
|
||||
| `operators/clipboard_image/` | [Clipboard Image](clipboard-image.md) | 系统剪贴板读取、粘贴与快捷键 |
|
||||
| `operators/convert_to_plane/` | [Convert to Plane](convert-to-plane.md) | Mesh Plane 与 Depth Plane 创建 |
|
||||
| `operators/cutout_tool/` | [Cutout Tool](cutout-tool.md) | 区域选择、轮廓生成与 Shape 构建 |
|
||||
| `operators/cutout_tool/` | [Cutout Tool](cutout-tool.md) | Region 选择、基础 Shape 构建与 Blender 对象创建 |
|
||||
| `operators/debug.py` | [Debug Operator](debug.md) | 模型接口与原始产物验证 |
|
||||
| `operators/image_tool/` | [Image Tool](image-tool.md) | Box、Lasso、Line 与 Polyline 编辑 |
|
||||
| `operators/perspective_tool/` | [Perspective Tool](perspective-tool.md) | 四点透视框与透视校正 |
|
||||
| `operators/remove_background.py` | [Remove Background](remove-background.md) | BEN2 去背与结果替换 |
|
||||
| `operators/upscale.py` | [Upscale](upscale.md) | 4× 高清与原图引用维护 |
|
||||
| `operators/upscale.py` | [Upscale](upscale.md) | 当前 Image 的 4× 高清与输入长边检查 |
|
||||
|
||||
`operators/__init__.py` 只聚合注册类,不承载独立业务流程。具体类的注册和逆序注销由扩展入口统一管理,整体边界见[程序架构](../architecture.md)。
|
||||
|
||||
@@ -10,7 +10,7 @@ operators/perspective_tool/
|
||||
└── edit_perspective.py # 四点交互、预览、Homography 与写回
|
||||
```
|
||||
|
||||
图片选择、裁切和 Empty 写回复用 `operators/common/` 的基础能力,不与 Image Mask Operator 共享业务状态。
|
||||
图片坐标投射、Alpha 裁切和 Empty 写回复用 `operators/common/` 的基础能力;四点数据始终称为 Quad,不与 Image Region 或 Image Mask Operator 共享业务状态。
|
||||
|
||||
## 矫正流程
|
||||
|
||||
@@ -29,4 +29,4 @@ flowchart TD
|
||||
|
||||
Homography 使用预乘 Alpha 插值,避免透明边缘混入黑色。输出最长边限制为 8192 px,总像素限制为 16,777,216,并按 256 行分块计算,控制中间数组大小。
|
||||
|
||||
Perspective 是 deform 工具,不提供 Refine 或反选。结果比例可能不同于原四边形的轴对齐范围,因此 Empty 写回保持中心和覆盖尺度近似一致,而不是假设当前 3D View 相机等于图片拍摄相机。
|
||||
Perspective 是 deform 工具,不提供 Refine 或反选。它通过公共 `image_pixels()` 读取供预览与最终 Warp 共用的源像素,并与 Image Mask 共用像素结果创建和 Image Empty 替换入口。结果比例可能不同于原四边形的轴对齐范围,因此 Empty 写回保持中心和覆盖尺度近似一致,而不是假设当前 3D View 相机等于图片拍摄相机。
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
src/anyimage/
|
||||
├── operators/
|
||||
│ ├── remove_background.py # Blender 入口、任务参数与结果替换
|
||||
│ └── common/image.py # 媒体输入准备与结果 Image 创建
|
||||
│ └── common/image_data.py # 媒体输入准备与结果 Image 创建
|
||||
└── server/
|
||||
├── jobs/remove_background.py # 单图与多帧任务编排
|
||||
└── models/ben2.py # BEN2 前景适配
|
||||
@@ -28,4 +28,4 @@ flowchart TD
|
||||
|
||||
Packed 图片或内存中修改过的单图会先导出为临时输入;文件图片、视频和序列则沿用可读取的源路径。多帧输入由统一媒体层展开,结果保持连续帧命名,导入后继续沿用源 Image User 的帧起点、偏移与循环设置。
|
||||
|
||||
BEN2 推理前使用输入 Alpha 屏蔽透明区域,模型输出的前景 Alpha 再与源 Alpha 合成,RGB 保持为源图内容。响应阶段只替换当前 Empty 的 Image 数据;当旧 Image 没有其他用户和 Fake User 时,旧数据块会被清理并由结果继承名称。
|
||||
BEN2 推理前使用输入 Alpha 屏蔽透明区域,模型输出的前景 Alpha 再与源 Alpha 合成,RGB 保持为源图内容。响应阶段通过公共 Image Empty 替换入口导入结果;当旧 Image 没有其他用户和 Fake User 时,旧数据块会被清理并由结果继承名称。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Upscale
|
||||
|
||||
本页对应 `src/anyimage/operators/upscale.py`。该模块读取扩展首选项中的模型与全局 AI 输入长边上限,提交 4× 高清任务,并维护高清结果到原始 Image 的引用。
|
||||
本页对应 `src/anyimage/operators/upscale.py`。该模块读取扩展首选项中的模型与全局 AI 输入长边上限,检查当前 Image 是否可处理,再提交 4× 高清任务。
|
||||
|
||||
## 对应文件
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
src/anyimage/
|
||||
├── operators/
|
||||
│ ├── upscale.py # Blender 入口、任务参数与结果替换
|
||||
│ └── common/image.py # 媒体输入准备与结果 Image 创建
|
||||
│ └── common/image_data.py # 媒体输入准备与结果 Image 创建
|
||||
└── server/
|
||||
├── jobs/upscale.py # 单图与多帧任务编排
|
||||
├── media/resolution.py # 共用长边限制与等比缩放
|
||||
@@ -20,17 +20,18 @@ src/anyimage/
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Empty["Image Empty"] --> Source["解析原始 Image"]
|
||||
Source --> Prepare["准备媒体输入"]
|
||||
Empty["Image Empty"] --> Source["读取当前 Image"]
|
||||
Source --> Gate{"当前长边小于全局上限?"}
|
||||
Gate -- "否" --> Disabled["Upscale 置灰"]
|
||||
Gate -- "是" --> Prepare["准备媒体输入"]
|
||||
Prepare --> Job["upscale-image Job"]
|
||||
Job --> Limit["按全局输入长边上限等比缩放"]
|
||||
Limit --> RGB["分块执行 4× RGB 推理"]
|
||||
Limit --> Alpha["独立缩放 Alpha"]
|
||||
Job --> RGB["分块执行 4× RGB 推理"]
|
||||
Job --> Alpha["独立缩放 Alpha"]
|
||||
RGB --> Merge["合并 RGBA 结果"]
|
||||
Alpha --> Merge
|
||||
Merge --> Replace["导入并替换当前 Image"]
|
||||
```
|
||||
|
||||
模型以 256×256 分块处理 RGB,并带入相邻上下文以减弱块边界;Alpha 按同一受限输入尺寸单独缩放,最后合并为 RGBA。`max_input_size` 来自全局 **Maximum AI Input Size**,默认 `2048`,只约束送入模型的长边;4× 输出长边因此默认为最多 `8192`。输入尺寸不超过上限时不会发生预缩放。
|
||||
模型以 256×256 分块处理 RGB,并带入相邻上下文以减弱块边界;Alpha 不进入模型,使用 Lanczos 独立放大后合并为 RGBA。`max_input_size` 来自全局 **Maximum AI Input Size**,默认 `2048`。Operator 只允许当前 Image 长边小于该值时执行,因此正式流程不会预缩放输入,4× 输出长边小于上限的四倍。Server 仍保留相同上限作为任务边界。
|
||||
|
||||
结果以 `_upscale.png` 结尾,并通过 `Image.anyimage_upscale_source` 保存原图引用。再次对高清结果执行时,Operator 会从原图重新生成,而不是继续放大上一次输出。模型与全局输入上限在每次执行时从 Preferences 读取,再写入可序列化的隐藏属性交给 Job。Provider 资源错误会释放当前 Upscale Session,并提示降低全局输入上限或改用 CPU。
|
||||
菜单根据当前尺寸只显示预计的 4× 结果尺寸。结果通过与 Remove Background、Image Mask 和 Perspective 相同的 Image Empty 替换入口处理:原 Image 没有其他用户且未启用 Fake User 时,移除旧数据并让结果沿用原名;存在其他用户时保留原 Image,并只让当前 Empty 使用独立结果。结果不增加 Upscale 专属后缀,也不保存来源引用。后续 Upscale 与 Depth Plane 都读取当前 Image。模型与全局输入上限在每次执行时从 Preferences 读取,再写入可序列化的隐藏属性交给 Job。Provider 资源错误会释放当前 Upscale Session,并提示降低全局输入上限或改用 CPU。
|
||||
|
||||
Reference in New Issue
Block a user