pixelator.pixelator

  1import cv2, numpy, type_enforced
  2
  3
  4class Picture_Utils:
  5    @staticmethod
  6    def crop_image(image: list, width: int, height: int):
  7        """
  8        Crops an image to a specified width and height (centered)
  9
 10        Takes in three required arguments:
 11
 12            - 'image':
 13                - Type: list of lists
 14                - What: CV2 image data
 15            - 'width':
 16                - Type: int
 17                - What: The width in pixels for the output image
 18            - 'height':
 19                - Type: int
 20                - What: The height in pixels for the output image
 21        """
 22        (h, w) = image.shape[:2]
 23        if width > w or height > h:
 24            raise Exception("Cannot crop an image larger")
 25        h_start = (h - height) // 2
 26        h_end = h_start + height
 27        w_start = (w - width) // 2
 28        w_end = w_start + width
 29        return image[h_start:h_end, w_start:w_end]
 30
 31    @staticmethod
 32    def crop_to_aspect_ratio(image: list, aspect_ratio_w_by_h: [int, float]):
 33        """
 34        Crops an image to a specified aspect ratio
 35
 36        Takes in two required arguments:
 37
 38            - 'image':
 39                - Type: list of lists
 40                - What: CV2 image data
 41            - 'aspect_ratio_w_by_h':
 42                - Type: int | float
 43                - What: The aspect ratio for the cropped image
 44        """
 45        (h, w) = image.shape[:2]
 46        aspect_ratio_current = w / h
 47        if aspect_ratio_w_by_h == aspect_ratio_current:
 48            return image
 49        new_h = int(w / aspect_ratio_w_by_h)
 50        new_w = int(h * aspect_ratio_w_by_h)
 51        if new_h < h:
 52            return Picture_Utils.crop_image(image, width=w, height=new_h)
 53        if new_w < w:
 54            return Picture_Utils.crop_image(image, width=new_w, height=h)
 55        raise Exception("Invalid aspect_ratio_w_by_h")
 56
 57    @staticmethod
 58    def resize(
 59        image: list, width: int, height: int, interpolation=cv2.INTER_AREA
 60    ):
 61        """
 62        Resizes an image to a specified width and height
 63
 64        Takes in three required arguments:
 65
 66            - 'image':
 67                - Type: list of lists
 68                - What: CV2 image data
 69            - 'width':
 70                - Type: int
 71                - What: The width in pixels for the output image
 72            - 'height':
 73                - Type: int
 74                - What: The height in pixels for the output image
 75        """
 76        image = Picture_Utils.crop_to_aspect_ratio(image, width / height)
 77        return cv2.resize(image, (width, height), interpolation=interpolation)
 78
 79    @staticmethod
 80    def quantize_to_palette(image: list, palette: list):
 81        """
 82        Quantizes an image to a given palette
 83
 84        Takes in two required arguments:
 85
 86            - 'image':
 87                - Type: list of lists
 88                - What: CV2 image data
 89            - 'palette':
 90                - Type: list of lists
 91                - What: A list of BGR lists for quantizing the image
 92        """
 93        image = image.astype(numpy.int16)
 94        quantized_image = numpy.zeros_like(image)
 95        palette = numpy.array(palette, dtype=numpy.int16)
 96        for i in range(image.shape[0]):
 97            for j in range(image.shape[1]):
 98                quantized_image[i, j] = palette[
 99                    numpy.argmin(
100                        numpy.sum(
101                            numpy.absolute((palette - image[i, j])), axis=1
102                        )
103                    )
104                ]
105        return quantized_image.astype(numpy.uint8)
106
107    @staticmethod
108    def capture(cam_port: int = 0):
109        """
110        Uses an attached camera or webcam to capture its input at the time of calling
111
112        Takes in one optional argument:
113
114            - 'cam_port':
115                - Type: int
116                - What: The camera port to use for a capture
117                - Default: 0
118                - Note: For more info see the docs for cv2.VideoCapture.
119        """
120        cam = cv2.VideoCapture(cam_port)
121        try:
122            result, image = cam.read()
123            cam.release()
124        except Exception as e:
125            cam.release()
126            raise Exception(e)
127        return image
128
129    @staticmethod
130    def to_colorscheme(image: list, colorscheme: str = "bgr"):
131        """
132        Converts an image to an alternate colorscheme
133
134        Takes in one required argument:
135
136            - 'image':
137                - Type: list of lists
138                - What: CV2 image data
139
140        Takes in one optional argument:
141
142            - 'colorscheme':
143                - Type: str
144                - What: The color scheme to convert
145                - Options: ['bgr', 'rgb', 'gray', 'hsv']
146                - Default: 'bgr'
147
148        """
149        colorscheme = str(colorscheme).lower()
150        if colorscheme == "bgr":
151            return image
152        if colorscheme == "rgb":
153            return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
154        if colorscheme == "gray":
155            return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
156        if colorscheme == "hsv":
157            return cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
158
159    @staticmethod
160    def read(filename: str):
161        """
162        Reads a picture into CV2 image data
163
164        Requires one argument:
165
166            - 'filename':
167                - Type: str
168                - What: Filename from which to load a picture
169        """
170        return cv2.imread(filename)
171
172
173@type_enforced.Enforcer
174class Pixelator(Picture_Utils):
175    def __init__(
176        self,
177        data: [numpy.ndarray, list, None] = None,
178        filename: [str, None] = None,
179        cam_port: int = 0,
180    ):
181        """
182        Initialize a Pixelator object.
183
184        Takes in three optional arguments:
185
186            - 'data':
187                - Type: list of lists
188                - What: BGR array of data to input
189                - Note: If not specified, proceeds to attempt to load from a filename
190            - 'filename':
191                - Type: str
192                - What: Filename from which to load a picture
193                - Note: If not specified, proceeds to attempt a camera capture
194            - 'cam_port':
195                - Type: int
196                - What: The camera port to use for a capture
197                - Note: For more info see the docs for cv2.VideoCapture.
198        """
199        if data is not None:
200            self.data = data
201        elif filename is not None:
202            self.data = self.read(filename)
203        else:
204            self.data = self.capture(cam_port)
205
206    def pixelate(
207        self,
208        width: [int, None] = None,
209        height: [int, None] = None,
210        palette: [numpy.ndarray, list, None] = None,
211    ):
212        """
213        Pixelates an image to a specific shape and color palette
214
215        Returns a new Pixelator (class) image
216
217        Takes in three optional arguments:
218
219            - 'width':
220                - Type: int
221                - What: The width in pixels for the output image
222                - Note: If either 'width' or 'height' are not specified, this function only applies the palette
223            - 'height':
224                - Type: int
225                - What: The height in pixels for the output image
226                - Note: If either 'width' or 'height' are not specified, this function only applies the palette
227            - 'palette':
228                - Type: list of lists
229                - What: A list of BGR lists to apply as a pallete
230                - Note: If not specified, no palette is applied
231        """
232        out = self.resize(image=self.data, width=width, height=height)
233        if palette is not None:
234            out = self.quantize_to_palette(out, palette)
235        return Pixelator(data=out)
236
237    def write(
238        self,
239        filename: str,
240        width: [int, None] = None,
241        height: [int, None] = None,
242    ):
243        """
244        Writes the current image to a specific file and resizes to a given width and height if supplied
245
246        Takes in one required argument:
247
248            - 'filename':
249                - Type: str
250                - What: Filename at which to write the picture
251
252        Takes in two optional arguments:
253
254            - 'width':
255                - Type: int
256                - What: The width in pixels for the output image
257                - Note: If either 'width' or 'height' are not specified, no resizing is done
258            - 'height':
259                - Type: int
260                - What: The height in pixels for the output image
261                - Note: If either 'width' or 'height' are not specified, no resizing is done
262        """
263        if width == None or height == None:
264            (height, width) = self.data.shape[:2]
265        cv2.imwrite(
266            filename, self.resize(self.data, width, height).astype(numpy.uint8)
267        )
268
269    def get_color_counts(self):
270        """
271        Gets the counts of each color in the image
272
273        Returns a dictionary of color counts where:
274            - The keys are the tuples of the colors
275            - The values are the counts of each color
276
277        EG: {(255, 255, 255): 100, (0, 0, 0): 50}
278        """
279        colors, count = numpy.unique(
280            self.data.reshape(-1, self.data.shape[-1]),
281            axis=0,
282            return_counts=True,
283        )
284        # Force all items in colors to be integers
285        colors = colors.astype(int)
286        return dict(zip([tuple(color) for color in colors], count))
class Picture_Utils:
  5class Picture_Utils:
  6    @staticmethod
  7    def crop_image(image: list, width: int, height: int):
  8        """
  9        Crops an image to a specified width and height (centered)
 10
 11        Takes in three required arguments:
 12
 13            - 'image':
 14                - Type: list of lists
 15                - What: CV2 image data
 16            - 'width':
 17                - Type: int
 18                - What: The width in pixels for the output image
 19            - 'height':
 20                - Type: int
 21                - What: The height in pixels for the output image
 22        """
 23        (h, w) = image.shape[:2]
 24        if width > w or height > h:
 25            raise Exception("Cannot crop an image larger")
 26        h_start = (h - height) // 2
 27        h_end = h_start + height
 28        w_start = (w - width) // 2
 29        w_end = w_start + width
 30        return image[h_start:h_end, w_start:w_end]
 31
 32    @staticmethod
 33    def crop_to_aspect_ratio(image: list, aspect_ratio_w_by_h: [int, float]):
 34        """
 35        Crops an image to a specified aspect ratio
 36
 37        Takes in two required arguments:
 38
 39            - 'image':
 40                - Type: list of lists
 41                - What: CV2 image data
 42            - 'aspect_ratio_w_by_h':
 43                - Type: int | float
 44                - What: The aspect ratio for the cropped image
 45        """
 46        (h, w) = image.shape[:2]
 47        aspect_ratio_current = w / h
 48        if aspect_ratio_w_by_h == aspect_ratio_current:
 49            return image
 50        new_h = int(w / aspect_ratio_w_by_h)
 51        new_w = int(h * aspect_ratio_w_by_h)
 52        if new_h < h:
 53            return Picture_Utils.crop_image(image, width=w, height=new_h)
 54        if new_w < w:
 55            return Picture_Utils.crop_image(image, width=new_w, height=h)
 56        raise Exception("Invalid aspect_ratio_w_by_h")
 57
 58    @staticmethod
 59    def resize(
 60        image: list, width: int, height: int, interpolation=cv2.INTER_AREA
 61    ):
 62        """
 63        Resizes an image to a specified width and height
 64
 65        Takes in three required arguments:
 66
 67            - 'image':
 68                - Type: list of lists
 69                - What: CV2 image data
 70            - 'width':
 71                - Type: int
 72                - What: The width in pixels for the output image
 73            - 'height':
 74                - Type: int
 75                - What: The height in pixels for the output image
 76        """
 77        image = Picture_Utils.crop_to_aspect_ratio(image, width / height)
 78        return cv2.resize(image, (width, height), interpolation=interpolation)
 79
 80    @staticmethod
 81    def quantize_to_palette(image: list, palette: list):
 82        """
 83        Quantizes an image to a given palette
 84
 85        Takes in two required arguments:
 86
 87            - 'image':
 88                - Type: list of lists
 89                - What: CV2 image data
 90            - 'palette':
 91                - Type: list of lists
 92                - What: A list of BGR lists for quantizing the image
 93        """
 94        image = image.astype(numpy.int16)
 95        quantized_image = numpy.zeros_like(image)
 96        palette = numpy.array(palette, dtype=numpy.int16)
 97        for i in range(image.shape[0]):
 98            for j in range(image.shape[1]):
 99                quantized_image[i, j] = palette[
100                    numpy.argmin(
101                        numpy.sum(
102                            numpy.absolute((palette - image[i, j])), axis=1
103                        )
104                    )
105                ]
106        return quantized_image.astype(numpy.uint8)
107
108    @staticmethod
109    def capture(cam_port: int = 0):
110        """
111        Uses an attached camera or webcam to capture its input at the time of calling
112
113        Takes in one optional argument:
114
115            - 'cam_port':
116                - Type: int
117                - What: The camera port to use for a capture
118                - Default: 0
119                - Note: For more info see the docs for cv2.VideoCapture.
120        """
121        cam = cv2.VideoCapture(cam_port)
122        try:
123            result, image = cam.read()
124            cam.release()
125        except Exception as e:
126            cam.release()
127            raise Exception(e)
128        return image
129
130    @staticmethod
131    def to_colorscheme(image: list, colorscheme: str = "bgr"):
132        """
133        Converts an image to an alternate colorscheme
134
135        Takes in one required argument:
136
137            - 'image':
138                - Type: list of lists
139                - What: CV2 image data
140
141        Takes in one optional argument:
142
143            - 'colorscheme':
144                - Type: str
145                - What: The color scheme to convert
146                - Options: ['bgr', 'rgb', 'gray', 'hsv']
147                - Default: 'bgr'
148
149        """
150        colorscheme = str(colorscheme).lower()
151        if colorscheme == "bgr":
152            return image
153        if colorscheme == "rgb":
154            return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
155        if colorscheme == "gray":
156            return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
157        if colorscheme == "hsv":
158            return cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
159
160    @staticmethod
161    def read(filename: str):
162        """
163        Reads a picture into CV2 image data
164
165        Requires one argument:
166
167            - 'filename':
168                - Type: str
169                - What: Filename from which to load a picture
170        """
171        return cv2.imread(filename)
@staticmethod
def crop_image(image: list, width: int, height: int):
 6    @staticmethod
 7    def crop_image(image: list, width: int, height: int):
 8        """
 9        Crops an image to a specified width and height (centered)
10
11        Takes in three required arguments:
12
13            - 'image':
14                - Type: list of lists
15                - What: CV2 image data
16            - 'width':
17                - Type: int
18                - What: The width in pixels for the output image
19            - 'height':
20                - Type: int
21                - What: The height in pixels for the output image
22        """
23        (h, w) = image.shape[:2]
24        if width > w or height > h:
25            raise Exception("Cannot crop an image larger")
26        h_start = (h - height) // 2
27        h_end = h_start + height
28        w_start = (w - width) // 2
29        w_end = w_start + width
30        return image[h_start:h_end, w_start:w_end]

