HumansXドキュメントセンター 公式サイトへ ↗

関数呼び出しによる視覚言語モデル(VLM)を用いた画像解析

実験の目的

  1. VLM(Vision Language Model、視覚言語モデル)に基づき、画像理解と視覚解析を実現します。

応用シーン

VLM 視覚言語モデルシステムは、画像理解や視覚解析を必要とするインテリジェントな応用シーンに適しており、画像のインテリジェントな説明、物体検出、視覚的質問応答、文字認識の各機能を実現します。

主にインテリジェントロボットシステムにおける視覚認識タスクに用いられ、自然言語の指示によって画像内容を解析したり、物体の位置を検出したり、画像に関する質問に答えたり、テキスト情報を抽出したりします。インテリジェント監視、ビジュアルナビゲーション、文書処理、教育支援など、コンピュータビジョン機能を必要とするさまざまな用途に適しています。

機能要件

画像に対して、インテリジェントな画像説明、物体検出、視覚的質問応答、文字認識の各機能を実現します。たとえば猫の画像をアップロードすると、その画像が伝えようとしている情報を解析して出力します。

  1. 画像解析機能:画像内容の詳細な説明と理解を提供します
  2. 物体検出機能:画像内の物体を検出し、座標情報を提供します
  3. 視覚的質問応答機能:画像内容に関する具体的な質問に回答します
  4. 文字認識機能:画像からテキスト内容を抽出します

ハードウェアの準備

ディスプレイ * 1、Bluetooth キーボード・マウス * 1、メインコンソール * 1

​

回路接続

ハードウェアモジュール

ヒント:ハードウェアモジュールの使用説明

ハードウェアシステムの全体組み立て

組み込み AI 開発ボード RDK_X5

Uni mega2560 拡張ボード【V1.1】使用説明

電子モジュールの紹介

物理配線

具体的な配線・取り付け方法については、ハードウェアシステムの全体組み立てを参照してください。

ソフトウェア設計

設計フローチャート

VLM インターフェースのフロー

VLM の実装プロセス

ソースコードのダウンロード

ソースコードのリンク:(HumansX サポートより提供)

プログラムコード

コードの構成:

フォルダ コード 機能
function_call vlm_functions.py LLM に視覚言語モデルの標準化された呼び出しインターフェースを提供し、画像解析・物体検出・視覚的質問応答・文字認識の 4 つのコア機能をサポートします。
vlm ​ 画像を解析するインターフェースを実装します
_init.py 公開インターフェースを定義し、コアクラスとツール関数をエクスポートします
image_utils.py 画像の検証、形式変換、データ処理の機能を提供します
vlm_client.py 画像解析・物体検出・視覚的質問応答・文字認識の 4 つのコア機能を提供します

具体的なコード:

プロジェクトの完全なコードは(ソースコードのリンク)からダウンロードしてください。

"""
VLM (Vision Language Model) 功能实现
提供图像理解和视觉分析的function-calling功能
"""

import base64
import logging
import os
import tempfile
from typing import Optional, Dict, Any
from pathlib import Path

from .function_registry import FunctionRegistry
from ..vlm.vlm_client import VLMClient
from ..vlm.image_utils import validate_image_data, convert_image_to_base64
from config.config_manager import get_config

logger = logging.getLogger(__name__)

# 全局VLM客户端实例
_vlm_client: Optional[VLMClient] = None

def initialize_vlm_client():
    """初始化VLM客户端"""
    global _vlm_client

    config = get_config()
    if not config.vlm.enabled:
        logger.info("VLM功能未启用")
        return

    if not config.vlm.api_key:
        logger.warning("VLM API密钥未配置,请在.env文件中设置SILICONFLOW_API_KEY")
        return

    try:
        _vlm_client = VLMClient(
            api_key=config.vlm.api_key,
            api_url=config.vlm.api_url,
            model_name=config.vlm.model_name,
            timeout=config.vlm.timeout
        )
        logger.info("VLM客户端初始化成功")
    except Exception as e:
        logger.error(f"VLM客户端初始化失败: {e}")
        _vlm_client = None

def get_vlm_client() -> Optional[VLMClient]:
    """获取VLM客户端实例"""
    return _vlm_client

@FunctionRegistry.register_function(
    'vlm_analyze_image',
    '分析图像内容,提供详细的图像描述和理解'
)
async def analyze_image(image_base64: str, prompt: str = "请详细描述这张图片的内容") -> Dict[str, Any]:
    """
    分析图像内容,提供详细的图像描述和理解

    Args:
        image_base64 (str): 图像的base64编码字符串
        prompt (str): 分析提示词,默认为"请详细描述这张图片的内容"

    Returns:
        Dict[str, Any]: 包含分析结果的字典
            - success (bool): 是否成功
            - description (str): 图像描述
            - details (dict): 详细分析结果
    """
    if not _vlm_client:
        return {
            "success": False,
            "error": "VLM客户端未初始化或配置不正确"
        }

    try:
        # 验证图像数据
        is_valid, error_msg = validate_image_data(image_base64)
        if not is_valid:
            return {
                "success": False,
                "error": f"图像数据验证失败: {error_msg}"
            }

        # 验证base64字符串
        if not image_base64.startswith('data:image/'):
            # 如果不是完整的data URL,尝试添加默认的PNG头部
            if not image_base64.startswith('iVBORw0KGgo') and not image_base64.startswith('/9j/'):
                image_base64 = f"data:image/png;base64,{image_base64}"

        result = await _vlm_client.analyze_image(image_base64, prompt)
        return {
            "success": True,
            "description": result.get("response", "未获得有效响应"),
            "details": result
        }
    except Exception as e:
        logger.error(f"图像分析失败: {e}")
        return {
            "success": False,
            "error": f"图像分析失败: {str(e)}"
        }

