在某些情况下,我们可能需要在 Node.js 项目中使用 OpenCV 进行图像匹配。但 OpenCV 在 Node.js 生态中支持较弱,Python 由于其丰富的计算机视觉库(如 OpenCV),更适合作为处理图像的后端。本文介绍如何使用 FastAPI 搭建 Python 微服务,并通过 Node.js 进行 HTTP 请求调用。


1. 搭建 Python FastAPI 微服务

安装依赖

首先,确保你的 Python 环境已安装 FastAPIUvicorn 和 OpenCV

pip install fastapi uvicorn opencv-python

编写 server.py(Python 服务器端)

import cv2
from fastapi import FastAPI

app = FastAPI()

@app.get("/find_image")
def find_image(imsrc_path: str, imobj_path: str, threshold: float = 0.9):
    imsrc = cv2.imread(imsrc_path)
    imobj = cv2.imread(imobj_path)

    if imsrc is None:
        return {"error": f"Source image not found at {imsrc_path}"}
    if imobj is None:
        return {"error": f"Object image not found at {imobj_path}"}

    result = cv2.matchTemplate(imsrc, imobj, cv2.TM_CCOEFF_NORMED)
    _, max_val, _, max_loc = cv2.minMaxLoc(result)

    if max_val > threshold:
        center_x = max_loc[0] + imobj.shape[1] // 2
        center_y = max_loc[1] + imobj.shape[0] // 2
        return {"centerX": center_x, "centerY": center_y, "similarity": max_val}

    return {"error": "No match found"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

运行 FastAPI 服务器

执行以下命令启动 Python 服务器:

python server.py

如果成功启动,终端会输出类似:

INFO:     Started server process [12345]
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

2. 在 Node.js 中调用 FastAPI

使用 http 内置模块(避免使用 axios)

如果你不想安装额外的库,可以使用 Node.js 自带的 http 模块进行请求:

const http = require("http");

const params = new URLSearchParams({
    imsrc_path: "/mnt/nas/share/download/node/test.png",
    imobj_path: "/mnt/nas/share/download/node/template.png"
});

const options = {
    hostname: "127.0.0.1",
    port: 8000,
    path: `/find_image?${params.toString()}`,
    method: "GET"
};

const req = http.request(options, (res) => {
    let data = "";
    
    res.on("data", (chunk) => {
        data += chunk;
    });

    res.on("end", () => {
        try {
            const jsonResponse = JSON.parse(data);
            console.log("Response:", jsonResponse);
        } catch (err) {
            console.error("Error parsing response:", err);
        }
    });
});

req.on("error", (err) => {
    console.error("Request error:", err);
});

req.end();

使用 axios 进行请求(如果可以使用第三方库)

如果你愿意使用 axios,它的代码会更简单:

const axios = require("axios");

axios.get("http://127.0.0.1:8000/find_image", {
    params: {
        imsrc_path: "/mnt/nas/share/download/node/test.png",
        imobj_path: "/mnt/nas/share/download/node/template.png"
    }
}).then(response => {
    console.log("Response:", response.data);
}).catch(error => {
    console.error("Error:", error.response ? error.response.data : error.message);
});

3. 为什么选择 Python 作为微服务?

Python 具有丰富的计算机视觉库,适合用于图像处理。相比之下,Node.js 更擅长并发处理,但不擅长计算密集型任务。将 OpenCV 代码放到 Python 服务器上,让 Node.js 通过 HTTP 调用,是一种高效的方式。

优点

✅ 提高性能:Python 进程不会反复启动,而是长时间运行。
✅ 支持大规模计算:可以并行处理多个请求。
✅ 模块化架构:Python 负责计算,Node.js 负责 API 交互。

缺点

❌ HTTP 传输开销:相比本地函数调用,HTTP 需要额外的传输时间。
❌ 额外部署 Python 服务器:需要确保 Python 进程始终运行。


4. 总结

  • 使用 Python + FastAPI 搭建 OpenCV 微服务,让 Node.js 通过 HTTP 访问。
  • FastAPI 轻量高效,适合构建小型 API。
  • Node.js 使用 http 或 axios 调用 Python API,两者结合处理图像任务。
  • 这种架构适用于需要计算密集型任务的场景,例如自动化测试、图片匹配等。

这种方法让 Node.js 和 Python 各自发挥所长,结合使用效果更佳!🚀