Alexandros Popov commited on
Commit
6894106
·
1 Parent(s): fa24889

included precommit.

Browse files
Files changed (6) hide show
  1. .pre-commit-config.yaml +49 -0
  2. README.md +1 -1
  3. agents.py +20 -6
  4. app.py +7 -4
  5. evaluators.py +4 -2
  6. filters.py +22 -12
.pre-commit-config.yaml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # .pre-commit-config.yaml
2
+
3
+ repos:
4
+ - repo: https://github.com/pre-commit/pre-commit-hooks
5
+ rev: v4.5.0
6
+ hooks:
7
+ - id: trailing-whitespace
8
+ - id: end-of-file-fixer
9
+ - id: check-yaml
10
+ - id: check-added-large-files
11
+
12
+ - repo: https://github.com/psf/black
13
+ rev: 24.4.2 # Always check for the latest stable version
14
+ hooks:
15
+ - id: black
16
+ language_version: python3.10 # Match your project's Python version
17
+ args: ["--line-length", "120"]
18
+
19
+ - repo: https://github.com/PyCQA/flake8
20
+ rev: 7.0.0
21
+ hooks:
22
+ - id: flake8
23
+ additional_dependencies: ['flake8-bugbear']
24
+ args: [--max-line-length=120, "--ignore", "E203"]
25
+
26
+ - repo: https://github.com/pre-commit/mirrors-mypy
27
+ rev: v1.10.0
28
+ hooks:
29
+ - id: mypy
30
+ args: ["--ignore-missing-imports", "--install-types", "--non-interactive"]
31
+
32
+ - repo: https://github.com/PyCQA/isort
33
+ rev: 5.13.2
34
+ hooks:
35
+ - id: isort
36
+
37
+ - repo: https://github.com/PyCQA/bandit
38
+ rev: 1.7.7
39
+ hooks:
40
+ - id: bandit
41
+ args: ["-r", "src"] # Adjust if your code is in a different directory
42
+
43
+ - repo: https://github.com/asottile/pyupgrade
44
+ rev: v3.15.0
45
+ hooks:
46
+ - id: pyupgrade
47
+ args: ["--py39-plus"] # Set based on your minimum supported version
48
+
49
+ default_stages: [pre-commit]
README.md CHANGED
@@ -10,4 +10,4 @@ Upload an image. Agents apply multiple filters and pick the best one based on qu
10
 
11
  ### Credits
12
 
