LabVIEW的POSTMultipart

目录

python代码

测试代码的版本:python310

运行前需安装

bash 复制代码
pip install python-multipart
pip install fastapi uvicorn opencv-python numpy

代码:

python 复制代码
import cv2
import numpy as np
from fastapi import FastAPI, File, UploadFile
from datetime import datetime

app = FastAPI()

@app.post("/locate")
async def locate(file: UploadFile = File(...)):
    # 1. 读取原始字节
    contents = await file.read()
    
    # 2. 【调试用】保存原始文件,验证传输完整性
    debug_path = f"debug_{datetime.now():%Y%m%d_%H%M%S}.jpg"
    with open(debug_path, "wb") as f:
        f.write(contents)
    print(f"[DEBUG] 已保存原始文件: {debug_path}, 大小: {len(contents)} bytes")
    
    # 3. 解码为 numpy 数组(你原有的逻辑)
    nparr = np.frombuffer(contents, np.uint8)
    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    
    # 4. 【可选】检查解码结果
    if img is None:
        return {"error": "图片解码失败,请检查LabVIEW编码格式"}
    print(f"[DEBUG] 解码成功: shape={img.shape}, dtype={img.dtype}")
    
    # 5. 后续 AI 推理逻辑...
    # result = model.predict(img)
    
    return {"status": "ok", "shape": list(img.shape)}

fastapi部署

部署:

bash 复制代码
uvicorn main:app --host 0.0.0.0 --port 8000

判断是否部署成功:

bash 复制代码
netstat -anob | findstr :8000

如果部署成功想关闭:

bash 复制代码
taskkill /F /PID <调用netstat显示的PID号>

效果如下:

bash 复制代码
C:\Users\test>netstat -ano | findstr :8000
  TCP    0.0.0.0:8000           0.0.0.0:0              LISTENING       27376

C:\Users\test>taskkill /F /PID 27376
成功: 已终止 PID 为 27376 的进程。

LabVIEW代码

apipost

locate-anything

安装依赖包

python 复制代码
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
pip install locate-anything

下载模型

python 复制代码
pip install modelscope
modelscope download --model nv-community/LocateAnything-3B
  • 默认路径:C:\Users\test\.cache\modelscope\models\nv-community--LocateAnything-3B\snapshots\master

模型

推理代码:

python 复制代码
import os
import re
import torch
from datetime import datetime
from PIL import Image, ImageDraw
from locate_anything import LocateAnything

# ================= 配置区 =================
IMAGE_PATH = "maoding.png"
MAX_SIZE = 1024
#CATEGORIES = ["large irregular circular hole with torn edges"]
CATEGORIES = ["large hole with diameter between 5% and 7% of image width"]
SAVE_DIR = r"D:\script\detect_results"
# ==========================================

# 1. 加载模型
model = LocateAnything(
    model_name=r"C:\Users\test\.cache\modelscope\models\nv-community--LocateAnything-3B\snapshots\master",
    device_map="auto",
    torch_dtype=torch.float16
)

# 2. 读取图片并自动等比缩放
orig_img = Image.open(IMAGE_PATH).convert("RGB")
ow, oh = orig_img.size
scale_ratio = min(MAX_SIZE / max(ow, oh), 1.0)
new_w = int(ow * scale_ratio)
new_h = int(oh * scale_ratio)
new_w = new_w if new_w % 2 == 0 else new_w + 1
new_h = new_h if new_h % 2 == 0 else new_h + 1

resized_img = orig_img.resize((new_w, new_h), Image.LANCZOS)
print(f"📐 原图 {ow}x{oh} → 缩放 {new_w}x{new_h}")

# 3. 执行检测(👈 打开SDK绘图)
result = model.detect(
    image=resized_img,
    categories=CATEGORIES, #提示词
    generation_mode="hybrid", #fast,slow,hybrid
    max_new_tokens=64, #越小,找的框就越少
    draw=True 
)

