ishworrsubedii commited on
Commit
5754201
·
1 Parent(s): 1fb00de

feat: add color extraction

Browse files
setup.py CHANGED
@@ -1,17 +1,20 @@
1
  from setuptools import setup, find_packages
2
 
3
  HYPER_E_DOT = "-e ."
 
 
4
  def getRequirements(requirementsPath: str) -> list[str]:
5
  with open(requirementsPath) as file:
6
  requirements = file.read().split("\n")
7
  requirements.remove(HYPER_E_DOT)
8
  return requirements
9
 
 
10
  setup(
11
- name = "Magical-Mirror",
12
- author = "Subramani Sivakumar",
13
- author_email = "bwsubbu@gmail.com",
14
- version = "0.1",
15
- packages = find_packages(),
16
- install_requires = getRequirements(requirementsPath = "./requirements.txt")
17
- )
 
1
  from setuptools import setup, find_packages
2
 
3
  HYPER_E_DOT = "-e ."
4
+
5
+
6
  def getRequirements(requirementsPath: str) -> list[str]:
7
  with open(requirementsPath) as file:
8
  requirements = file.read().split("\n")
9
  requirements.remove(HYPER_E_DOT)
10
  return requirements
11
 
12
+
13
  setup(
14
+ name="Jewel Mirror",
15
+ author="Ishwor Subedi",
16
+ author_email="ishworr.subedi@gmail.com",
17
+ version="0.1",
18
+ packages=find_packages(),
19
+ install_requires=getRequirements(requirementsPath="./requirements.txt")
20
+ )
src/api/image_prep_api.py CHANGED
@@ -6,6 +6,8 @@ author @ github.com/ishworrsubedii
6
  import base64
7
  import os
8
  from io import BytesIO
 
 
9
  import numpy as np
10
  import replicate
11
  import requests
@@ -14,12 +16,14 @@ from fastapi import APIRouter, UploadFile, File, HTTPException
14
  from fastapi.responses import JSONResponse
15
 
16
  from src.components.auto_crop import crop_transparent_image
 
17
 
18
  preprocessing_router = APIRouter()
19
 
20
  rmbg: str = os.getenv("RMBG")
21
 
22
  enhancer: str = os.getenv("ENHANCER")
 
23
 
24
 
25
  def replicate_bg(input):
@@ -131,7 +135,7 @@ async def crop_transparent(image: UploadFile):
131
 
132
 
133
  @preprocessing_router.post("/background_replace")
134
- async def nto_id(image: UploadFile = File(...), bg_image: UploadFile = File(...)):
135
  image_bytes = await image.read()
136
  bg_image = await bg_image.read()
137
 
@@ -156,3 +160,30 @@ async def nto_id(image: UploadFile = File(...), bg_image: UploadFile = File(...)
156
 
157
  except Exception as e:
158
  raise HTTPException(status_code=500, detail=f"Failed to process image: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  import base64
7
  import os
8
  from io import BytesIO
9
+
10
+ import cv2
11
  import numpy as np
12
  import replicate
13
  import requests
 
16
  from fastapi.responses import JSONResponse
17
 
18
  from src.components.auto_crop import crop_transparent_image
19
+ from src.components.color_extraction import ColorExtractionRMBG
20
 
21
  preprocessing_router = APIRouter()
22
 
23
  rmbg: str = os.getenv("RMBG")
24
 
25
  enhancer: str = os.getenv("ENHANCER")
26
+ color_extraction_rmbg = ColorExtractionRMBG()
27
 
28
 
29
  def replicate_bg(input):
 
135
 
136
 
137
  @preprocessing_router.post("/background_replace")
138
+ async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(...)):
139
  image_bytes = await image.read()
140
  bg_image = await bg_image.read()
141
 
 
160
 
161
  except Exception as e:
162
  raise HTTPException(status_code=500, detail=f"Failed to process image: {e}")
163
+
164
+
165
+ @preprocessing_router.post("/rem_bg_color_extraction")
166
+ async def remove_background_color_extraction(image: UploadFile = File(...), hex_color: str = "#FFFFFF",
167
+ threshold: int = 30):
168
+ image_bytes = await image.read()
169
+ image = Image.open(BytesIO(image_bytes)).convert("RGBA")
170
+ image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
171
+
172
+ result = color_extraction_rmbg.extract_color(image, hex_color, threshold)
173
+ result = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_RGB2BGR)).convert("RGBA")
174
+ act_img_base_64 = BytesIO()
175
+ result.save(act_img_base_64, format="PNG")
176
+ image_bytes_ = base64.b64encode(act_img_base_64.getvalue()).decode("utf-8")
177
+
178
+ image_data_uri = f"data:image/png;base64,{image_bytes_}"
179
+
180
+ try:
181
+ response = {
182
+ "output": f"{image_data_uri}",
183
+ 'code': 200
184
+ }
185
+
186
+ return JSONResponse(content=response, status_code=200)
187
+
188
+ except Exception as e:
189
+ raise HTTPException(status_code=500, detail=f"Failed to process image: {e}")
src/components/color_extraction.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ project @ NTO-TCP-HF
3
+ created @ 2024-10-28
4
+ author @ github.com/ishworrsubedii
5
+ """
6
+
7
+ import cv2
8
+ import numpy as np
9
+
10
+
11
+ class ColorExtractionRMBG:
12
+ def __init__(self):
13
+ self.HSV_LOWER = None
14
+ self.HSV_UPPER = None
15
+
16
+ def hex_to_rgb(self, hex_color: str):
17
+ hex_color = hex_color.lstrip("#")
18
+ return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4))
19
+
20
+ def rgb_to_hsv(self, rgb_color):
21
+ rgb_array = np.uint8([[rgb_color]])
22
+ hsv_array = cv2.cvtColor(rgb_array, cv2.COLOR_RGB2HSV)
23
+ return hsv_array[0][0]
24
+
25
+ def set_thresholds(self, hex_color: str, threshold: int):
26
+ hsv_color = self.rgb_to_hsv(self.hex_to_rgb(hex_color))
27
+ lower_bound = np.clip([hsv_color[0] - threshold, 50, 50], 0, 255)
28
+ upper_bound = np.clip([hsv_color[0] + threshold, 255, 255], 0, 255)
29
+ return lower_bound, upper_bound
30
+
31
+ def extract_color(self, image: np.ndarray, hex_color: str, threshold: int):
32
+ self.HSV_LOWER, self.HSV_UPPER = self.set_thresholds(hex_color, threshold)
33
+ hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
34
+ mask = cv2.inRange(hsv, self.HSV_LOWER, self.HSV_UPPER)
35
+ result = cv2.bitwise_and(image, image, mask=mask)
36
+ result = cv2.cvtColor(result, cv2.COLOR_BGR2BGRA)
37
+ result[:, :, 3] = mask
38
+ return result