@FunctionRegistry.register_function(
    'vlm_detect_objects',
    '检测图像中的物体并提供边界框坐标'
)
async def detect_objects(image_base64: str, prompt: str = "请检测图像中的物体并提供边界框坐标") -> Dict[str, Any]:
    """
    检测图像中的物体并提供边界框坐标

    Args:
        image_base64 (str): 图像的base64编码字符串
        prompt (str): 检测提示词,默认为"请检测图像中的物体并提供边界框坐标"

    Returns:
        Dict[str, Any]: 包含检测结果的字典
            - success (bool): 是否成功
            - objects (list): 检测到的物体列表
            - coordinates (list): 边界框坐标列表
    """
    if not _vlm_client:
        return {
            "success": False,
            "error": "VLM客户端未初始化或配置不正确"
        }

    try:
        # 验证图像数据
        is_valid, error_msg = validate_image_data(image_base64)
        if not is_valid:
            return {
                "success": False,
                "error": f"图像数据验证失败: {error_msg}"
            }

        # 验证base64字符串
        if not image_base64.startswith('data:image/'):
            # 如果不是完整的data URL,尝试添加默认的PNG头部
            if not image_base64.startswith('iVBORw0KGgo') and not image_base64.startswith('/9j/'):
                image_base64 = f"data:image/png;base64,{image_base64}"

        result = await _vlm_client.detect_objects(image_base64, prompt)
        return {
            "success": True,
            "objects": result.get("objects", []),
            "coordinates": result.get("coordinates", []),
            "details": result
        }
    except Exception as e:
        logger.error(f"物体检测失败: {e}")
        return {
            "success": False,
            "error": f"物体检测失败: {str(e)}"
        }

@FunctionRegistry.register_function(
    'vlm_answer_visual_question',
    '回答关于图像内容的具体问题'
)
async def answer_visual_question(image_base64: str, question: str) -> Dict[str, Any]:
    """
    回答关于图像内容的具体问题

    Args:
        image_base64 (str): 图像的base64编码字符串
        question (str): 关于图像的问题

    Returns:
        Dict[str, Any]: 包含回答结果的字典
            - success (bool): 是否成功
            - answer (str): 问题的答案
    """
    if not _vlm_client:
        return {
            "success": False,
            "error": "VLM客户端未初始化或配置不正确"
        }

    try:
        # 验证图像数据
        is_valid, error_msg = validate_image_data(image_base64)
        if not is_valid:
            return {
                "success": False,
                "error": f"图像数据验证失败: {error_msg}"
            }

        # 验证base64字符串
        if not image_base64.startswith('data:image/'):
            # 如果不是完整的data URL,尝试添加默认的PNG头部
            if not image_base64.startswith('iVBORw0KGgo') and not image_base64.startswith('/9j/'):
                image_base64 = f"data:image/png;base64,{image_base64}"

        result = await _vlm_client.answer_question(image_base64, question)
        return {
            "success": True,
            "answer": result.get("response", "未获得有效响应"),
            "details": result
        }
    except Exception as e:
        logger.error(f"视觉问答失败: {e}")
        return {
            "success": False,
            "error": f"视觉问答失败: {str(e)}"
        }

@FunctionRegistry.register_function(
    'vlm_read_text',
    '识别并提取图像中的文字内容'
)
async def read_text(image_base64: str) -> Dict[str, Any]:
    """
    识别并提取图像中的文字内容

    Args:
        image_base64 (str): 图像的base64编码字符串

    Returns:
        Dict[str, Any]: 包含文字识别结果的字典
            - success (bool): 是否成功
            - text (str): 识别出的文字内容
    """
    if not _vlm_client:
        return {
            "success": False,
            "error": "VLM客户端未初始化或配置不正确"
        }

    try:
        # 验证图像数据
        is_valid, error_msg = validate_image_data(image_base64)
        if not is_valid:
            return {
                "success": False,
                "error": f"图像数据验证失败: {error_msg}"
            }

        # 验证base64字符串
        if not image_base64.startswith('data:image/'):
            # 如果不是完整的data URL,尝试添加默认的PNG头部
            if not image_base64.startswith('iVBORw0KGgo') and not image_base64.startswith('/9j/'):
                image_base64 = f"data:image/png;base64,{image_base64}"

        result = await _vlm_client.read_text(image_base64)
        return {
            "success": True,
            "text": result.get("response", "未获得有效响应"),
            "details": result
        }
    except Exception as e:
        logger.error(f"文字识别失败: {e}")
        return {
            "success": False,
            "error": f"文字识别失败: {str(e)}"
        }

操作手順

回路接続が完了したら:

  1. ターミナルからリモートアクセスします。ターミナルで次のコマンドを入力し、Enter キーを押します。

ssh sunrise@192.168.8.111

  1. サービスを起動します。llm フォルダに移動し、メインプログラム python main.py を起動します。

Enter キーを押して起動を待ちます。次の画面が表示されたら、http:// 0.0.0.0:8002 を開けることを示しています。

  1. ブラウザを開き、URL http:// 0.0.0.0:8002 を入力してアクセスします。起動すると LLM インテリジェント対話アシスタントのメイン画面が表示されます。

  1. 「画像解析」をクリックして解析結果を確認します。たとえば猫の画像をアップロードして、解析結果を確認します。

​

実験結果

アップロードした画像に対して画像理解と視覚解析を行い、結果を表示します。

サポート窓口

資料のダウンロード・技術サポートについては、HumansX株式会社までお問い合わせください。