rein0421 commited on
Commit
0ec32fc
·
verified ·
1 Parent(s): 6034c78

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -100
app.py CHANGED
@@ -1,137 +1,124 @@
1
-
2
  import json
3
  import numpy as np
4
  from PIL import Image
5
  import subprocess
6
  import sys
7
-
8
  import logging
9
  import gradio as gr
10
  from typing import Tuple, Dict, Optional
11
- import gradio as gr
12
  import tempfile
 
 
 
13
 
14
- import json
15
- import numpy as np
16
- from PIL import Image
17
  def install(package):
18
  subprocess.check_call([sys.executable, "-m", "pip", "install", package])
19
 
20
- # OpenCVとGradioをインストール
21
- install("opencv-python")
22
  install("moondream")
23
  install("openai")
24
- from openai import OpenAI
25
- import cv2
26
- import moondream as md
27
  class PrivacyProtector:
28
  def __init__(self, moondream_api_key, deepseek_api_key):
29
- # Moondream初期化
30
  self.moon_model = md.vl(api_key=moondream_api_key)
31
-
32
- # DeepSeekクライアント初期化
33
  self.deepseek_client = OpenAI(
34
  api_key=deepseek_api_key,
35
  base_url="https://api.deepseek.com"
36
  )
37
-
38
  def analyze_risk(self, image_path):
39
  """画像のリスク分析を行う"""
40
- # 画像読み込みとエンコード
41
- pil_image = Image.open(image_path)
42
- cv_image = cv2.imread(image_path)
43
- encoded_image = self.moon_model.encode_image(pil_image)
44
-
45
- # 画像キャプション生成
46
- caption = self.moon_model.caption(encoded_image)["caption"]
47
- print(caption)
48
- # リスク分析プロンプト
49
- analysis_prompt = f"""
50
- 以下の画像説明を基に個人情報漏洩リスクを分析し、厳密にJSON形式で返答してください:
51
- {{
52
- "risk_level": "high|medium|low",
53
- "risk_reason": "リスクの具体的理由",
54
- "objects_to_remove": ["消去すべきオブジェクトリスト"]
55
- }}
56
-
57
- 画像説明: {caption}
58
- """
59
-
60
- # DeepSeek API呼び出し
61
- response = self.deepseek_client.chat.completions.create(
62
- model="deepseek-chat",
63
- messages=[
64
- {"role": "system", "content": "あなたは優秀なセキュリティ分析AIです。"},
65
- {"role": "user", "content": analysis_prompt}
66
- ],
67
- temperature=0.3,
68
- response_format={"type": "json_object"}
69
- )
70
-
71
- # 結果パース
72
- result = json.loads(response.choices[0].message.content)
73
- return pil_image, cv_image, result
74
-
 
 
75
  def remove_objects(self, pil_image, cv_image, objects_to_remove):
76
  """オブジェクト検出と消去処理"""
77
- # マスク作成
78
- mask = np.zeros(cv_image.shape[:2], dtype=np.uint8)
79
- h, w = cv_image.shape[:2]
80
-
81
- for obj_name in objects_to_remove:
82
- # オブジェクト検出
83
- detection = self.moon_model.detect(pil_image, obj_name)
84
- print(detection)
85
- for obj in detection["objects"]:
86
- # 正規化座標→絶対座標変換
87
- x_min = int(obj['x_min'] * w)
88
- y_min = int(obj['y_min'] * h)
89
- x_max = int(obj['x_max'] * w)
90
- y_max = int(obj['y_max'] * h)
91
-
92
- # マスク領域を矩形で追加
93
- cv2.rectangle(mask, (x_min, y_min), (x_max, y_max), 255, -1)
94
-
95
- # インペイント処理
96
- inpainted = cv2.inpaint(cv_image, mask, 3, cv2.INPAINT_TELEA)
97
- return inpainted
98
-
99
- def process_image(self, image_path, output_path):
100
  """画像処理フロー全体"""
