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")