Jaizxzx commited on
Commit
bdce3ce
·
1 Parent(s): 46ab407

Added more image editing features.

Browse files
Files changed (3) hide show
  1. app.py +67 -3
  2. app/image_processing.py +85 -1
  3. requirements.txt +5 -5
app.py CHANGED
@@ -15,7 +15,13 @@ def process_image_pipeline(
15
  filter_type: str,
16
  bg_color_r: int,
17
  bg_color_g: int,
18
- bg_color_b: int
 
 
 
 
 
 
19
  ) -> np.ndarray:
20
  """Process image with selected parameters"""
21
  try:
@@ -31,6 +37,17 @@ def process_image_pipeline(
31
  bg_color = (bg_color_r, bg_color_g, bg_color_b, 255)
32
 
33
  try:
 
 
 
 
 
 
 
 
 
 
 
34
  # Process image using the ImageProcessor class
35
  # First remove background
36
  processed = ImageProcessor.remove_background(
@@ -78,7 +95,8 @@ def create_gradio_interface():
78
 
79
  # Define available filters from the image processor's filter dictionary
80
  filter_type = gr.Dropdown(
81
- choices=["none", "grayscale", "sepia", "blur", "sharpen", "edge_detect"],
 
82
  value="none",
83
  label="Filter Type",
84
  info="Select a filter to apply to the image"
@@ -110,6 +128,46 @@ def create_gradio_interface():
110
  info="Blue component of background color"
111
  )
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  # Define output with PNG format
114
  output_image = gr.Image(
115
  label="Processed Image",
@@ -126,7 +184,13 @@ def create_gradio_interface():
126
  filter_type,
127
  bg_color_r,
128
  bg_color_g,
129
- bg_color_b
 
 
 
 
 
 
130
  ],
131
  outputs=output_image,
132
  title="Advanced Image Processing Tool",
 
15
  filter_type: str,
16
  bg_color_r: int,
17
  bg_color_g: int,
18
+ bg_color_b: int,
19
+ brightness: float,
20
+ contrast: float,
21
+ saturation: float,
22
+ rotation: int,
23
+ flip_horizontal: bool,
24
+ flip_vertical: bool
25
  ) -> np.ndarray:
26
  """Process image with selected parameters"""
27
  try:
 
37
  bg_color = (bg_color_r, bg_color_g, bg_color_b, 255)
38
 
39
  try:
40
+ # Apply adjustments first
41
+ input_image = ImageProcessor.adjust_image(
42
+ input_image,
43
+ brightness=brightness,
44
+ contrast=contrast,
45
+ saturation=saturation,
46
+ rotation=rotation,
47
+ flip_horizontal=flip_horizontal,
48
+ flip_vertical=flip_vertical
49
+ )
50
+
51
  # Process image using the ImageProcessor class
52
  # First remove background
53
  processed = ImageProcessor.remove_background(
 
95
 
96
  # Define available filters from the image processor's filter dictionary
97
  filter_type = gr.Dropdown(
98
+ choices=["none", "grayscale", "sepia", "blur", "sharpen",
99
+ "edge_detect", "emboss", "sketch", "watercolor", "invert"],
100
  value="none",
101
  label="Filter Type",
102
  info="Select a filter to apply to the image"
 
128
  info="Blue component of background color"
129
  )
130
 
131
+ with gr.Row():
132
+ brightness = gr.Slider(
133
+ minimum=0.0,
134
+ maximum=2.0,
135
+ value=1.0,
136
+ step=0.1,
137
+ label="Brightness"
138
+ )
139
+ contrast = gr.Slider(
140
+ minimum=0.0,
141
+ maximum=2.0,
142
+ value=1.0,
143
+ step=0.1,
144
+ label="Contrast"
145
+ )
146
+ saturation = gr.Slider(
147
+ minimum=0.0,
148
+ maximum=2.0,
149
+ value=1.0,
150
+ step=0.1,
151
+ label="Saturation"
152
+ )
153
+
154
+ with gr.Row():
155
+ rotation = gr.Slider(
156
+ minimum=-180,
157
+ maximum=180,
158
+ value=0,
159
+ step=90,
160
+ label="Rotation"
161
+ )
162
+ flip_horizontal = gr.Checkbox(
163
+ label="Flip Horizontal",
164
+ value=False
165
+ )
166
+ flip_vertical = gr.Checkbox(
167
+ label="Flip Vertical",
168
+ value=False
169
+ )
170
+
171
  # Define output with PNG format
172
  output_image = gr.Image(
173
  label="Processed Image",
 
184
  filter_type,
185
  bg_color_r,
186
  bg_color_g,
187
+ bg_color_b,
188
+ brightness,
189
+ contrast,
190
+ saturation,
191
+ rotation,
192
+ flip_horizontal,
193
+ flip_vertical
194
  ],
195
  outputs=output_image,
196
  title="Advanced Image Processing Tool",
app/image_processing.py CHANGED
@@ -117,7 +117,11 @@ class ImageProcessor:
117
  "blur": lambda img: cv2.GaussianBlur(img, (5, 5), 0),
118
  "sharpen": lambda img: ImageProcessor._sharpen_image(img),
119
  "edge_detect": lambda img: cv2.Canny(img, 100, 200),
120
- "none": lambda img: img
 
 
 
 
121
  }
122
 
123
  # Apply selected filter
@@ -144,6 +148,86 @@ class ImageProcessor:
144
  ])