Crops an image to a specified width and height (centered)

Takes in three required arguments:

- 'image':
    - Type: list of lists
    - What: CV2 image data
- 'width':
    - Type: int
    - What: The width in pixels for the output image
- 'height':
    - Type: int
    - What: The height in pixels for the output image
@staticmethod
def crop_to_aspect_ratio(image: list, aspect_ratio_w_by_h: [<class 'int'>, <class 'float'>]):
32    @staticmethod
33    def crop_to_aspect_ratio(image: list, aspect_ratio_w_by_h: [int, float]):
34        """
35        Crops an image to a specified aspect ratio
36
37        Takes in two required arguments:
38
39            - 'image':
40                - Type: list of lists
41                - What: CV2 image data
42            - 'aspect_ratio_w_by_h':
43                - Type: int | float
44                - What: The aspect ratio for the cropped image
45        """
46        (h, w) = image.shape[:2]
47        aspect_ratio_current = w / h
48        if aspect_ratio_w_by_h == aspect_ratio_current:
49            return image
50        new_h = int(w / aspect_ratio_w_by_h)
51        new_w = int(h * aspect_ratio_w_by_h)
52        if new_h < h:
53            return Picture_Utils.crop_image(image, width=w, height=new_h)
54        if new_w < w:
55            return Picture_Utils.crop_image(image, width=new_w, height=h)
56        raise Exception("Invalid aspect_ratio_w_by_h")

