dahyedahye commited on
Commit
2d8a39b
ยท
1 Parent(s): c216f77
Files changed (2) hide show
  1. app.py +18 -65
  2. app.py.bacup2 +81 -0
app.py CHANGED
@@ -1,11 +1,8 @@
1
- import io
2
  import cv2
3
  import numpy as np
4
- import base64
5
- from PIL import Image
6
- from fastapi import FastAPI, HTTPException
7
- from fastapi.responses import StreamingResponse, JSONResponse
8
- from pydantic import BaseModel
9
 
10
  app = FastAPI(
11
  version="0.0.1",
@@ -17,65 +14,21 @@ app = FastAPI(
17
  ],
18
  )
19
 
20
- # Pydantic ๋ชจ๋ธ ์ •์˜
21
- class ImageData(BaseModel):
22
- image_base64: str
23
-
24
- @app.post("/process-image/")
25
- def process_image(data: ImageData):
26
- try:
27
- # Base64 ๋ฌธ์ž์—ด์„ ๋””์ฝ”๋”ฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ
28
- image_data = base64.b64decode(data.image_base64)
29
- # NumPy ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
30
- nparr = np.frombuffer(image_data, np.uint8)
31
- # OpenCV๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋””์ฝ”๋”ฉ
32
- image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
33
-
34
- if image is None:
35
- raise HTTPException(status_code=400, detail="Invalid image data")
36
-
37
- # ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ๋กœ ๋ณ€ํ™˜
38
- gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
39
-
40
- # Canny ์—์ง€ ๊ฒ€์ถœ ์ ์šฉ
41
- edges = cv2.Canny(gray_image, threshold1=100, threshold2=200)
42
- edges_image = Image.fromarray(edges)
43
-
44
- # ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ ์ƒ์„ฑ
45
- white_background = Image.new("RGB", edges_image.size, (255, 255, 255))
46
-
47
- # ๊ฒ€์€์ƒ‰ ์—์ง€๋ฅผ ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ ์œ„์— ํ•ฉ์„ฑ
48
- edges_on_white = Image.composite(Image.new("RGB", edges_image.size, (0, 0, 0)), white_background, edges_image)
49
-
50
- # ์ตœ์ข… Canny ์ด๋ฏธ์ง€๋ฅผ BytesIO ๊ฐ์ฒด์— ์ €์žฅ
51
- canny_output_io = io.BytesIO()
52
- edges_on_white.save(canny_output_io, format='JPEG')
53
- canny_output_io.seek(0)
54
-
55
- # Sobel ์—ฐ์‚ฐ์ž ์ ์šฉ
56
- sobelx = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=5) # X ์ถ•์— ๋Œ€ํ•œ Sobel ์—ฐ์‚ฐ์ž
57
- sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=5) # Y ์ถ•์— ๋Œ€ํ•œ Sobel ์—ฐ์‚ฐ์ž
58
-
59
- # ๋‘ ๊ธฐ์šธ๊ธฐ ๊ฒฐํ•ฉ
60
- sobel_combined = cv2.magnitude(sobelx, sobely)
61
-
62
- # ๊ฒฐ๊ณผ๋ฅผ [0, 255] ๋ฒ”์œ„๋กœ ์ •๊ทœํ™”
63
- sobel_combined = cv2.normalize(sobel_combined, None, 0, 255, cv2.NORM_MINMAX)
64
- sobel_combined = sobel_combined.astype('uint8')
65
-
66
- # ๊ฒฐ๊ณผ๋ฅผ PIL ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜
67
- sobel_image = Image.fromarray(sobel_combined)
68
-
69
- # Sobel ์—์ง€๋ฅผ ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ ์œ„์— ํ•ฉ์„ฑ
70
- edges_on_white_sobel = Image.composite(Image.new("RGB", sobel_image.size, (0, 0, 0)), white_background, sobel_image)
71
 
72
- # ์ตœ์ข… Sobel ์ด๋ฏธ์ง€๋ฅผ BytesIO ๊ฐ์ฒด์— ์ €์žฅ
73
- sobel_output_io = io.BytesIO()
74
- edges_on_white_sobel.save(sobel_output_io, format='JPEG')
75
- sobel_output_io.seek(0)
76
 
77
- # StreamingResponse๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ ๋ฐ˜ํ™˜
78
- return StreamingResponse(sobel_output_io, media_type='image/jpeg')
 
79
 
80
- except Exception as e:
81
- return JSONResponse(status_code=500, content={"message": str(e)})
 
1
+ from fastapi import FastAPI, File, UploadFile
2
  import cv2
3
  import numpy as np
4
+ from fastapi.responses import StreamingResponse
5
+ import io
 
 
 
6
 
7
  app = FastAPI(
8
  version="0.0.1",
 
14
  ],
15
  )
16
 