145
  return cv2.filter2D(image, -1, kernel)
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  @staticmethod
148
  def convert_to_format(
149
  image: np.ndarray,
 
117
  "blur": lambda img: cv2.GaussianBlur(img, (5, 5), 0),
118
  "sharpen": lambda img: ImageProcessor._sharpen_image(img),
119
  "edge_detect": lambda img: cv2.Canny(img, 100, 200),
120
+ "none": lambda img: img,
121
+ "emboss": lambda img: ImageProcessor._apply_emboss(img),
122
+ "sketch": lambda img: ImageProcessor._apply_sketch(img),
123
+ "watercolor": lambda img: ImageProcessor._apply_watercolor(img),
124
+ "invert": lambda img: cv2.bitwise_not(img)
125
  }
126
 
127
  # Apply selected filter
 
148
  ])
149
  return cv2.filter2D(image, -1, kernel)
150
 
151
+ @staticmethod
152
+ def _apply_emboss(image: np.ndarray) -> np.ndarray:
153
+ """Apply emboss effect"""
154
+ kernel = np.array([[-2,-1,0], [-1,1,1], [0,1,2]])
155
+ return cv2.filter2D(image, -1, kernel) + 128
156
+
157
+ @staticmethod
158
+ def _apply_sketch(image: np.ndarray) -> np.ndarray:
159
+ """Create pencil sketch effect"""
160
+ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
161
+ blur = cv2.GaussianBlur(gray, (5,5), 0)
162
+ sketch = cv2.divide(gray, blur, scale=256.0)
163
+ return cv2.cvtColor(sketch, cv2.COLOR_GRAY2RGB)
164
+
165
+ @staticmethod
166
+ def _apply_watercolor(image: np.ndarray) -> np.ndarray:
167
+ """Create watercolor effect"""
168
+ temp = cv2.stylization(image, sigma_s=60, sigma_r=0.6)
169
+ return cv2.edgePreservingFilter(temp, flags=1, sigma_s=64, sigma_r=0.2)
170
+
171
+ @staticmethod
172
+ def adjust_image(
173
+ image: np.ndarray,
174
+ brightness: float = 1.0,
175
+ contrast: float = 1.0,
176
+ saturation: float = 1.0,
177
+ rotation: int = 0,
178
+ flip_horizontal: bool = False,
179
+ flip_vertical: bool = False
180
+ ) -> np.ndarray:
181
+ """
182
+ Apply various adjustments to the image
183
+
184
+ Args:
185
+ image: Input image
186
+ brightness: Brightness factor (0.0 to 2.0)
187
+ contrast: Contrast factor (0.0 to 2.0)
188
+ saturation: Saturation factor (0.0 to 2.0)
189
+ rotation: Rotation angle in degrees
190
+ flip_horizontal: Whether to flip horizontally
191
+ flip_vertical: Whether to flip vertically
192
+ """
193
+ try:
194
+ # Convert to float for processing
195
+ img_float = image.astype(float)
196
+
197
+ # Apply brightness
198
+ img_float = cv2.multiply(img_float, brightness)
199
+
200
+ # Apply contrast
201
+ mean = np.mean(img_float)
202
+ img_float = (img_float - mean) * contrast + mean
203
+
204
+ # Apply saturation
205
+ if len(image.shape) == 3: # Only for color images
206
+ hsv = cv2.cvtColor(np.clip(img_float, 0, 255).astype(np.uint8), cv2.COLOR_RGB2HSV)
207
+ hsv[:, :, 1] = hsv[:, :, 1] * saturation
208
+ img_float = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB).astype(float)
209
+
210
+ # Clip values
211
+ img_float = np.clip(img_float, 0, 255).astype(np.uint8)
212
+
213
+ # Apply rotation
214
+ if rotation != 0:
215
+ center = (image.shape[1] // 2, image.shape[0] // 2)
216
+ matrix = cv2.getRotationMatrix2D(center, rotation, 1.0)
217
+ img_float = cv2.warpAffine(img_float, matrix, (image.shape[1], image.shape[0]))
218
+
219
+ # Apply flips
220
+ if flip_horizontal:
221
+ img_float = cv2.flip(img_float, 1)
222
+ if flip_vertical:
223
+ img_float = cv2.flip(img_float, 0)
224
+
225
+ return img_float
226
+
227
+ except Exception as e:
228
+ print(f"Image adjustment error: {e}")
229
+ return image
230
+
231
  @staticmethod
232
  def convert_to_format(
233
  image: np.ndarray,
requirements.txt CHANGED
@@ -1,6 +1,6 @@
1
- numpy>=1.21.0
2
- opencv-python>=4.5.0
3
- Pillow>=9.0.0
4
- gradio>=3.50.0
5
- rembg>=2.0.0
6
  onnxruntime>=1.15.0
 
1
+ numpy>=1.24.0
2
+ opencv-python>=4.8.0
3
+ Pillow>=10.0.0
4
+ gradio>=3.40.1
5
+ rembg>=2.0.50
6
  onnxruntime>=1.15.0