Crops an image to a specified aspect ratio

Takes in two required arguments:

- 'image':
    - Type: list of lists
    - What: CV2 image data
- 'aspect_ratio_w_by_h':
    - Type: int | float
    - What: The aspect ratio for the cropped image
@staticmethod
def resize(image: list, width: int, height: int, interpolation=3):
58    @staticmethod
59    def resize(
60        image: list, width: int, height: int, interpolation=cv2.INTER_AREA
61    ):
62        """
63        Resizes an image to a specified width and height
64
65        Takes in three required arguments:
66
67            - 'image':
68                - Type: list of lists
69                - What: CV2 image data
70            - 'width':
71                - Type: int
72                - What: The width in pixels for the output image
73            - 'height':
74                - Type: int
75                - What: The height in pixels for the output image
76        """
77        image = Picture_Utils.crop_to_aspect_ratio(image, width / height)
78        return cv2.resize(image, (width, height), interpolation=interpolation)

Resizes an image to a specified width and height

Takes in three required arguments:

- 'image':
    - Type: list of lists
    - What: CV2 image data
- 'width':
    - Type: int
    - What: The width in pixels for the output image
- 'height':
    - Type: int
    - What: The height in pixels for the output image
@staticmethod
def quantize_to_palette(image: list, palette: list):
 80    @staticmethod
 81    def quantize_to_palette(image: list, palette: list):
 82        """
 83        Quantizes an image to a given palette
 84
 85        Takes in two required arguments:
 86
 87            - 'image':
 88                - Type: list of lists
 89                - What: CV2 image data
 90            - 'palette':
 91                - Type: list of lists
 92                - What: A list of BGR lists for quantizing the image
 93        """
 94        image = image.astype(numpy.int16)
 95        quantized_image = numpy.zeros_like(image)
 96        palette = numpy.array(palette, dtype=numpy.int16)
 97        for i in range(image.shape[0]):
 98            for j in range(image.shape[1]):
 99                quantized_image[i, j] = palette[
100                    numpy.argmin(
101                        numpy.sum(
102                            numpy.absolute((palette - image[i, j])), axis=1
103                        )
104                    )
105                ]
106        return quantized_image.astype(numpy.uint8)