17
+ @app.post("/detect-edges/")
18
+ async def detect_edges(file: UploadFile = File(...)):
19
+ # ์ด๋ฏธ์ง€๋ฅผ ๋ฐ”์ดํŠธ ๋ฐฐ์—ด๋กœ ์ฝ๊ธฐ
20
+ image_bytes = await file.read()
21
+ # ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์„ numpy ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
22
+ nparr = np.frombuffer(image_bytes, np.uint8)
23
+ # numpy ๋ฐฐ์—ด์„ ์ด๋ฏธ์ง€๋กœ ๋””์ฝ”๋”ฉ
24
+ img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ # ์—ฃ์ง€ ๋””ํ…์…˜ ์ˆ˜ํ–‰ (Canny ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ)
27
+ edges = cv2.Canny(img, 100, 200)
 
 
28
 
29
+ # ์—ฃ์ง€ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œ ์ธ์ฝ”๋”ฉ
30
+ _, buffer = cv2.imencode('.png', edges)
31
+ io_buf = io.BytesIO(buffer)
32
 
33
+ # ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „์†ก
34
+ return StreamingResponse(io_buf, media_type="image/png")
app.py.bacup2 ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import cv2
3
+ import numpy as np
4
+ import base64
5
+ from PIL import Image
6
+ from fastapi import FastAPI, HTTPException
7
+ from fastapi.responses import StreamingResponse, JSONResponse
8
+ from pydantic import BaseModel
9
+
10
+ app = FastAPI(
11
+ version="0.0.1",
12
+ servers=[
13
+ {
14
+ "url": "https://leekwoon-edge-api.hf.space",
15
+ "description": "image edge detection API",
16
+ }
17
+ ],
18
+ )
19
+
20
+ # Pydantic ๋ชจ๋ธ ์ •์˜
21
+ class ImageData(BaseModel):
22
+ image_base64: str
23
+
24
+ @app.post("/process-image/")
25
+ def process_image(data: ImageData):
26
+ try:
27
+ # Base64 ๋ฌธ์ž์—ด์„ ๋””์ฝ”๋”ฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ
28
+ image_data = base64.b64decode(data.image_base64)
29
+ # NumPy ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
30
+ nparr = np.frombuffer(image_data, np.uint8)
31
+ # OpenCV๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋””์ฝ”๋”ฉ
32
+ image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
33
+
34
+ if image is None:
35
+ raise HTTPException(status_code=400, detail="Invalid image data")
36
+
37
+ # ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ๋กœ ๋ณ€ํ™˜
38
+ gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
39
+
40
+ # Canny ์—์ง€ ๊ฒ€์ถœ ์ ์šฉ
41
+ edges = cv2.Canny(gray_image, threshold1=100, threshold2=200)
42
+ edges_image = Image.fromarray(edges)
43
+
44
+ # ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ ์ƒ์„ฑ
45
+ white_background = Image.new("RGB", edges_image.size, (255, 255, 255))
46
+
47
+ # ๊ฒ€์€์ƒ‰ ์—์ง€๋ฅผ ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ ์œ„์— ํ•ฉ์„ฑ
48
+ edges_on_white = Image.composite(Image.new("RGB", edges_image.size, (0, 0, 0)), white_background, edges_image)
49
+
50
+ # ์ตœ์ข… Canny ์ด๋ฏธ์ง€๋ฅผ BytesIO ๊ฐ์ฒด์— ์ €์žฅ
51
+ canny_output_io = io.BytesIO()
52
+ edges_on_white.save(canny_output_io, format='JPEG')
53
+ canny_output_io.seek(0)
54
+
55
+ # Sobel ์—ฐ์‚ฐ์ž ์ ์šฉ
56
+ sobelx = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=5) # X ์ถ•์— ๋Œ€ํ•œ Sobel ์—ฐ์‚ฐ์ž
57
+ sobely = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=5) # Y ์ถ•์— ๋Œ€ํ•œ Sobel ์—ฐ์‚ฐ์ž
58
+
59
+ # ๋‘ ๊ธฐ์šธ๊ธฐ ๊ฒฐํ•ฉ
60
+ sobel_combined = cv2.magnitude(sobelx, sobely)
61
+
62
+ # ๊ฒฐ๊ณผ๋ฅผ [0, 255] ๋ฒ”์œ„๋กœ ์ •๊ทœํ™”
63
+ sobel_combined = cv2.normalize(sobel_combined, None, 0, 255, cv2.NORM_MINMAX)
64
+ sobel_combined = sobel_combined.astype('uint8')
65
+
66
+ # ๊ฒฐ๊ณผ๋ฅผ PIL ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜
67
+ sobel_image = Image.fromarray(sobel_combined)
68
+
69
+ # Sobel ์—์ง€๋ฅผ ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ ์œ„์— ํ•ฉ์„ฑ
70
+ edges_on_white_sobel = Image.composite(Image.new("RGB", sobel_image.size, (0, 0, 0)), white_background, sobel_image)
71
+
72
+ # ์ตœ์ข… Sobel ์ด๋ฏธ์ง€๋ฅผ BytesIO ๊ฐ์ฒด์— ์ €์žฅ
73
+ sobel_output_io = io.BytesIO()
74
+ edges_on_white_sobel.save(sobel_output_io, format='JPEG')
75
+ sobel_output_io.seek(0)
76
+
77
+ # StreamingResponse๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ ๋ฐ˜ํ™˜
78
+ return StreamingResponse(sobel_output_io, media_type='image/jpeg')
79
+
80
+ except Exception as e:
81
+ return JSONResponse(status_code=500, content={"message": str(e)})