Spaces:
Sleeping
Sleeping
Sagar Bharadwaj
commited on
Commit
·
54cb6c5
1
Parent(s):
68b9a41
Pulled out configs. Added main.
Browse files- colorbynumber/config.py +11 -0
- colorbynumber/gen_islands.py +8 -2
- colorbynumber/main.py +39 -0
- colorbynumber/numbered_islands.py +19 -9
- colorbynumber/simplify_image.py +4 -2
- colorbynumber/utils.py +2 -0
colorbynumber/config.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
default_config = {
|
| 2 |
+
"denoise": True,
|
| 3 |
+
"denoise_h": 100,
|
| 4 |
+
"border_padding": 2,
|
| 5 |
+
"area_perc_threshold": 0.05,
|
| 6 |
+
"arc_length_area_ratio_threshold": 1,
|
| 7 |
+
"border_color": (0, 0, 0),
|
| 8 |
+
"font_size": 0.5,
|
| 9 |
+
"font_color": (0, 0, 0),
|
| 10 |
+
"font_thickness": 2,
|
| 11 |
+
}
|
colorbynumber/gen_islands.py
CHANGED
|
@@ -2,6 +2,9 @@ import cv2 as cv
|
|
| 2 |
import numpy as np
|
| 3 |
from polylabel import polylabel
|
| 4 |
|
|
|
|
|
|
|
|
|
|
| 5 |
class GenerateIslands:
|
| 6 |
def __init__(self, indices_color_choices,):
|
| 7 |
self.indices_color_choices = indices_color_choices
|
|
@@ -144,8 +147,11 @@ class GenerateIslands:
|
|
| 144 |
self.island_borders[color_index].append((color_index, contour_border_coords))
|
| 145 |
|
| 146 |
|
| 147 |
-
def get_islands(self,
|
| 148 |
-
|
|
|
|
|
|
|
|
|
|
| 149 |
for color_index in np.unique(self.indices_color_choices):
|
| 150 |
self._get_islands_for_one_color(
|
| 151 |
color_index = color_index,
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
from polylabel import polylabel
|
| 4 |
|
| 5 |
+
from .config import default_config
|
| 6 |
+
|
| 7 |
+
|
| 8 |
class GenerateIslands:
|
| 9 |
def __init__(self, indices_color_choices,):
|
| 10 |
self.indices_color_choices = indices_color_choices
|
|
|
|
| 147 |
self.island_borders[color_index].append((color_index, contour_border_coords))
|
| 148 |
|
| 149 |
|
| 150 |
+
def get_islands(self, config = default_config):
|
| 151 |
+
border_padding = config["border_padding"]
|
| 152 |
+
area_perc_threshold = config["area_perc_threshold"]
|
| 153 |
+
arc_length_area_ratio_threshold = config["arc_length_area_ratio_threshold"]
|
| 154 |
+
|
| 155 |
for color_index in np.unique(self.indices_color_choices):
|
| 156 |
self._get_islands_for_one_color(
|
| 157 |
color_index = color_index,
|
colorbynumber/main.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2 as cv
|
| 2 |
+
|
| 3 |
+
from .config import default_config
|
| 4 |
+
from .simplify_image import simplify_image
|
| 5 |
+
from .gen_islands import GenerateIslands
|
| 6 |
+
from .numbered_islands import create_numbered_islands
|
| 7 |
+
|
| 8 |
+
class ColorByNumber:
|
| 9 |
+
def __init__(self, image_path, color_list, config = default_config):
|
| 10 |
+
self.image_path = image_path
|
| 11 |
+
self.color_list = color_list
|
| 12 |
+
self.config = config
|
| 13 |
+
|
| 14 |
+
def create_color_by_number(self):
|
| 15 |
+
image = cv.imread(self.image_path)
|
| 16 |
+
image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
|
| 17 |
+
self.image = image
|
| 18 |
+
|
| 19 |
+
simplified_image, indices_color_choices = simplify_image(
|
| 20 |
+
image=self.image,
|
| 21 |
+
color_list=self.color_list,
|
| 22 |
+
config=self.config
|
| 23 |
+
)
|
| 24 |
+
self.simplified_image = simplified_image
|
| 25 |
+
|
| 26 |
+
generate_islands_obj = GenerateIslands(indices_color_choices)
|
| 27 |
+
island_borders_list, centroid_coords_list = generate_islands_obj.get_islands(config=self.config)
|
| 28 |
+
self.generate_islands_obj = generate_islands_obj
|
| 29 |
+
self.island_borders_list = island_borders_list
|
| 30 |
+
|
| 31 |
+
numbered_islands = create_numbered_islands(
|
| 32 |
+
islands = self.island_borders_list,
|
| 33 |
+
image_shape = self.image.shape,
|
| 34 |
+
centroid_coords_list = centroid_coords_list,
|
| 35 |
+
config = self.config
|
| 36 |
+
)
|
| 37 |
+
self.numbered_islands = numbered_islands
|
| 38 |
+
|
| 39 |
+
return self.numbered_islands
|
colorbynumber/numbered_islands.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
import cv2
|
| 2 |
import numpy as np
|
| 3 |
|
|
|
|
|
|
|
| 4 |
def _get_centroid(coordinates):
|
| 5 |
rows, cols = coordinates
|
| 6 |
if len(rows) == 0 or len(cols) == 0:
|
|
@@ -8,7 +10,7 @@ def _get_centroid(coordinates):
|
|
| 8 |
return (int(np.mean(rows)), int(np.mean(cols)))
|
| 9 |
|
| 10 |
|
| 11 |
-
def _add_text_to_image(image, text, position, font_size
|
| 12 |
"""Add text to an image.
|
| 13 |
|
| 14 |
Args:
|
|
@@ -21,14 +23,12 @@ def _add_text_to_image(image, text, position, font_size=0.5, font_color=(0, 0, 0
|
|
| 21 |
np.array: A new image with the text added.
|
| 22 |
"""
|
| 23 |
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 24 |
-
font_scale = font_size
|
| 25 |
-
font_thickness = 2
|
| 26 |
return cv2.putText(
|
| 27 |
image,
|
| 28 |
text,
|
| 29 |
position,
|
| 30 |
font,
|
| 31 |
-
|
| 32 |
font_color,
|
| 33 |
font_thickness,
|
| 34 |
cv2.LINE_AA
|
|
@@ -37,8 +37,8 @@ def _add_text_to_image(image, text, position, font_size=0.5, font_color=(0, 0, 0
|
|
| 37 |
|
| 38 |
def create_numbered_islands(islands, image_shape,
|
| 39 |
centroid_coords_list = None,
|
| 40 |
-
|
| 41 |
-
|
| 42 |
"""Create a new image with the islands numbered.
|
| 43 |
|
| 44 |
Args:
|
|
@@ -48,6 +48,13 @@ def create_numbered_islands(islands, image_shape,
|
|
| 48 |
Returns:
|
| 49 |
np.array: A new image with the islands numbered.
|
| 50 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
# Create an all white image
|
| 52 |
width, height, channels = image_shape
|
| 53 |
numbered_islands = np.ones((width + padding*2, height + padding*2, channels),
|
|
@@ -64,9 +71,12 @@ def create_numbered_islands(islands, image_shape,
|
|
| 64 |
centroid = _get_centroid(island_coordinates)
|
| 65 |
if not np.isnan(centroid).any():
|
| 66 |
numbered_islands = _add_text_to_image(
|
| 67 |
-
numbered_islands,
|
| 68 |
-
str(color_id),
|
| 69 |
-
centroid
|
|
|
|
|
|
|
|
|
|
| 70 |
)
|
| 71 |
if binary:
|
| 72 |
# Convert numbered_islands to binary using openCV
|
|
|
|
| 1 |
import cv2
|
| 2 |
import numpy as np
|
| 3 |
|
| 4 |
+
from .config import default_config
|
| 5 |
+
|
| 6 |
def _get_centroid(coordinates):
|
| 7 |
rows, cols = coordinates
|
| 8 |
if len(rows) == 0 or len(cols) == 0:
|
|
|
|
| 10 |
return (int(np.mean(rows)), int(np.mean(cols)))
|
| 11 |
|
| 12 |
|
| 13 |
+
def _add_text_to_image(image, text, position, font_size, font_color, font_thickness):
|
| 14 |
"""Add text to an image.
|
| 15 |
|
| 16 |
Args:
|
|
|
|
| 23 |
np.array: A new image with the text added.
|
| 24 |
"""
|
| 25 |
font = cv2.FONT_HERSHEY_SIMPLEX
|
|
|
|
|
|
|
| 26 |
return cv2.putText(
|
| 27 |
image,
|
| 28 |
text,
|
| 29 |
position,
|
| 30 |
font,
|
| 31 |
+
font_size,
|
| 32 |
font_color,
|
| 33 |
font_thickness,
|
| 34 |
cv2.LINE_AA
|
|
|
|
| 37 |
|
| 38 |
def create_numbered_islands(islands, image_shape,
|
| 39 |
centroid_coords_list = None,
|
| 40 |
+
config = default_config,
|
| 41 |
+
show_numbers=True, binary = False):
|
| 42 |
"""Create a new image with the islands numbered.
|
| 43 |
|
| 44 |
Args:
|
|
|
|
| 48 |
Returns:
|
| 49 |
np.array: A new image with the islands numbered.
|
| 50 |
"""
|
| 51 |
+
|
| 52 |
+
padding = config["border_padding"]
|
| 53 |
+
border_color = config["border_color"]
|
| 54 |
+
font_size = config["font_size"]
|
| 55 |
+
font_color = config["font_color"]
|
| 56 |
+
font_thickness = config["font_thickness"]
|
| 57 |
+
|
| 58 |
# Create an all white image
|
| 59 |
width, height, channels = image_shape
|
| 60 |
numbered_islands = np.ones((width + padding*2, height + padding*2, channels),
|
|
|
|
| 71 |
centroid = _get_centroid(island_coordinates)
|
| 72 |
if not np.isnan(centroid).any():
|
| 73 |
numbered_islands = _add_text_to_image(
|
| 74 |
+
image=numbered_islands,
|
| 75 |
+
text=str(color_id),
|
| 76 |
+
position=centroid,
|
| 77 |
+
font_size=font_size,
|
| 78 |
+
font_color=font_color,
|
| 79 |
+
font_thickness=font_thickness
|
| 80 |
)
|
| 81 |
if binary:
|
| 82 |
# Convert numbered_islands to binary using openCV
|
colorbynumber/simplify_image.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import cv2 as cv
|
| 2 |
import numpy as np
|
| 3 |
|
|
|
|
| 4 |
|
| 5 |
def _choose_closest_colors(image, color_list):
|
| 6 |
"""
|
|
@@ -40,8 +41,7 @@ def _denoise_image(image, h):
|
|
| 40 |
|
| 41 |
def simplify_image(image,
|
| 42 |
color_list,
|
| 43 |
-
|
| 44 |
-
denoise_h = 100
|
| 45 |
):
|
| 46 |
"""
|
| 47 |
Converts all colors in an image to the closest color in the color list.
|
|
@@ -54,6 +54,8 @@ def simplify_image(image,
|
|
| 54 |
Returns:
|
| 55 |
A copy of the image with all colors replaced with the closest color in the list.
|
| 56 |
"""
|
|
|
|
|
|
|
| 57 |
|
| 58 |
simplified_image, indices_color_choices = _choose_closest_colors(image, color_list)
|
| 59 |
if denoise:
|
|
|
|
| 1 |
import cv2 as cv
|
| 2 |
import numpy as np
|
| 3 |
|
| 4 |
+
from .config import default_config
|
| 5 |
|
| 6 |
def _choose_closest_colors(image, color_list):
|
| 7 |
"""
|
|
|
|
| 41 |
|
| 42 |
def simplify_image(image,
|
| 43 |
color_list,
|
| 44 |
+
config = default_config,
|
|
|
|
| 45 |
):
|
| 46 |
"""
|
| 47 |
Converts all colors in an image to the closest color in the color list.
|
|
|
|
| 54 |
Returns:
|
| 55 |
A copy of the image with all colors replaced with the closest color in the list.
|
| 56 |
"""
|
| 57 |
+
denoise = config["denoise"]
|
| 58 |
+
denoise_h = config["denoise_h"]
|
| 59 |
|
| 60 |
simplified_image, indices_color_choices = _choose_closest_colors(image, color_list)
|
| 61 |
if denoise:
|
colorbynumber/utils.py
CHANGED
|
@@ -20,3 +20,5 @@ def draw_contours(contour, image_width, image_height):
|
|
| 20 |
cv.drawContours(contours_image, [contour], 0, (0,255,0), 4)
|
| 21 |
show_image(contours_image, cmap = 'gray')
|
| 22 |
|
|
|
|
|
|
|
|
|
| 20 |
cv.drawContours(contours_image, [contour], 0, (0,255,0), 4)
|
| 21 |
show_image(contours_image, cmap = 'gray')
|
| 22 |
|
| 23 |
+
def save_image(image, filename):
|
| 24 |
+
cv.imwrite(filename, image)
|