From 21291d0200142c372bc1ed95c2966e958e598669 Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 11:39:07 -0700 Subject: [PATCH 01/10] refactoring --- trivector/trivector.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/trivector/trivector.py b/trivector/trivector.py index 4ae67f2..0176c46 100644 --- a/trivector/trivector.py +++ b/trivector/trivector.py @@ -4,6 +4,7 @@ """Image conversion functionality for trivector""" from enum import Enum +from typing import List import numpy as np import svgwrite @@ -12,6 +13,17 @@ import progressbar +def bgr_value_average(bgr_values: List[np.ndarray]) -> np.ndarray: + """Compute the average BGR value from an list of BGR arrays + + :param bgr_values: list of BGR arrays + + :return: a single BGR array noting the average BGR values contained within + ``bgr_array`` + """ + return np.sum(bgr_values, axis=0) // len(bgr_values) + + def upper_tri_sum(d3array: np.ndarray) -> np.ndarray: """Get a 3D image array's upper diagonal's pixel color average @@ -24,13 +36,13 @@ def upper_tri_sum(d3array: np.ndarray) -> np.ndarray: 3D image array """ x, y, _ = d3array.shape - tri = [] + tri_elem = [] for i in range(x): if i > y: break for j in range(y - i): - tri.append(d3array[i][i + j]) - return np.sum(tri, axis=0) // len(tri) + tri_elem.append(d3array[i][i + j]) + return bgr_value_average(tri_elem) def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: @@ -50,17 +62,17 @@ def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: 3D image array """ x, y, _ = d3array.shape - tri = [] + tri_elem = [] for i in range(x): if i > y: break for j in range(i): - tri.append(d3array[i][j]) + tri_elem.append(d3array[i][j]) # if bottom tri is empty use the upper tri's sum - if not tri: + if not tri_elem: return upper_tri_sum(d3array) - return np.sum(tri, axis=0) // len(tri) + return bgr_value_average(tri_elem) def vectorize_sector_left(sub_img: np.ndarray, svg_drawing: svgwrite.Drawing, From 084a7ed72eb87c60fd4eb1e90193e50bc21d227f Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 12:44:00 -0700 Subject: [PATCH 02/10] prototyping class structure --- trivector/__init__.py | 3 -- trivector/__main__.py | 13 +++--- trivector/trivector.py | 90 ++++++++++++++++++++++++------------------ 3 files changed, 58 insertions(+), 48 deletions(-) diff --git a/trivector/__init__.py b/trivector/__init__.py index f7e6c38..966c902 100644 --- a/trivector/__init__.py +++ b/trivector/__init__.py @@ -11,7 +11,4 @@ + :mod:`.trivector` - Image conversion functionality for trivector """ -from trivector.trivector import trivector - - __version__ = (1, 1, 1) diff --git a/trivector/__main__.py b/trivector/__main__.py index febdc0d..fa558e5 100644 --- a/trivector/__main__.py +++ b/trivector/__main__.py @@ -6,7 +6,7 @@ import argparse import sys -from trivector.trivector import trivector, DiagonalStyle +from trivector.trivector import TriVectorizer, DiagonalStyle def get_parser(): @@ -24,7 +24,7 @@ def get_parser(): help="size in pixels for each triangle sector") group.add_argument("-d", "--diagonal-style", dest="diagonal_style", type=DiagonalStyle, choices=list(DiagonalStyle), - default=DiagonalStyle.alternating.value, + default=DiagonalStyle.left_alternating.value, help="diagonal arrangement of the triangle sectors") return parser @@ -34,13 +34,14 @@ def main(argv=sys.argv[1:]): parser = get_parser() args = parser.parse_args(argv) - trivector( + tri_vectorizer = TriVectorizer( image_path=args.image, - cut_size=args.sector_size, - output_path=args.output, - diagonal_style=args.diagonal_style + diagonal_style=args.diagonal_style, + sector_size=args.sector_size ) + with open(args.output, "w") as f: + tri_vectorizer.vectorize().write(f) return 0 diff --git a/trivector/trivector.py b/trivector/trivector.py index 0176c46..bafb740 100644 --- a/trivector/trivector.py +++ b/trivector/trivector.py @@ -4,7 +4,7 @@ """Image conversion functionality for trivector""" from enum import Enum -from typing import List +from typing import List, Generator, Tuple import numpy as np import svgwrite @@ -122,51 +122,63 @@ class DiagonalStyle(Enum): triangle sectors""" right = "right" left = "left" - alternating = "alternating" + left_alternating = "left_alternating" + right_alternating = "right_alternating" def __str__(self): return self.value -def trivector(image_path: str, cut_size: int, output_path: str, - diagonal_style: DiagonalStyle = DiagonalStyle.alternating): - """Convert an image into a SVG vector image composed of triangular sectors +class Vectorizer: - :param image_path: path to the image to trivector - :param cut_size: size in pixels for each triangle sector - :param diagonal_style: diagonal arrangement of the triangle sectors - :param output_path: path to write the trivectored image - """ - image = cv2.imread(image_path) # pylint:disable=no-member - - height, width, _ = image.shape + def __init__(self, image_path: str, sector_size: int, **kwargs): + self.image = cv2.imread(image_path) # pylint: disable=no-member + self.sector_size = sector_size - width_slices = range(0, width, cut_size) - height_slices = range(0, height, cut_size) - svg_drawing = svgwrite.Drawing( - output_path, - profile="full", - size=(len(width_slices)*cut_size, len(height_slices)*cut_size) - ) + height, width, _ = self.image.shape + self.width_slices = list(range(0, width, self.sector_size)) + self.height_slices = list(range(0, height, self.sector_size)) + self.svg_drawing = svgwrite.Drawing( + profile="full", + size=(len(self.width_slices)*self.sector_size, + len(self.height_slices)*self.sector_size) + ) - # start up the progress bar - # each image sector is one tick one the progress bar - bar = progressbar.ProgressBar(max_value=len(width_slices)*len(height_slices)) - counter_2 = 0 - sector_num = 0 - for y in height_slices: - counter_1 = counter_2 - counter_2 += 1 - for x in width_slices: - sector_image = image[y:y + cut_size, x:x + cut_size] - if (diagonal_style == DiagonalStyle.left) or \ - (diagonal_style == DiagonalStyle.alternating and counter_1 % 2): - vectorize_sector_left(sector_image, svg_drawing, x, y, cut_size) + def vectorize(self) -> svgwrite.Drawing: + pass + + def get_sector(self, x: int, y: int) -> np.ndarray: + return self.image[y:y + self.sector_size, x:x + self.sector_size] + + @property + def sectors(self) -> Generator[Tuple[int, int, np.ndarray], None, None]: + for y in self.height_slices: + for x in self.width_slices: + yield x, y, self.get_sector(x, y) + + +class TriVectorizer(Vectorizer): + + def __init__(self, diagonal_style: DiagonalStyle = DiagonalStyle.left_alternating, **kwargs): + self.diagonal_style = diagonal_style + super().__init__(**kwargs) + + def vectorize(self) -> svgwrite.Drawing: + for x, y, sector_image in self.sectors: + x_idx = x//self.sector_size + y_idx = y//self.sector_size + # (self.diagonal_style == DiagonalStyle.left_alternating and (x/self.sector_size == 1 and not (y_idx) % 2) or (x/self.sector_size) % 2) or \ # wave + if (self.diagonal_style == DiagonalStyle.left) or \ + (self.diagonal_style == DiagonalStyle.right_alternating and + ((x_idx % 2 and not y_idx % 2) or + (not x_idx % 2 and y_idx % 2))) or \ + (self.diagonal_style == DiagonalStyle.left_alternating and + not ((x_idx % 2 and not y_idx % 2) or + (not x_idx % 2 and y_idx % 2))): + vectorize_sector_left(sector_image, self.svg_drawing, x, y, + self.sector_size) else: sector_image = np.rot90(sector_image, axes=(0, 1)) - vectorize_sector_right(sector_image, svg_drawing, x, y, cut_size) - sector_num += 1 - counter_1 += 1 - bar.update(sector_num) - - svg_drawing.save() + vectorize_sector_right(sector_image, self.svg_drawing, x, y, + self.sector_size) + return self.svg_drawing From 7bfd9a4f672e6c8e9bf43849e1d707c64a9e45fa Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 13:02:09 -0700 Subject: [PATCH 03/10] adding square and circle vectorizers --- trivector/trivector.py | 45 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/trivector/trivector.py b/trivector/trivector.py index bafb740..8f689cd 100644 --- a/trivector/trivector.py +++ b/trivector/trivector.py @@ -11,6 +11,7 @@ import cv2 import progressbar +from svgwrite.shapes import Rect, Circle def bgr_value_average(bgr_values: List[np.ndarray]) -> np.ndarray: @@ -158,7 +159,6 @@ def sectors(self) -> Generator[Tuple[int, int, np.ndarray], None, None]: class TriVectorizer(Vectorizer): - def __init__(self, diagonal_style: DiagonalStyle = DiagonalStyle.left_alternating, **kwargs): self.diagonal_style = diagonal_style super().__init__(**kwargs) @@ -182,3 +182,46 @@ def vectorize(self) -> svgwrite.Drawing: vectorize_sector_right(sector_image, self.svg_drawing, x, y, self.sector_size) return self.svg_drawing + + +def square_vectorize_sector(sector_image: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): + b, g, r = np.average(sector_image, (0, 1)) + svg_drawing.add( + Rect( + insert=(x, y), + size=(sector_size, sector_size), + fill=svgwrite.rgb(r, g, b, "RGB") + ) + ) + + +class SquareVectorizer(Vectorizer): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def vectorize(self): + for x, y, sector_image in self.sectors: + square_vectorize_sector(sector_image, self.svg_drawing, x, y, self.sector_size) + return self.svg_drawing + + +def circle_vectorize_sector(sector_image: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): + b, g, r = np.average(sector_image, (0, 1)) + svg_drawing.add( + Circle( + center=(x + (sector_size / 2), y + (sector_size / 2)), + r=sector_size / 1.3, + fill=svgwrite.rgb(r, g, b, "RGB") + ) + ) + + +class CircleVectorizer(Vectorizer): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def vectorize(self): + for x, y, sector_image in self.sectors: + circle_vectorize_sector( + sector_image, self.svg_drawing, x, y, self.sector_size) + return self.svg_drawing From adc603ced20f16a46e782a915143ae39a7eede71 Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 13:09:07 -0700 Subject: [PATCH 04/10] refactoring --- trivector/trivector.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/trivector/trivector.py b/trivector/trivector.py index 8f689cd..710f3f7 100644 --- a/trivector/trivector.py +++ b/trivector/trivector.py @@ -10,7 +10,6 @@ import svgwrite import cv2 -import progressbar from svgwrite.shapes import Rect, Circle @@ -131,7 +130,6 @@ def __str__(self): class Vectorizer: - def __init__(self, image_path: str, sector_size: int, **kwargs): self.image = cv2.imread(image_path) # pylint: disable=no-member self.sector_size = sector_size From 7997a010e8837677727cc084b520d7d90b560c15 Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 13:35:59 -0700 Subject: [PATCH 05/10] refactoring --- trivector/{trivector.py => vectorizer.py} | 48 ++++++++++++++--------- 1 file changed, 29 insertions(+), 19 deletions(-) rename trivector/{trivector.py => vectorizer.py} (78%) diff --git a/trivector/trivector.py b/trivector/vectorizer.py similarity index 78% rename from trivector/trivector.py rename to trivector/vectorizer.py index 710f3f7..e6eec22 100644 --- a/trivector/trivector.py +++ b/trivector/vectorizer.py @@ -75,43 +75,46 @@ def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: return bgr_value_average(tri_elem) -def vectorize_sector_left(sub_img: np.ndarray, svg_drawing: svgwrite.Drawing, - x: int, y: int, cut_size: int): +def vectorize_sector_left(sub_img: np.ndarray, + svg_drawing: svgwrite.Drawing, + x: int, y: int, sector_size: int): """Add two triangles to ``svg_drawing`` whose colors are derived from the color averages from the top and bottom diagonals of the 3D BGR image array of the sub image""" b, g, r = upper_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( - [(x, y), (x + cut_size, y), (x + cut_size, y + cut_size)], + [(x, y), (x + sector_size, y), (x + sector_size, y + sector_size)], fill=svgwrite.rgb(r, g, b, "RGB") ) ) b, g, r = lower_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( - [(x, y), (x, y + cut_size), (x + cut_size, y + cut_size)], + [(x, y), (x, y + sector_size), (x + sector_size, y + sector_size)], fill=svgwrite.rgb(r, g, b, "RGB") ) ) -def vectorize_sector_right(sub_img: np.ndarray, svg_drawing: svgwrite.Drawing, - x: int, y: int, cut_size: int): +def vectorize_sector_right(sub_img: np.ndarray, + svg_drawing: svgwrite.Drawing, + x: int, y: int, sector_size: int): """Add two triangles to ``svg_drawing`` whose colors are derived from the color averages from the top and bottom diagonals of the 3D BGR image array of the sub image""" + sub_img = np.rot90(sub_img, axes=(0, 1)) b, g, r = upper_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( - [(x, y + cut_size), (x + cut_size, y + cut_size), (x + cut_size, y)], + [(x, y + sector_size), (x + sector_size, y + sector_size), (x + sector_size, y)], fill=svgwrite.rgb(r, g, b, "RGB") ) ) b, g, r = lower_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( - [(x, y + cut_size), (x, y), (x + cut_size, y)], + [(x, y + sector_size), (x, y), (x + sector_size, y)], fill=svgwrite.rgb(r, g, b, "RGB") ) ) @@ -163,26 +166,30 @@ def __init__(self, diagonal_style: DiagonalStyle = DiagonalStyle.left_alternatin def vectorize(self) -> svgwrite.Drawing: for x, y, sector_image in self.sectors: - x_idx = x//self.sector_size - y_idx = y//self.sector_size + x_idx = x // self.sector_size + y_idx = y // self.sector_size # (self.diagonal_style == DiagonalStyle.left_alternating and (x/self.sector_size == 1 and not (y_idx) % 2) or (x/self.sector_size) % 2) or \ # wave - if (self.diagonal_style == DiagonalStyle.left) or \ - (self.diagonal_style == DiagonalStyle.right_alternating and + if self.diagonal_style == DiagonalStyle.right: + vectorize_sector_right(sector_image, self.svg_drawing, x, y, + self.sector_size) + elif (self.diagonal_style == DiagonalStyle.left) or \ + (self.diagonal_style == DiagonalStyle.right_alternating and ((x_idx % 2 and not y_idx % 2) or (not x_idx % 2 and y_idx % 2))) or \ - (self.diagonal_style == DiagonalStyle.left_alternating and + (self.diagonal_style == DiagonalStyle.left_alternating and not ((x_idx % 2 and not y_idx % 2) or (not x_idx % 2 and y_idx % 2))): vectorize_sector_left(sector_image, self.svg_drawing, x, y, self.sector_size) else: - sector_image = np.rot90(sector_image, axes=(0, 1)) vectorize_sector_right(sector_image, self.svg_drawing, x, y, self.sector_size) return self.svg_drawing -def square_vectorize_sector(sector_image: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): +def square_vectorize_sector(sector_image: np.ndarray, + svg_drawing: svgwrite.Drawing, + x: int, y: int, sector_size: int): b, g, r = np.average(sector_image, (0, 1)) svg_drawing.add( Rect( @@ -197,13 +204,16 @@ class SquareVectorizer(Vectorizer): def __init__(self, **kwargs): super().__init__(**kwargs) - def vectorize(self): + def vectorize(self) -> svgwrite.Drawing: for x, y, sector_image in self.sectors: - square_vectorize_sector(sector_image, self.svg_drawing, x, y, self.sector_size) + square_vectorize_sector( + sector_image, self.svg_drawing, x, y, self.sector_size) return self.svg_drawing -def circle_vectorize_sector(sector_image: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): +def circle_vectorize_sector(sector_image: np.ndarray, + svg_drawing: svgwrite.Drawing, + x: int, y: int, sector_size: int): b, g, r = np.average(sector_image, (0, 1)) svg_drawing.add( Circle( @@ -218,7 +228,7 @@ class CircleVectorizer(Vectorizer): def __init__(self, **kwargs): super().__init__(**kwargs) - def vectorize(self): + def vectorize(self) -> svgwrite.Drawing: for x, y, sector_image in self.sectors: circle_vectorize_sector( sector_image, self.svg_drawing, x, y, self.sector_size) From 094b4572296c792e08414d23a0d3f36cf5b65dcc Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 14:47:36 -0700 Subject: [PATCH 06/10] fixing import --- trivector/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trivector/__main__.py b/trivector/__main__.py index fa558e5..0360fce 100644 --- a/trivector/__main__.py +++ b/trivector/__main__.py @@ -6,7 +6,7 @@ import argparse import sys -from trivector.trivector import TriVectorizer, DiagonalStyle +from trivector.vectorizer import TriVectorizer, DiagonalStyle def get_parser(): From 007f219075d45fee1f3ae0f9af652cdb39534c7b Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 15:21:30 -0700 Subject: [PATCH 07/10] simplifying code --- trivector/vectorizer.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/trivector/vectorizer.py b/trivector/vectorizer.py index e6eec22..aa46a00 100644 --- a/trivector/vectorizer.py +++ b/trivector/vectorizer.py @@ -13,17 +13,6 @@ from svgwrite.shapes import Rect, Circle -def bgr_value_average(bgr_values: List[np.ndarray]) -> np.ndarray: - """Compute the average BGR value from an list of BGR arrays - - :param bgr_values: list of BGR arrays - - :return: a single BGR array noting the average BGR values contained within - ``bgr_array`` - """ - return np.sum(bgr_values, axis=0) // len(bgr_values) - - def upper_tri_sum(d3array: np.ndarray) -> np.ndarray: """Get a 3D image array's upper diagonal's pixel color average @@ -42,7 +31,7 @@ def upper_tri_sum(d3array: np.ndarray) -> np.ndarray: break for j in range(y - i): tri_elem.append(d3array[i][i + j]) - return bgr_value_average(tri_elem) + return np.average(tri_elem, axis=0) def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: @@ -72,7 +61,7 @@ def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: # if bottom tri is empty use the upper tri's sum if not tri_elem: return upper_tri_sum(d3array) - return bgr_value_average(tri_elem) + return np.average(tri_elem, axis=0) def vectorize_sector_left(sub_img: np.ndarray, From 4121c2502927eeef2e309c09ddfb78a845bc4d4a Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 15:35:02 -0700 Subject: [PATCH 08/10] no more BGR --- trivector/vectorizer.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/trivector/vectorizer.py b/trivector/vectorizer.py index aa46a00..6821f9f 100644 --- a/trivector/vectorizer.py +++ b/trivector/vectorizer.py @@ -4,7 +4,7 @@ """Image conversion functionality for trivector""" from enum import Enum -from typing import List, Generator, Tuple +from typing import Generator, Tuple import numpy as np import svgwrite @@ -18,10 +18,10 @@ def upper_tri_sum(d3array: np.ndarray) -> np.ndarray: :param d3array: 3D image array derived from :func:`cv2.imread` - Treat the 3D array as 2d array. Having the innermost array (pixel BGR + Treat the 3D array as 2d array. Having the innermost array (pixel RGB values) be considered base values to be averaged. - :return: BGR array of the average color of the upper diagonal of the + :return: RGB array of the average color of the upper diagonal of the 3D image array """ x, y, _ = d3array.shape @@ -39,7 +39,7 @@ def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: :param d3array: 3D image array derived from :func:`cv2.imread` - Treat the 3D array as 2d array. Having the innermost array (pixel BGR + Treat the 3D array as 2d array. Having the innermost array (pixel RGB values) be considered base values to be averaged. .. note:: @@ -47,7 +47,7 @@ def lower_tri_sum(d3array: np.ndarray) -> np.ndarray: If the lower diagonal cannot be computed (eg: flat/malformed 3D array) use the 3D image array's upper diagonal's pixel color average instead. - :return: BGR array of the average color of the lower diagonal of the + :return: RGB array of the average color of the lower diagonal of the 3D image array """ x, y, _ = d3array.shape @@ -68,16 +68,16 @@ def vectorize_sector_left(sub_img: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): """Add two triangles to ``svg_drawing`` whose colors are derived from - the color averages from the top and bottom diagonals of the 3D BGR image + the color averages from the top and bottom diagonals of the 3D RGB image array of the sub image""" - b, g, r = upper_tri_sum(sub_img) + r, g, b = upper_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( [(x, y), (x + sector_size, y), (x + sector_size, y + sector_size)], fill=svgwrite.rgb(r, g, b, "RGB") ) ) - b, g, r = lower_tri_sum(sub_img) + r, g, b = lower_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( [(x, y), (x, y + sector_size), (x + sector_size, y + sector_size)], @@ -90,17 +90,17 @@ def vectorize_sector_right(sub_img: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): """Add two triangles to ``svg_drawing`` whose colors are derived from - the color averages from the top and bottom diagonals of the 3D BGR image + the color averages from the top and bottom diagonals of the 3D RGB image array of the sub image""" sub_img = np.rot90(sub_img, axes=(0, 1)) - b, g, r = upper_tri_sum(sub_img) + r, g, b = upper_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( [(x, y + sector_size), (x + sector_size, y + sector_size), (x + sector_size, y)], fill=svgwrite.rgb(r, g, b, "RGB") ) ) - b, g, r = lower_tri_sum(sub_img) + r, g, b = lower_tri_sum(sub_img) svg_drawing.add( svg_drawing.polygon( [(x, y + sector_size), (x, y), (x + sector_size, y)], @@ -123,7 +123,7 @@ def __str__(self): class Vectorizer: def __init__(self, image_path: str, sector_size: int, **kwargs): - self.image = cv2.imread(image_path) # pylint: disable=no-member + self.image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_RGB2RGB) # pylint: disable=no-member self.sector_size = sector_size height, width, _ = self.image.shape @@ -179,7 +179,7 @@ def vectorize(self) -> svgwrite.Drawing: def square_vectorize_sector(sector_image: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): - b, g, r = np.average(sector_image, (0, 1)) + r, g, b = np.average(sector_image, (0, 1)) svg_drawing.add( Rect( insert=(x, y), @@ -203,7 +203,7 @@ def vectorize(self) -> svgwrite.Drawing: def circle_vectorize_sector(sector_image: np.ndarray, svg_drawing: svgwrite.Drawing, x: int, y: int, sector_size: int): - b, g, r = np.average(sector_image, (0, 1)) + r, g, b = np.average(sector_image, (0, 1)) svg_drawing.add( Circle( center=(x + (sector_size / 2), y + (sector_size / 2)), From 852ff49716f7b33a315b70a189baedc555a65e5f Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 15:36:20 -0700 Subject: [PATCH 09/10] no more BGR --- trivector/vectorizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trivector/vectorizer.py b/trivector/vectorizer.py index 6821f9f..64ff03c 100644 --- a/trivector/vectorizer.py +++ b/trivector/vectorizer.py @@ -123,7 +123,7 @@ def __str__(self): class Vectorizer: def __init__(self, image_path: str, sector_size: int, **kwargs): - self.image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_RGB2RGB) # pylint: disable=no-member + self.image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB) # pylint: disable=no-member self.sector_size = sector_size height, width, _ = self.image.shape From d8507be17e930dfd1e0779d31be0c29b4a88be2d Mon Sep 17 00:00:00 2001 From: Nathan Klapstein Date: Thu, 28 Feb 2019 15:48:25 -0700 Subject: [PATCH 10/10] refactoring --- trivector/vectorizer.py | 54 ++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/trivector/vectorizer.py b/trivector/vectorizer.py index 64ff03c..7b64c30 100644 --- a/trivector/vectorizer.py +++ b/trivector/vectorizer.py @@ -13,6 +13,33 @@ from svgwrite.shapes import Rect, Circle +class Vectorizer: + def __init__(self, image_path: str, sector_size: int, **kwargs): + self.image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB) # pylint: disable=no-member + self.sector_size = sector_size + + height, width, _ = self.image.shape + self.width_slices = list(range(0, width, self.sector_size)) + self.height_slices = list(range(0, height, self.sector_size)) + self.svg_drawing = svgwrite.Drawing( + profile="full", + size=(len(self.width_slices)*self.sector_size, + len(self.height_slices)*self.sector_size) + ) + + def vectorize(self) -> svgwrite.Drawing: + pass + + def get_sector(self, x: int, y: int) -> np.ndarray: + return self.image[y:y + self.sector_size, x:x + self.sector_size] + + @property + def sectors(self) -> Generator[Tuple[int, int, np.ndarray], None, None]: + for y in self.height_slices: + for x in self.width_slices: + yield x, y, self.get_sector(x, y) + + def upper_tri_sum(d3array: np.ndarray) -> np.ndarray: """Get a 3D image array's upper diagonal's pixel color average @@ -121,33 +148,6 @@ def __str__(self): return self.value -class Vectorizer: - def __init__(self, image_path: str, sector_size: int, **kwargs): - self.image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB) # pylint: disable=no-member - self.sector_size = sector_size - - height, width, _ = self.image.shape - self.width_slices = list(range(0, width, self.sector_size)) - self.height_slices = list(range(0, height, self.sector_size)) - self.svg_drawing = svgwrite.Drawing( - profile="full", - size=(len(self.width_slices)*self.sector_size, - len(self.height_slices)*self.sector_size) - ) - - def vectorize(self) -> svgwrite.Drawing: - pass - - def get_sector(self, x: int, y: int) -> np.ndarray: - return self.image[y:y + self.sector_size, x:x + self.sector_size] - - @property - def sectors(self) -> Generator[Tuple[int, int, np.ndarray], None, None]: - for y in self.height_slices: - for x in self.width_slices: - yield x, y, self.get_sector(x, y) - - class TriVectorizer(Vectorizer): def __init__(self, diagonal_style: DiagonalStyle = DiagonalStyle.left_alternating, **kwargs): self.diagonal_style = diagonal_style