101
- pil_img, cv_img, result = self.analyze_risk(image_path)
102
- print(f"リスクレベル: {result['risk_level']}")
103
- print(f"理由: {result['risk_reason']}")
104
-
105
- if result['risk_level'] != 'low':
106
- print( result['objects_to_remove'])
107
- cleaned = self.remove_objects(pil_img, cv_img, result['objects_to_remove'])
108
- cv2.imwrite(output_path, cleaned)
109
- print(f"処理済み画像を保存: {output_path}")
110
- return True
111
- print("リスク対象なし")
112
- return False
113
 
114
  def gradio_process(input_image):
115
- with tempfile.NamedTemporaryFile(suffix=".jpg") as tmp_file:
116
- input_path = tmp_file.name
117
- output_path = "/content/output.jpg"
118
-
119
- cv2.imwrite(input_path, cv2.cvtColor(input_image, cv2.COLOR_RGB2BGR))
120
 
121
  protector = PrivacyProtector(
122
- moondream_api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXlfaWQiOiI4NmI0NTUxMi01NWZlLTQ0YzItYTA2Ni1hMTE1NDBlM2EzZTMiLCJpYXQiOjE3Mzc4NTMzMzJ9.8dc3xo_z7nYApJwaOCI2ayYX9pTKpo8QHkoH96ykEcg",
123
- deepseek_api_key="sk-61418a466189492c916ec7bcc873b142"
124
  )
125
 
 
 
126
 
127
- # 分析結果を含めて取得
128
- pil_img, cv_img, result = protector.analyze_risk(input_path)
129
- processed = protector.process_image(input_path, output_path)
130
-
131
- # 出力画像
132
- output = cv2.cvtColor(cv2.imread(output_path), cv2.COLOR_BGR2RGB) if processed else None
133
 
134
- # 表示用情報の整形
135
  info_html = f"""
136
  <div style="padding:20px; background:#f0f0f0; border-radius:10px;">
137
  <h3>分析結果</h3>
@@ -142,7 +129,17 @@ def gradio_process(input_image):
142
  </div>
143
  """
144
 
145
- return input_image, output, info_html
 
 
 
 
 
 
 
 
 
 
146
 
147
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
148
  gr.Markdown("# 🛡️ プライバシー保護画像処理ツール")
 
 
1
  import json
2
  import numpy as np
3
  from PIL import Image
4
  import subprocess
5
  import sys
 
6
  import logging
7
  import gradio as gr
8
  from typing import Tuple, Dict, Optional
 
9
  import tempfile
10
+ import cv2
11
+ import moondream as md
12
+ from openai import OpenAI
13
 
 
 
 
14
  def install(package):
15
  subprocess.check_call([sys.executable, "-m", "pip", "install", package])
16
 
17
+ # 依存関係のインストール
18
+ install("opencv-python-headless")
19
  install("moondream")
20
  install("openai")
21
+
 
 
22
  class PrivacyProtector:
23
  def __init__(self, moondream_api_key, deepseek_api_key):
 
24
  self.moon_model = md.vl(api_key=moondream_api_key)
 
 
25
  self.deepseek_client = OpenAI(
26
  api_key=deepseek_api_key,
27
  base_url="https://api.deepseek.com"
28
  )
29
+
30
  def analyze_risk(self, image_path):
31
  """画像のリスク分析を行う"""