Quantizes an image to a given palette

Takes in two required arguments:

- 'image':
    - Type: list of lists
    - What: CV2 image data
- 'palette':
    - Type: list of lists
    - What: A list of BGR lists for quantizing the image
@staticmethod
def capture(cam_port: int = 0):
108    @staticmethod
109    def capture(cam_port: int = 0):
110        """
111        Uses an attached camera or webcam to capture its input at the time of calling
112
113        Takes in one optional argument:
114
115            - 'cam_port':
116                - Type: int
117                - What: The camera port to use for a capture
118                - Default: 0
119                - Note: For more info see the docs for cv2.VideoCapture.
120        """
121        cam = cv2.VideoCapture(cam_port)
122        try:
123            result, image = cam.read()
124            cam.release()
125        except Exception as e:
126            cam.release()
127            raise Exception(e)
128        return image

Uses an attached camera or webcam to capture its input at the time of calling

Takes in one optional argument:

- 'cam_port':
    - Type: int
    - What: The camera port to use for a capture
    - Default: 0
    - Note: For more info see the docs for cv2.VideoCapture.
@staticmethod
def to_colorscheme(image: list, colorscheme: str = 'bgr'):
130    @staticmethod
131    def to_colorscheme(image: list, colorscheme: str = "bgr"):
132        """
133        Converts an image to an alternate colorscheme
134
135        Takes in one required argument:
136
137            - 'image':
138                - Type: list of lists
139                - What: CV2 image data
140
141        Takes in one optional argument:
142
143            - 'colorscheme':
144                - Type: str
145                - What: The color scheme to convert
146                - Options: ['bgr', 'rgb', 'gray', 'hsv']
147                - Default: 'bgr'
148
149        """
150        colorscheme = str(colorscheme).lower()
151        if colorscheme == "bgr":
152            return image
153        if colorscheme == "rgb":
154            return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
155        if colorscheme == "gray":
156            return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
157        if colorscheme == "hsv":
158            return cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