# 4. 保存SDK原始标注图(缩放图上的效果)
os.makedirs(SAVE_DIR, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")

if result.get("annotated_image") is not None:
    sdk_path = os.path.join(SAVE_DIR, f"sdk_overlay_{timestamp}.jpg")
    result["annotated_image"].save(sdk_path, quality=95)
    print(f"✅ SDK标注图已保存: {sdk_path}")

# 5. 解析原始输出,映射坐标到原图
raw = result.get("raw_output", "") or ""

# 先拆成每个 <ref> 段
segments = re.split(r"(?=<ref>)", raw)
raw_detections = []

for seg in segments:
    ref_m = re.search(r"<ref>(.*?)</ref>", seg)
    if not ref_m:
        continue
    label = ref_m.group(1)

    boxes = re.findall(
        r"<box><(\d+)><(\d+)><(\d+)><(\d+)></box>",
        seg,
    )
    for x1, y1, x2, y2 in boxes:
        coords = [int(x1), int(y1), int(x2), int(y2)]

        px_x1 = coords[0] / 1000.0 * new_w
        px_y1 = coords[1] / 1000.0 * new_h
        px_x2 = coords[2] / 1000.0 * new_w
        px_y2 = coords[3] / 1000.0 * new_h

        if px_x2 <= px_x1 or px_y2 <= px_y1:
            continue

        orig_x1 = int(px_x1 / scale_ratio)
        orig_y1 = int(px_y1 / scale_ratio)
        orig_x2 = int(px_x2 / scale_ratio)
        orig_y2 = int(px_y2 / scale_ratio)

        orig_x1 = max(0, min(orig_x1, ow - 1))
        orig_y1 = max(0, min(orig_y1, oh - 1))
        orig_x2 = max(0, min(orig_x2, ow - 1))
        orig_y2 = max(0, min(orig_y2, oh - 1))

        raw_detections.append({
            "label": label,
            "bbox": [orig_x1, orig_y1, orig_x2, orig_y2],
        })

print(f"📋 原始解析: {len(raw_detections)} 个框")
detections = raw_detections

# 6. 在原图上手动绘制并保存(最终结果)
if detections:
    draw_img = orig_img.copy()
    draw = ImageDraw.Draw(draw_img)
    for det in detections:
        x1, y1, x2, y2 = det["bbox"]
        draw.rectangle([x1, y1, x2, y2], outline="red", width=4)

    orig_path = os.path.join(SAVE_DIR, f"orig_overlay_{timestamp}.jpg")
    draw_img.save(orig_path, quality=95)
    print(f"✅ 原图标注已保存: {orig_path}")
else:
    print("⚠️ 未检测到目标")

print(f"📝 原始输出: {raw}")
  • 用原图3072*2048会OOM,要缩小到1024以下
  • 推理不要求是正方形的图形输入
  • 推理输出的结果是0-1000的归一化像素坐标,需要转换
  • max_new_tokens:32,64,128等等,越小找到的框就越少
相关推荐
浅浅的小草21 小时前
LabVIEW的G# framework简单使用记录
labview
LabVIEW开发2 天前
LabVIEW 3 人 15 个月做出镜片修复系统
labview·labview知识·labview功能·labview程序
LabVIEW开发2 天前
对撞机上的 500 台电机,被 LabVIEW 同步到 100 微秒
labview·labview知识·labview功能·labview程序
LabVIEW开发3 天前
LabVIEW 10 个月重做洗衣机高速不平衡检测
labview·labview知识·labview功能·labview程序
LabVIEW开发3 天前
Anritsu 2602A:频谱仪的几种测量怎么自动跑
运维·服务器·labview·labview知识·labview功能·labview程序
LabVIEW开发4 天前
Pfeiffer 真空泵接 LabVIEW:驱动装完才刚开始
labview·labview知识·labview功能·labview程序
LabVIEW开发5 天前
1362S 数字多用表:标准表怎么进自动校准流程
labview·labview知识·labview功能·labview程序
LabVIEW开发5 天前
FAST 的 2225 个促动器:上位机为什么选 LabVIEW
labview·labview知识·labview功能·labview程序
LabVIEW开发6 天前
LabVIEW 接 600 只麦克风:给客机噪声成像
labview·labview知识·labview功能·labview程序