13
- The image in the repo originates from [toa-heftiba-Xmn-QXsVL4k-unsplash](https://unsplash.com/@heftiba)
 
10
 
11
  ### Credits
12
 
13
+ The image in the repo originates from [toa-heftiba-Xmn-QXsVL4k-unsplash](https://unsplash.com/@heftiba)
agents.py CHANGED
@@ -1,14 +1,28 @@
1
- from smolagents import CodeAgent, HfApiModel, tool
2
- from filters import *
3
  import os
4
 
 
 
 
 
5
  HUGGING_FACE_TOKEN = os.environ["HUGGING_FACE_TOKEN"]
6
 
7
  # Initialize the model and agent
8
  model = HfApiModel(token=HUGGING_FACE_TOKEN)
9
- agent = CodeAgent(tools=[adjust_contrast, load_image_as_bgr, save_image], model=model)
 
 
 
 
 
 
 
 
10
 
11
  # Run the agent
12
- agent.run("Adjust the contrast of the image in image_path by a factor of 1.5. Save the image to output_path.",
13
- additional_args={'image_path': 'toa-heftiba-Xmn-QXsVL4k-unsplash.jpg',
14
- "output_path": 'adjusted_image.jpg'})
 
 
 
 
 
 
 
1
  import os
2
 
3
+ from smolagents import CodeAgent, HfApiModel
4
+
5
+ import filters as flt
6
+
7
  HUGGING_FACE_TOKEN = os.environ["HUGGING_FACE_TOKEN"]
8
 
9
  # Initialize the model and agent
10
  model = HfApiModel(token=HUGGING_FACE_TOKEN)
11
+ picture_operator = CodeAgent(
12
+ tools=[flt.adjust_contrast, flt.load_image_as_bgr, flt.save_image],
13
+ model=model,
14
+ name="Picture Operator",
15
+ description=(
16
+ "Performs operations on images, such as adjusting contrast, loading images, and saving them. "
17
+ "Give it your query as an argument, as well as the path to the image and the output path."
18
+ ),
19
+ )
20
 
21
  # Run the agent
22
+ picture_operator.run(
23
+ "Adjust the contrast of the image in image_path by a factor of 1.5. Save the image to output_path.",
24
+ additional_args={
25
+ "image_path": "toa-heftiba-Xmn-QXsVL4k-unsplash.jpg",
26
+ "output_path": "adjusted_image.jpg",
27
+ },
28
+ )
app.py CHANGED
@@ -1,22 +1,25 @@
1
  import gradio as gr
2
- from filters import apply_filters
3
  from evaluators import evaluate_filters
 
 
4
 
5
  def process_image(image):
6
  filtered_images = apply_filters(image)
7
  best_index, reasons = evaluate_filters(filtered_images)
8
  return filtered_images, f"Winner: Filter {best_index + 1} — {reasons[best_index]}"
9
 
 
10
  demo = gr.Interface(
11
  fn=process_image,
12
  inputs=gr.Image(type="pil"),
13
  outputs=[
14
  gr.Gallery(label="Filtered Options"),
15
- gr.Textbox(label="Critique Agent's Verdict")
16
  ],
17
  title="🧠 AI Art Director – Filter Showdown",
18
- description="Upload an image and let AI agents apply, evaluate, and pick the best filter."
19
  )
20
 
21
  if __name__ == "__main__":
22
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import gradio as gr
2
+
3
  from evaluators import evaluate_filters
4
+ from filters import apply_filters
5
+
6
 
7
  def process_image(image):
8
  filtered_images = apply_filters(image)
9
  best_index, reasons = evaluate_filters(filtered_images)
10
  return filtered_images, f"Winner: Filter {best_index + 1} — {reasons[best_index]}"
11
 
12
+
13
  demo = gr.Interface(
14
  fn=process_image,
15
  inputs=gr.Image(type="pil"),
16
  outputs=[
17
  gr.Gallery(label="Filtered Options"),
18
+ gr.Textbox(label="Critique Agent's Verdict"),
19
  ],
20
  title="🧠 AI Art Director – Filter Showdown",
21
+ description="Upload an image and let AI agents apply, evaluate, and pick the best filter.",
22
  )
23
 
24
  if __name__ == "__main__":
25
+ demo.launch()
evaluators.py CHANGED
@@ -1,13 +1,15 @@
1
- import numpy as np
2
  import cv2
 
 
3
 
4
  def score_image(pil_img):
5
  img = np.array(pil_img.convert("L"))
6
  variance = cv2.Laplacian(img, cv2.CV_64F).var()
7
  return variance
8
 
 
9
  def evaluate_filters(images):
10
  scores = [score_image(img) for img in images]
11
  best_index = int(np.argmax(scores))
12
  reasons = [f"Sharpness score: {s:.2f}" for s in scores]
13
- return best_index, reasons
 
 
1
  import cv2
2
+ import numpy as np
3
+
4
 
5
  def score_image(pil_img):
6
  img = np.array(pil_img.convert("L"))
7
  variance = cv2.Laplacian(img, cv2.CV_64F).var()
8
  return variance
9
 
10
+
11
  def evaluate_filters(images):
12
  scores = [score_image(img) for img in images]
13
  best_index = int(np.argmax(scores))
14
  reasons = [f"Sharpness score: {s:.2f}" for s in scores]
15
+ return best_index, reasons
filters.py CHANGED
@@ -1,9 +1,11 @@
 
 
 
1
  import cv2
2
  import numpy as np
3
  from PIL import Image
4
  from smolagents import tool
5
- import tempfile
6
- import os
7
 
8
  def apply_filters(image: np.ndarray) -> list[np.ndarray]:
9
  """Applies a series of filters to the input image.
@@ -33,6 +35,7 @@ def apply_filters(image: np.ndarray) -> list[np.ndarray]:
33
 
34
  return filtered_images
35
 
 
36
  @tool
37
  def adjust_contrast(image: np.ndarray, alpha: float = 1.5) -> np.ndarray:
38
  """Adjusts the contrast of the image.
@@ -46,6 +49,7 @@ def adjust_contrast(image: np.ndarray, alpha: float = 1.5) -> np.ndarray:
46
  """
47
  return cv2.convertScaleAbs(image, alpha=alpha, beta=0)
48
 
 
49
  @tool
50
  def adjust_saturation(image: np.ndarray, saturation_scale: float = 1.0) -> np.ndarray:
51
  """Adjusts the saturation of the image.
@@ -62,19 +66,21 @@ def adjust_saturation(image: np.ndarray, saturation_scale: float = 1.0) -> np.nd
62
  hsv_img[:, :, 1] = np.clip(hsv_img[:, :, 1], 0, 255)
63
  return cv2.cvtColor(hsv_img.astype(np.uint8), cv2.COLOR_HSV2BGR)
64
 
 
65
  @tool
66
  def adjust_exposure(image: np.ndarray, beta: int = 50) -> np.ndarray:
67
  """Adjusts the exposure (brightness) of the image.
68
 
69
  Args:
70
  image (np.ndarray): Input image in BGR format.
71
- beta (int, optional): Brightness control. Positive values increase brightness, negative decrease. Defaults to 50.
72
 
73
  Returns:
74
  np.ndarray: Exposure adjusted image in BGR format.
75
  """
76
  return cv2.convertScaleAbs(image, alpha=1.0, beta=beta)
77
 
 
78
  @tool
79
  def denoise_image(image: np.ndarray, h: int = 10) -> np.ndarray:
80
  """Denoises the image using Non-local Means Denoising algorithm.
@@ -88,6 +94,7 @@ def denoise_image(image: np.ndarray, h: int = 10) -> np.ndarray:
88
  """
89
  return cv2.fastNlMeansDenoisingColored(image, None, h, h, 7, 21)
90
 
 
91
  @tool
92
  def crop_image(image: np.ndarray, x: int, y: int, width: int, height: int) -> np.ndarray:
93
  """Crops the image to the specified rectangle.
@@ -102,7 +109,8 @@ def crop_image(image: np.ndarray, x: int, y: int, width: int, height: int) -> np
102
  Returns:
103
  np.ndarray: Cropped image in BGR format.
104
  """
105
- return image[y:y+height, x:x+width]
 
106
 
107
  @tool
108
  def apply_vignette(image: np.ndarray, level: int = 2) -> np.ndarray:
@@ -116,8 +124,8 @@ def apply_vignette(image: np.ndarray, level: int = 2) -> np.ndarray:
116
  np.ndarray: Image with vignette effect applied in BGR format.
117
  """
118
  rows, cols = image.shape[:2]
119
- kernel_x = cv2.getGaussianKernel(cols, cols/level)
120
- kernel_y = cv2.getGaussianKernel(rows, rows/level)
121
  kernel = kernel_y * kernel_x.T
122
  mask = kernel / kernel.max()
123
  vignette = np.copy(image)
@@ -125,13 +133,14 @@ def apply_vignette(image: np.ndarray, level: int = 2) -> np.ndarray:
125
  vignette[:, :, i] = vignette[:, :, i] * mask
126
  return vignette
127
 
 
128
  @tool
129
  def load_image_as_bgr(image_path: str) -> np.ndarray:
130
  """Loads an image from path and converts it to BGR format for OpenCV.
131
-
132
  Args:
133
  image_path (str): Path to the image file.
134
-
135
  Returns:
136
  np.ndarray: Image in BGR format as numpy array.
137
  """
@@ -139,7 +148,8 @@ def load_image_as_bgr(image_path: str) -> np.ndarray:
139
  image_np = np.array(image)
140
  return cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
141
 
142
- @tool
 
143
  def save_image(image: np.ndarray, image_path: str) -> None:
144
  """Saves an image to the specified path.
145
 
@@ -153,14 +163,14 @@ def save_image(image: np.ndarray, image_path: str) -> None:
153
  if __name__ == "__main__":
154
  # Load a test image
155
  test_image_np = load_image_as_bgr("test_image.jpg")
156
-
157
  # Apply all filters
158
  filtered_images = apply_filters(test_image_np)
159
-
160
  # Save results
161
  dir = tempfile.mkdtemp()
162
  for i, filtered_img in enumerate(filtered_images):
163
  output_path = os.path.join(dir, f"filter_{i+1}.jpg")
164
  rgb_img = cv2.cvtColor(filtered_img, cv2.COLOR_BGR2RGB)
165
  Image.fromarray(rgb_img).save(output_path)
166
- print(f"Saved {output_path}")
 
1
+ import os
2
+ import tempfile
3
+
4
  import cv2
5
  import numpy as np
6
  from PIL import Image
7
  from smolagents import tool
8
+
 
9
 
10
  def apply_filters(image: np.ndarray) -> list[np.ndarray]:
11
  """Applies a series of filters to the input image.
 
35
 
36
  return filtered_images
37
 
38
+
39
  @tool
40
  def adjust_contrast(image: np.ndarray, alpha: float = 1.5) -> np.ndarray:
41
  """Adjusts the contrast of the image.
 
49
  """
50
  return cv2.convertScaleAbs(image, alpha=alpha, beta=0)
51
 
52
+
53
  @tool
54
  def adjust_saturation(image: np.ndarray, saturation_scale: float = 1.0) -> np.ndarray:
55
  """Adjusts the saturation of the image.
 
66
  hsv_img[:, :, 1] = np.clip(hsv_img[:, :, 1], 0, 255)
67
  return cv2.cvtColor(hsv_img.astype(np.uint8), cv2.COLOR_HSV2BGR)
68
 
69
+
70
  @tool
71
  def adjust_exposure(image: np.ndarray, beta: int = 50) -> np.ndarray:
72
  """Adjusts the exposure (brightness) of the image.
73
 
74
  Args:
75
  image (np.ndarray): Input image in BGR format.
76
+ beta (int, optional): Brightness control. Positive values increase brightness, negative decrease. Defaults 50.
77
 
78
  Returns:
79
  np.ndarray: Exposure adjusted image in BGR format.
80
  """
81
  return cv2.convertScaleAbs(image, alpha=1.0, beta=beta)
82
 
83
+
84
  @tool
85
  def denoise_image(image: np.ndarray, h: int = 10) -> np.ndarray:
86
  """Denoises the image using Non-local Means Denoising algorithm.
 
94
  """
95
  return cv2.fastNlMeansDenoisingColored(image, None, h, h, 7, 21)
96
 
97
+
98
  @tool
99
  def crop_image(image: np.ndarray, x: int, y: int, width: int, height: int) -> np.ndarray:
100
  """Crops the image to the specified rectangle.
 
109
  Returns:
110
  np.ndarray: Cropped image in BGR format.
111
  """
112
+ return image[y : y + height, x : x + width]
113
+
114
 
115
  @tool
116
  def apply_vignette(image: np.ndarray, level: int = 2) -> np.ndarray:
 
124
  np.ndarray: Image with vignette effect applied in BGR format.
125
  """
126
  rows, cols = image.shape[:2]
127
+ kernel_x = cv2.getGaussianKernel(cols, cols / level)
128
+ kernel_y = cv2.getGaussianKernel(rows, rows / level)
129
  kernel = kernel_y * kernel_x.T
130
  mask = kernel / kernel.max()
131
  vignette = np.copy(image)
 
133
  vignette[:, :, i] = vignette[:, :, i] * mask
134
  return vignette
135
 
136
+
137
  @tool
138
  def load_image_as_bgr(image_path: str) -> np.ndarray:
139
  """Loads an image from path and converts it to BGR format for OpenCV.
140
+
141
  Args:
142
  image_path (str): Path to the image file.
143
+
144
  Returns:
145
  np.ndarray: Image in BGR format as numpy array.
146
  """
 
148
  image_np = np.array(image)
149
  return cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
150
 
151
+
152
+ @tool
153
  def save_image(image: np.ndarray, image_path: str) -> None:
154
  """Saves an image to the specified path.
155
 
 
163
  if __name__ == "__main__":
164
  # Load a test image
165
  test_image_np = load_image_as_bgr("test_image.jpg")
166
+
167
  # Apply all filters
168
  filtered_images = apply_filters(test_image_np)
169
+
170
  # Save results
171
  dir = tempfile.mkdtemp()
172
  for i, filtered_img in enumerate(filtered_images):
173
  output_path = os.path.join(dir, f"filter_{i+1}.jpg")
174
  rgb_img = cv2.cvtColor(filtered_img, cv2.COLOR_BGR2RGB)
175
  Image.fromarray(rgb_img).save(output_path)
176
+ print(f"Saved {output_path}")