Spaces:
Runtime error
Runtime error
syurein
commited on
Commit
·
45c8412
1
Parent(s):
855ced2
dotenvの問題の解決
Browse files- LLM_package.py +21 -3
- app.py +129 -9
- requirements.txt +1 -1
LLM_package.py
CHANGED
|
@@ -122,11 +122,11 @@ class ObjectDetector:
|
|
| 122 |
"""
|
| 123 |
Detects the danger level of the image.
|
| 124 |
"""
|
| 125 |
-
def
|
| 126 |
analysis_prompt = f"""
|
| 127 |
画像の個人情報漏洩リスクを分析し、厳密にJSON形式で返答してください。なおこの時、資料があれば、資料を参考にしてください:
|
| 128 |
{{
|
| 129 |
-
"risk_level":
|
| 130 |
"risk_reason": "リスクの具体的理由",
|
| 131 |
"objects_to_remove": ["消去すべきオブジェクトリスト(英語で、例: 'face', 'license_plate')"]
|
| 132 |
}}
|
|
@@ -137,4 +137,22 @@ class ObjectDetector:
|
|
| 137 |
|
| 138 |
response = self.model.parse(self.model.get_response(image_path, analysis_prompt))
|
| 139 |
print(f"Response: {response}")
|
| 140 |
-
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
"""
|
| 123 |
Detects the danger level of the image.
|
| 124 |
"""
|
| 125 |
+
def detect_auto(self, image_path):
|
| 126 |
analysis_prompt = f"""
|
| 127 |
画像の個人情報漏洩リスクを分析し、厳密にJSON形式で返答してください。なおこの時、資料があれば、資料を参考にしてください:
|
| 128 |
{{
|
| 129 |
+
"risk_level":0~100,
|
| 130 |
"risk_reason": "リスクの具体的理由",
|
| 131 |
"objects_to_remove": ["消去すべきオブジェクトリスト(英語で、例: 'face', 'license_plate')"]
|
| 132 |
}}
|
|
|
|
| 137 |
|
| 138 |
response = self.model.parse(self.model.get_response(image_path, analysis_prompt))
|
| 139 |
print(f"Response: {response}")
|
| 140 |
+
return response
|
| 141 |
+
def detect_danger_level(self, image_path):
|
| 142 |
+
analysis_prompt = f"""
|
| 143 |
+
画像の個人情報漏洩リスクを分析し、厳密にJSON形式で返答してください。なおこの時、資料があれば、資料を参考にしてください:
|
| 144 |
+
{{
|
| 145 |
+
"risk_level": 0~100,
|
| 146 |
+
}}
|
| 147 |
+
<資料>
|
| 148 |
+
{self.text if self.text else "なし"}
|
| 149 |
+
</資料>
|
| 150 |
+
"""
|
| 151 |
+
response = self.model.parse(self.model.get_response(image_path, analysis_prompt))
|
| 152 |
+
|
| 153 |
+
print(f"Response: {response}")
|
| 154 |
+
try:
|
| 155 |
+
risk_level = int(response.get('risk_level', 0))
|
| 156 |
+
except ValueError:
|
| 157 |
+
risk_level = 0
|
| 158 |
+
return risk_level
|
app.py
CHANGED
|
@@ -259,6 +259,58 @@ def llm_to_process_image_simple(risk_level, image_path, point1, point2, threshol
|
|
| 259 |
debug_image_pil.save(save_dir + debug_image_path)
|
| 260 |
return save_dir + debug_image_path
|
| 261 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
|
| 263 |
|
| 264 |
|
|
@@ -642,10 +694,6 @@ async def create_mask_and_inpaint_simple_lama(image: UploadFile = File(...), ris
|
|
| 642 |
return FileResponse(output_path)
|
| 643 |
|
| 644 |
|
| 645 |
-
#下のendpointは特定領域をマスクしないタイプのもの
|
| 646 |
-
|
| 647 |
-
|
| 648 |
-
#下記はDeepFillv2
|
| 649 |
|
| 650 |
|
| 651 |
|
|
@@ -775,7 +823,11 @@ async def classify_image(file: UploadFile = File(...)):
|
|
| 775 |
new_image_cluster = classify_new_image(new_image_vector, sums_data, loaded_vectors, loaded_object_names)
|
| 776 |
|
| 777 |
return {"danger":dangerarray[int(new_image_cluster + 1)]}#バグったらここを+にして
|
| 778 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 779 |
|
| 780 |
@app.post("/create-mask-and-inpaint-simple-lama-special")
|
| 781 |
async def create_mask_and_inpaint_simple_lama(
|
|
@@ -875,8 +927,34 @@ async def mosaic_face(file: UploadFile = File(...)):
|
|
| 875 |
|
| 876 |
|
| 877 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 878 |
@app.post("/create-mask-and-inpaint-sum-llm-simple")
|
| 879 |
-
async def
|
| 880 |
x1: float = Form(...),
|
| 881 |
y1: float = Form(...),
|
| 882 |
x2: float = Form(...),
|
|
@@ -900,8 +978,50 @@ async def create_mask_sum(image: UploadFile = File(...), risk_level: int = Form(
|
|
| 900 |
|
| 901 |
return FileResponse(output_path)
|
| 902 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 903 |
# カスケードファイルの読み込み (顔検出)
|
| 904 |
-
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
| 905 |
|
| 906 |
def apply_mosaic(image, x, y, w, h, mosaic_level=15):
|
| 907 |
""" 指定範囲にモザイク処理を適用 """
|
|
@@ -910,7 +1030,7 @@ def apply_mosaic(image, x, y, w, h, mosaic_level=15):
|
|
| 910 |
face = cv2.resize(face, (w, h), interpolation=cv2.INTER_NEAREST)
|
| 911 |
image[y:y+h, x:x+w] = face
|
| 912 |
return image
|
| 913 |
-
|
| 914 |
@app.post("/mosaic_face")
|
| 915 |
async def mosaic_face(file: UploadFile = File(...)):
|
| 916 |
# 画像ファイルを読み込み
|
|
@@ -934,7 +1054,7 @@ async def mosaic_face(file: UploadFile = File(...)):
|
|
| 934 |
# 一時ファイルをレスポンスとして返す
|
| 935 |
return FileResponse(path=temp_file_path, media_type="image/jpeg", filename="mosaic_image.jpg")
|
| 936 |
|
| 937 |
-
|
| 938 |
|
| 939 |
|
| 940 |
|
|
|
|
| 259 |
debug_image_pil.save(save_dir + debug_image_path)
|
| 260 |
return save_dir + debug_image_path
|
| 261 |
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
def llm_to_process_image_simple_auto(risk_level, image_path, point1, point2, thresholds=None):
|
| 265 |
+
print(risk_level, image_path, point1, point2, thresholds)
|
| 266 |
+
print('point1,point2', point1, point2)
|
| 267 |
+
GEMINI_API_KEY=os.getenv('GEMINI_API_KEY')
|
| 268 |
+
# 画像処理のロジックをここに追加
|
| 269 |
+
Objectdetector = ObjectDetector(API_KEY=GEMINI_API_KEY)
|
| 270 |
+
debug_image_path='/test_llm.jpg'
|
| 271 |
+
response=Objectdetector.detect_auto(image_path)
|
| 272 |
+
Objectdetector.prompt_objects=response["objects_to_remove"]
|
| 273 |
+
# 画像の読み込みとRGB変換
|
| 274 |
+
|
| 275 |
+
image = cv2.imread(image_path)
|
| 276 |
+
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
| 277 |
+
mask_llm = np.zeros(image.shape[:2], dtype=np.uint8)
|
| 278 |
+
llm_results = Objectdetector.detect_objects(image_path)
|
| 279 |
+
for result in llm_results:
|
| 280 |
+
bbox=result['box_2d']
|
| 281 |
+
x1, y1 = int(bbox[1]* image.shape[1]), int(bbox[0]* image.shape[0])
|
| 282 |
+
x2, y2 = int(bbox[3]* image.shape[1]), int(bbox[2]* image.shape[0])
|
| 283 |
+
mask_llm[y1:y2, x1:x2] = 255 # テキスト領域をマスク
|
| 284 |
+
p1_x, p1_y = int(point1[0] * image.shape[1]), int(point1[1] * image.shape[0])
|
| 285 |
+
p2_x, p2_y = int(point2[0] * image.shape[1]), int(point2[1] * image.shape[0])
|
| 286 |
+
x_min, y_min = max(0, min(p1_x, p2_x)), max(0, min(p1_y, p2_y))
|
| 287 |
+
x_max, y_max = min(image.shape[1], max(p1_x, p2_x)), min(image.shape[0], max(p1_y, p2_y))
|
| 288 |
+
mask_llm[y_min:y_max, x_min:x_max] = 0 # 範囲を黒に設定
|
| 289 |
+
save_dir = "./saved_images"
|
| 290 |
+
os.makedirs(save_dir, exist_ok=True)
|
| 291 |
+
debug_image_pil = Image.fromarray(mask_llm)
|
| 292 |
+
debug_image_pil.save(save_dir + debug_image_path)
|
| 293 |
+
return save_dir + debug_image_path,response
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
|
| 305 |
+
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
|
| 314 |
|
| 315 |
|
| 316 |
|
|
|
|
| 694 |
return FileResponse(output_path)
|
| 695 |
|
| 696 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 697 |
|
| 698 |
|
| 699 |
|
|
|
|
| 823 |
new_image_cluster = classify_new_image(new_image_vector, sums_data, loaded_vectors, loaded_object_names)
|
| 824 |
|
| 825 |
return {"danger":dangerarray[int(new_image_cluster + 1)]}#バグったらここを+にして
|
| 826 |
+
|
| 827 |
+
|
| 828 |
+
|
| 829 |
+
|
| 830 |
+
|
| 831 |
|
| 832 |
@app.post("/create-mask-and-inpaint-simple-lama-special")
|
| 833 |
async def create_mask_and_inpaint_simple_lama(
|
|
|
|
| 927 |
|
| 928 |
|
| 929 |
|
| 930 |
+
|
| 931 |
+
|
| 932 |
+
|
| 933 |
+
|
| 934 |
+
|
| 935 |
+
|
| 936 |
+
|
| 937 |
+
|
| 938 |
+
#こっからLLM
|
| 939 |
+
|
| 940 |
+
|
| 941 |
+
|
| 942 |
+
# LLMを使用して画像を分類するエンドポイント
|
| 943 |
+
@app.post("/classify-image-llm/")
|
| 944 |
+
async def classify_image_llm(file: UploadFile = File(...)):
|
| 945 |
+
image_path = "./temp_image.jpg"
|
| 946 |
+
# アップロードされた画像を保存
|
| 947 |
+
with open(image_path, "wb") as buffer:
|
| 948 |
+
buffer.write(await file.read())
|
| 949 |
+
danger_level = ObjectDetector().detect_danger_level(image_path)
|
| 950 |
+
return {"danger":danger_level}
|
| 951 |
+
|
| 952 |
+
|
| 953 |
+
|
| 954 |
+
|
| 955 |
+
|
| 956 |
@app.post("/create-mask-and-inpaint-sum-llm-simple")
|
| 957 |
+
async def create_mask_sum2(image: UploadFile = File(...), risk_level: int = Form(...),
|
| 958 |
x1: float = Form(...),
|
| 959 |
y1: float = Form(...),
|
| 960 |
x2: float = Form(...),
|
|
|
|
| 978 |
|
| 979 |
return FileResponse(output_path)
|
| 980 |
|
| 981 |
+
|
| 982 |
+
#三浦と相談
|
| 983 |
+
|
| 984 |
+
@app.post("/create-mask-and-inpaint-sum-llm-auto")
|
| 985 |
+
async def create_mask_sum_auto(image: UploadFile = File(...), risk_level: int = Form(...),x1: float = Form(...),
|
| 986 |
+
y1: float = Form(...),
|
| 987 |
+
x2: float = Form(...),
|
| 988 |
+
y2: float = Form(...)):
|
| 989 |
+
default_x = 0.001
|
| 990 |
+
default_y = 0.001
|
| 991 |
+
|
| 992 |
+
|
| 993 |
+
point1 = [default_x if math.isnan(x1) else x1, default_y if math.isnan(y1) else y1]
|
| 994 |
+
|
| 995 |
+
point2 = [default_x if math.isnan(x2) else x2, default_y if math.isnan(y2) else y2]
|
| 996 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 997 |
+
# 一意な識別子を生成
|
| 998 |
+
unique_id = uuid.uuid4().hex
|
| 999 |
+
input_path = save_image(image.file, f"./input_{timestamp}_{unique_id}.jpg")
|
| 1000 |
+
mask_path,response = llm_to_process_image_simple_auto(risk_level, input_path, point1, point2,thresholds=thresholds)
|
| 1001 |
+
output_path = f"./output_simple_lama_{timestamp}_{unique_id}.jpg"
|
| 1002 |
+
print('point1,point2',point1,point2)#消去したくない範囲のこと
|
| 1003 |
+
# OpenCVでインペイント
|
| 1004 |
+
inpaint_image_with_mask1(input_path, mask_path, output_path)
|
| 1005 |
+
|
| 1006 |
+
return FileResponse(output_path), response
|
| 1007 |
+
|
| 1008 |
+
|
| 1009 |
+
|
| 1010 |
+
|
| 1011 |
+
|
| 1012 |
+
|
| 1013 |
+
|
| 1014 |
+
|
| 1015 |
+
|
| 1016 |
+
|
| 1017 |
+
|
| 1018 |
+
|
| 1019 |
+
|
| 1020 |
+
|
| 1021 |
+
|
| 1022 |
+
|
| 1023 |
# カスケードファイルの読み込み (顔検出)
|
| 1024 |
+
#face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
|
| 1025 |
|
| 1026 |
def apply_mosaic(image, x, y, w, h, mosaic_level=15):
|
| 1027 |
""" 指定範囲にモザイク処理を適用 """
|
|
|
|
| 1030 |
face = cv2.resize(face, (w, h), interpolation=cv2.INTER_NEAREST)
|
| 1031 |
image[y:y+h, x:x+w] = face
|
| 1032 |
return image
|
| 1033 |
+
'''
|
| 1034 |
@app.post("/mosaic_face")
|
| 1035 |
async def mosaic_face(file: UploadFile = File(...)):
|
| 1036 |
# 画像ファイルを読み込み
|
|
|
|
| 1054 |
# 一時ファイルをレスポンスとして返す
|
| 1055 |
return FileResponse(path=temp_file_path, media_type="image/jpeg", filename="mosaic_image.jpg")
|
| 1056 |
|
| 1057 |
+
'''
|
| 1058 |
|
| 1059 |
|
| 1060 |
|
requirements.txt
CHANGED
|
@@ -73,5 +73,5 @@ zipp==3.20.2
|
|
| 73 |
supervision
|
| 74 |
onnxruntime
|
| 75 |
google-genai
|
| 76 |
-
dotenv
|
| 77 |
moondream
|
|
|
|
| 73 |
supervision
|
| 74 |
onnxruntime
|
| 75 |
google-genai
|
| 76 |
+
python-dotenv
|
| 77 |
moondream
|