File size: 4,432 Bytes
39eb9cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5380ab
39eb9cb
 
 
 
 
 
 
 
 
 
a5380ab
b38dc26
39eb9cb
 
b38dc26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39eb9cb
 
 
 
 
 
 
 
a5380ab
39eb9cb
 
 
 
 
 
 
 
a5380ab
 
39eb9cb
a5380ab
39eb9cb
 
 
 
 
a5380ab
 
 
 
 
 
39eb9cb
a5380ab
 
 
 
39eb9cb
a5380ab
 
39eb9cb
 
 
 
 
 
 
 
a5380ab
39eb9cb
 
a5380ab
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import gradio as gr
import openai
import base64
import pandas as pd
import uuid
import io
import os

def analyze_image(image_path, api_key):
    """
    画像を読み込み、base64エンコードした上で
    指定したOpenAI API (gpt-4o-mini) に投げてCSVを取得し、
    テーブル表示用データとダウンロード用ファイルを返す
    """

    # 画像またはAPIキーが未入力の場合はメッセージを返す
    if not image_path:
        return "画像をアップロードしてください。", None
    if not api_key:
        return "API Key を入力してください。", None

    # 画像をbase64に変換
    with open(image_path, "rb") as f:
        image_data = f.read()
    image_base64 = base64.b64encode(image_data).decode("utf-8")

    # UUIDはOpenAI側に生成を指示してもよいですが、こちらで生成してもOKです。
    # ここではOpenAIに完全に任せるため、プロンプトで生成を依頼する例とします。
    # 必要に応じてこちらで生成した UUID を挿入することも可能です。
    
    # ChatGPT(gpt-4o-mini)に送るユーザープロンプト
    user_prompt = f"""
以下の画像に写っている各部位の計測値(首、肩、二の腕L、二の腕R、胸、ウエスト、ヒップ、太腿L、太腿R、ふくらはぎL、ふくらはぎR)を読み取り、
次のCSVフォーマットで出力してください。なお、CSVの1行目には列名を、2行目には画像から抽出した数値を入れてください。
左端のID列には自動生成したUUIDを記載してください。
出力には余計な説明文を加えず、CSVテキストのみとせよ。

- CSVフォーマット例:
ID,首,肩,二の腕L,二の腕R,胸,ウエスト,ヒップ,太腿L,太腿R,ふくらはぎL,ふくらはぎR
<自動生成UUID>,<首の数値>,<肩の数値>,<二の腕L>,<二の腕R>,<胸>,<ウエスト>,<ヒップ>,<太腿L>,<太腿R>,<ふくらはぎL>,<ふくらはぎR>

もし画像から読み取れない数値があれば空欄や"N/A"としてください。
"""

    try:
        # OpenAI API呼び出し
        client = openai.OpenAI(api_key=api_key)
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": user_prompt,
                        },
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/png;base64,{image_base64}",
                            }
                        },
                    ]
                }
            ],
            temperature=0.0
        )
    except Exception as e:
        return f"API呼び出しエラー: {str(e)}", None

    # APIの応答(CSVテキスト想定)
    csv_text = response.choices[0].message.content.strip()
    csv_text = csv_text.replace('```', '')

    # pandasでテーブルに変換を試みる
    try:
        df = pd.read_csv(io.StringIO(csv_text))
    except Exception as e:
        # CSVとしてパースできなければテキストのみ返す
        return f"CSVとして解析できませんでした。応答内容:\n{csv_text}", None

    # CSVをtemp.csvに出力する
    df.to_csv('temp.csv', index=False)

    return df, 'temp.csv'

# Gradioアプリの定義
with gr.Blocks() as demo:
    gr.Markdown("# 画像から数値を読み取り、CSVを生成するデモアプリ")

    api_key_input = gr.Textbox(
        label="OpenAI API Key",
        placeholder="sk-...",
        type="password",
        show_label=True
    )

    image_input = gr.Image(
        label="画像アップロード",
        type="filepath"
    )

    generate_button = gr.Button("CSV生成", variant="primary")
    download_button = gr.DownloadButton("CSVダウンロード")

    # 出力は DataFrame と File (ダウンロード用)
    output_table = gr.DataFrame(label="CSVプレビュー")

    # ボタンクリック時の動作
    generate_button.click(
        fn=analyze_image,
        inputs=[image_input, api_key_input],
        outputs=[output_table, download_button]
    )

if __name__ == "__main__":
    demo.launch()