Converts an image to an alternate colorscheme

Takes in one required argument:

- 'image':
    - Type: list of lists
    - What: CV2 image data

Takes in one optional argument:

- 'colorscheme':
    - Type: str
    - What: The color scheme to convert
    - Options: ['bgr', 'rgb', 'gray', 'hsv']
    - Default: 'bgr'
@staticmethod
def read(filename: str):
160    @staticmethod
161    def read(filename: str):
162        """
163        Reads a picture into CV2 image data
164
165        Requires one argument:
166
167            - 'filename':
168                - Type: str
169                - What: Filename from which to load a picture
170        """
171        return cv2.imread(filename)

Reads a picture into CV2 image data

Requires one argument:

- 'filename':
    - Type: str
    - What: Filename from which to load a picture
@type_enforced.Enforcer
class Pixelator(Picture_Utils):
174@type_enforced.Enforcer
175class Pixelator(Picture_Utils):
176    def __init__(
177        self,
178        data: [numpy.ndarray, list, None] = None,
179        filename: [str, None] = None,
180        cam_port: int = 0,
181    ):
182        """
183        Initialize a Pixelator object.
184
185        Takes in three optional arguments:
186
187            - 'data':
188                - Type: list of lists
189                - What: BGR array of data to input
190                - Note: If not specified, proceeds to attempt to load from a filename
191            - 'filename':
192                - Type: str
193                - What: Filename from which to load a picture
194                - Note: If not specified, proceeds to attempt a camera capture
195            - 'cam_port':
196                - Type: int
197                - What: The camera port to use for a capture
198                - Note: For more info see the docs for cv2.VideoCapture.
199        """
200        if data is not None:
201            self.data = data
202        elif filename is not None:
203            self.data = self.read(filename)
204        else:
205            self.data = self.capture(cam_port)
206
207    def pixelate(
208        self,
209        width: [int, None] = None,
210        height: [int, None] = None,
211        palette: [numpy.ndarray, list, None] = None,
212    ):
213        """
214        Pixelates an image to a specific shape and color palette
215
216        Returns a new Pixelator (class) image
217
218        Takes in three optional arguments:
219
220            - 'width':
221                - Type: int
222                - What: The width in pixels for the output image
223                - Note: If either 'width' or 'height' are not specified, this function only applies the palette
224            - 'height':
225                - Type: int
226                - What: The height in pixels for the output image
227                - Note: If either 'width' or 'height' are not specified, this function only applies the palette
228            - 'palette':
229                - Type: list of lists
230                - What: A list of BGR lists to apply as a pallete
231                - Note: If not specified, no palette is applied
232        """
233        out = self.resize(image=self.data, width=width, height=height)
234        if palette is not None:
235            out = self.quantize_to_palette(out, palette)
236        return Pixelator(data=out)
237
238    def write(
239        self,
240        filename: str,
241        width: [int, None] = None,
242        height: [int, None] = None,
243    ):
244        """
245        Writes the current image to a specific file and resizes to a given width and height if supplied
246
247        Takes in one required argument:
248
249            - 'filename':
250                - Type: str
251                - What: Filename at which to write the picture
252
253        Takes in two optional arguments:
254
255            - 'width':
256                - Type: int
257                - What: The width in pixels for the output image
258                - Note: If either 'width' or 'height' are not specified, no resizing is done
259            - 'height':
260                - Type: int
261                - What: The height in pixels for the output image
262                - Note: If either 'width' or 'height' are not specified, no resizing is done
263        """
264        if width == None or height == None:
265            (height, width) = self.data.shape[:2]
266        cv2.imwrite(
267            filename, self.resize(self.data, width, height).astype(numpy.uint8)
268        )
269
270    def get_color_counts(self):
271        """
272        Gets the counts of each color in the image
273
274        Returns a dictionary of color counts where:
275            - The keys are the tuples of the colors
276            - The values are the counts of each color
277
278        EG: {(255, 255, 255): 100, (0, 0, 0): 50}
279        """
280        colors, count = numpy.unique(
281            self.data.reshape(-1, self.data.shape[-1]),
282            axis=0,
283            return_counts=True,
284        )
285        # Force all items in colors to be integers
286        colors = colors.astype(int)
287        return dict(zip([tuple(color) for color in colors], count))
Pixelator( data: [<class 'numpy.ndarray'>, <class 'list'>, None] = None, filename: [<class 'str'>, None] = None, cam_port: int = 0)
176    def __init__(
177        self,
178        data: [numpy.ndarray, list, None] = None,
179        filename: [str, None] = None,
180        cam_port: int = 0,
181    ):
182        """
183        Initialize a Pixelator object.
184
185        Takes in three optional arguments:
186
187            - 'data':
188                - Type: list of lists
189                - What: BGR array of data to input
190                - Note: If not specified, proceeds to attempt to load from a filename
191            - 'filename':
192                - Type: str
193                - What: Filename from which to load a picture
194                - Note: If not specified, proceeds to attempt a camera capture
195            - 'cam_port':
196                - Type: int
197                - What: The camera port to use for a capture
198                - Note: For more info see the docs for cv2.VideoCapture.
199        """
200        if data is not None:
201            self.data = data
202        elif filename is not None:
203            self.data = self.read(filename)
204        else:
205            self.data = self.capture(cam_port)