32
+ try:
33
+ pil_image = Image.open(image_path)
34
+ cv_image = cv2.imread(image_path)
35
+ if cv_image is None:
36
+ raise ValueError("画像の読み込みに失敗しました")
37
+
38
+ encoded_image = self.moon_model.encode_image(pil_image)
39
+ caption = self.moon_model.caption(encoded_image)["caption"]
40
+
41
+ analysis_prompt = f"""
42
+ 以下の画像説明を基に個人情報漏洩リスクを分析し、厳密にJSON形式で返答してください:
43
+ {{
44
+ "risk_level": "high|medium|low",
45
+ "risk_reason": "リスクの具体的理由",
46
+ "objects_to_remove": ["消去すべきオブジェクトリスト"]
47
+ }}
48
+
49
+ 画像説明: {caption}
50
+ """
51
+
52
+ response = self.deepseek_client.chat.completions.create(
53
+ model="deepseek-chat",
54
+ messages=[
55
+ {"role": "system", "content": "あなたは優秀なセキュリティ分析AIです。"},
56
+ {"role": "user", "content": analysis_prompt}
57
+ ],
58
+ temperature=0.3,
59
+ response_format={"type": "json_object"}
60
+ )
61
+
62
+ result = json.loads(response.choices[0].message.content)
63
+ return pil_image, cv_image, result
64
+
65
+ except Exception as e:
66
+ logging.error(f"リスク分析エラー: {str(e)}")
67
+ raise
68
+
69
  def remove_objects(self, pil_image, cv_image, objects_to_remove):
70
  """オブジェクト検出と消去処理"""
71
+ try:
72
+ mask = np.zeros(cv_image.shape[:2], dtype=np.uint8)
73
+ h, w = cv_image.shape[:2]
74
+
75
+ for obj_name in objects_to_remove:
76
+ detection = self.moon_model.detect(pil_image, obj_name)
77
+ for obj in detection["objects"]:
78
+ x_min = int(obj['x_min'] * w)
79
+ y_min = int(obj['y_min'] * h)
80
+ x_max = int(obj['x_max'] * w)
81
+ y_max = int(obj['y_max'] * h)
82
+ cv2.rectangle(mask, (x_min, y_min), (x_max, y_max), 255, -1)
83
+
84
+ inpainted = cv2.inpaint(cv_image, mask, 3, cv2.INPAINT_TELEA)
85
+ return inpainted
86
+
87
+ except Exception as e:
88
+ logging.error(f"オブジェクト削除エラー: {str(e)}")
89
+ raise
90
+
91
+ def process_image(self, image_path):
 
 
92
  """画像処理フロー全体"""
93
+ try:
94
+ pil_img, cv_img, result = self.analyze_risk(image_path)
95
+ if result['risk_level'] != 'low':
96
+ cleaned = self.remove_objects(pil_img, cv_img, result['objects_to_remove'])
97
+ return cleaned, result
98
+ return cv_img, result
99
+
100
+ except Exception as e:
101
+ logging.error(f"画像処理エラー: {str(e)}")
102
+ raise
 
 
103
 
104
  def gradio_process(input_image):
105
+ try:
106
+ # 一時ファイルの処理
107
+ with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tmp_file:
108
+ input_path = tmp_file.name
109
+ cv2.imwrite(input_path, cv2.cvtColor(input_image, cv2.COLOR_RGB2BGR))
110
 
111
  protector = PrivacyProtector(
112
+ moondream_api_key="your_moondream_key",
113
+ deepseek_api_key="your_deepseek_key"
114
  )
115
 
116
+ # 画像処理実行
117
+ processed_image, result = protector.process_image(input_path)
118
 
119
+ # 結果の整形
120
+ output_image = cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB)
 
 
 
 
121
 
 
122
  info_html = f"""
123
  <div style="padding:20px; background:#f0f0f0; border-radius:10px;">
124
  <h3>分析結果</h3>
 
129
  </div>
130
  """
131
 
132
+ return input_image, output_image, info_html
133
+
134
+ except Exception as e:
135
+ error_msg = f"処理中にエラーが発生しました: {str(e)}"
136
+ return input_image, None, f'<div style="color:red;">{error_msg}</div>'
137
+
138
+ finally:
139
+ # 一時ファイルのクリーンアップ
140
+ if 'input_path' in locals():
141
+ import os
142
+ os.remove(input_path)
143
 
144
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
145
  gr.Markdown("# 🛡️ プライバシー保護画像処理ツール")