File size: 4,089 Bytes
be78bf0 a916af1 be78bf0 a7b1429 6cedaa8 ef7cf2b ac5ec09 bc53a36 be78bf0 c5bf998 be78bf0 dd440d8 c5bf998 ac5ec09 a7b1429 2d8a39b be78bf0 6cedaa8 be78bf0 a7b1429 6cedaa8 ef7cf2b 6cedaa8 be78bf0 6cedaa8 be78bf0 6cedaa8 be78bf0 6cedaa8 be78bf0 ef7cf2b be78bf0 6cedaa8 ef7cf2b 6cedaa8 be78bf0 ef7cf2b be78bf0 6cedaa8 ef7cf2b be78bf0 |
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 119 120 121 122 123 |
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import FileResponse
import cv2
from PIL import Image
import re
import gdown
import os
import uuid
URL = "https://leekwoon-edge-api.hf.space"
# URL = "http://localhost:7860"
app = FastAPI(
version="0.0.1",
servers=[
{
"url": URL,
"description": "image edge detection API",
}
],
)
def extract_file_id(drive_url: str) -> str:
"""
Google Drive URL์์ ํ์ผ ID๋ฅผ ์ถ์ถํฉ๋๋ค.
Parameters:
drive_url (str): Google Drive ํ์ผ URL.
Returns:
str: ์ถ์ถ๋ ํ์ผ ID.
"""
# ์ ๊ท ํํ์์ ์ฌ์ฉํ์ฌ URL์์ ํ์ผ ID ์ถ์ถ
match = re.search(r'/d/([a-zA-Z0-9_-]+)', drive_url)
if match:
return match.group(1)
# ๋ค๋ฅธ URL ํ์์์ ํ์ผ ID ์ถ์ถ
match = re.search(r'file/d/([a-zA-Z0-9_-]+)', drive_url)
if match:
return match.group(1)
# ๊ณต์ ๋งํฌ์์ ํ์ผ ID ์ถ์ถ
match = re.search(r'([a-zA-Z0-9_-]{33,})', drive_url)
if match:
return match.group(1)
raise ValueError("Invalid Google Drive URL")
@app.post("/detect-edges/")
def detect_edges(url: str, request: Request):
try:
# Google Drive ํ์ผ ID ์ถ์ถ
file_id = extract_file_id(url)
download_url = f"https://drive.google.com/uc?id={file_id}"
# ์ด๋ฏธ์ง๋ฅผ Google Drive์์ ๋ค์ด๋ก๋
temp_input_image = f'/tmp/{uuid.uuid4()}.png'
gdown.download(download_url, temp_input_image, quiet=False)
# ์ด๋ฏธ์ง๋ฅผ ์ฝ์ด๋ค์
image = cv2.imread(temp_input_image)
# ์ด๋ฏธ์ง๊ฐ ์ ๋๋ก ์ฝํ๋์ง ํ์ธ
if image is None:
raise HTTPException(status_code=400, detail="Invalid image URL or file not found.")
# ๊ทธ๋ ์ด์ค์ผ์ผ๋ก ๋ณํ
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Canny ์์ง ๊ฒ์ถ ์ ์ฉ
edges = cv2.Canny(gray_image, threshold1=100, threshold2=200)
edges_image = Image.fromarray(edges)
# ํฐ์ ๋ฐฐ๊ฒฝ ์์ฑ
white_background = Image.new("RGB", edges_image.size, (255, 255, 255))
# Canny ์์ง๋ฅผ ํฐ์ ๋ฐฐ๊ฒฝ ์์ ํฉ์ฑ
edges_on_white = Image.composite(Image.new("RGB", edges_image.size, (0, 0, 0)), white_background, edges_image)
# Sobel ์ฐ์ฐ์ ์ ์ฉ
sobelx = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=5) # X ์ถ์ ๋ํ Sobel ์ฐ์ฐ์
sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=5) # Y ์ถ์ ๋ํ Sobel ์ฐ์ฐ์
# ๋ ๊ธฐ์ธ๊ธฐ ๊ฒฐํฉ
sobel_combined = cv2.magnitude(sobelx, sobely)
# ๊ฒฐ๊ณผ๋ฅผ [0, 255] ๋ฒ์๋ก ์ ๊ทํ
sobel_combined = cv2.normalize(sobel_combined, None, 0, 255, cv2.NORM_MINMAX)
sobel_combined = sobel_combined.astype('uint8')
# ๊ฒฐ๊ณผ๋ฅผ PIL ์ด๋ฏธ์ง๋ก ๋ณํ
sobel_image = Image.fromarray(sobel_combined)
# Sobel ์์ง๋ฅผ ํฐ์ ๋ฐฐ๊ฒฝ ์์ ํฉ์ฑ
edges_on_white_sobel = Image.composite(Image.new("RGB", sobel_image.size, (0, 0, 0)), white_background, sobel_image)
# ์ต์ข
Sobel ์ด๋ฏธ์ง๋ฅผ ํ์ผ๋ก ์ ์ฅ (PNG ํ์)
output_file_path = f'/tmp/{uuid.uuid4()}.png'
edges_on_white_sobel.save(output_file_path, format='PNG')
# ์
๋ ฅ ์ด๋ฏธ์ง ์์ ํ์ผ ์ญ์
os.remove(temp_input_image)
# ์๋ฒ์ URL์ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ด๋ก๋ URL ์์ฑ
download_url = os.path.join(URL, "tmp", os.path.basename(output_file_path))
# ํด๋ผ์ด์ธํธ์๊ฒ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋ฐํ
return {"download_url": download_url}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@app.get("/tmp/{filename}")
def download_file(filename: str):
file_path = f"/tmp/{filename}"
if os.path.exists(file_path):
return FileResponse(file_path, media_type='image/png', filename=filename)
else:
raise HTTPException(status_code=404, detail="File not found") |