Initialize a Pixelator object.

Takes in three optional arguments:

- 'data':
    - Type: list of lists
    - What: BGR array of data to input
    - Note: If not specified, proceeds to attempt to load from a filename
- 'filename':
    - Type: str
    - What: Filename from which to load a picture
    - Note: If not specified, proceeds to attempt a camera capture
- 'cam_port':
    - Type: int
    - What: The camera port to use for a capture
    - Note: For more info see the docs for cv2.VideoCapture.
def pixelate( self, width: [<class 'int'>, None] = None, height: [<class 'int'>, None] = None, palette: [<class 'numpy.ndarray'>, <class 'list'>, None] = None):
207    def pixelate(
208        self,
209        width: [int, None] = None,
210        height: [int, None] = None,
211        palette: [numpy.ndarray, list, None] = None,
212    ):
213        """
214        Pixelates an image to a specific shape and color palette
215
216        Returns a new Pixelator (class) image
217
218        Takes in three optional arguments:
219
220            - 'width':
221                - Type: int
222                - What: The width in pixels for the output image
223                - Note: If either 'width' or 'height' are not specified, this function only applies the palette
224            - 'height':
225                - Type: int
226                - What: The height in pixels for the output image
227                - Note: If either 'width' or 'height' are not specified, this function only applies the palette
228            - 'palette':
229                - Type: list of lists
230                - What: A list of BGR lists to apply as a pallete
231                - Note: If not specified, no palette is applied
232        """
233        out = self.resize(image=self.data, width=width, height=height)
234        if palette is not None:
235            out = self.quantize_to_palette(out, palette)
236        return Pixelator(data=out)

Pixelates an image to a specific shape and color palette

Returns a new Pixelator (class) image

Takes in three optional arguments:

- 'width':
    - Type: int
    - What: The width in pixels for the output image
    - Note: If either 'width' or 'height' are not specified, this function only applies the palette
- 'height':
    - Type: int
    - What: The height in pixels for the output image
    - Note: If either 'width' or 'height' are not specified, this function only applies the palette
- 'palette':
    - Type: list of lists
    - What: A list of BGR lists to apply as a pallete
    - Note: If not specified, no palette is applied
def write( self, filename: str, width: [<class 'int'>, None] = None, height: [<class 'int'>, None] = None):
238    def write(
239        self,
240        filename: str,
241        width: [int, None] = None,
242        height: [int, None] = None,
243    ):
244        """
245        Writes the current image to a specific file and resizes to a given width and height if supplied
246
247        Takes in one required argument:
248
249            - 'filename':
250                - Type: str
251                - What: Filename at which to write the picture
252
253        Takes in two optional arguments:
254
255            - 'width':
256                - Type: int
257                - What: The width in pixels for the output image
258                - Note: If either 'width' or 'height' are not specified, no resizing is done
259            - 'height':
260                - Type: int
261                - What: The height in pixels for the output image
262                - Note: If either 'width' or 'height' are not specified, no resizing is done
263        """
264        if width == None or height == None:
265            (height, width) = self.data.shape[:2]
266        cv2.imwrite(
267            filename, self.resize(self.data, width, height).astype(numpy.uint8)
268        )

Writes the current image to a specific file and resizes to a given width and height if supplied

Takes in one required argument:

- 'filename':
    - Type: str
    - What: Filename at which to write the picture

Takes in two optional arguments:

- 'width':
    - Type: int
    - What: The width in pixels for the output image
    - Note: If either 'width' or 'height' are not specified, no resizing is done
- 'height':
    - Type: int
    - What: The height in pixels for the output image
    - Note: If either 'width' or 'height' are not specified, no resizing is done
def get_color_counts(self):
270    def get_color_counts(self):
271        """
272        Gets the counts of each color in the image
273
274        Returns a dictionary of color counts where:
275            - The keys are the tuples of the colors
276            - The values are the counts of each color
277
278        EG: {(255, 255, 255): 100, (0, 0, 0): 50}
279        """
280        colors, count = numpy.unique(
281            self.data.reshape(-1, self.data.shape[-1]),
282            axis=0,
283            return_counts=True,
284        )
285        # Force all items in colors to be integers
286        colors = colors.astype(int)
287        return dict(zip([tuple(color) for color in colors], count))

Gets the counts of each color in the image

Returns a dictionary of color counts where: - The keys are the tuples of the colors - The values are the counts of each color

EG: {(255, 255, 255): 100, (0, 0, 0): 50}