Skip to content

Commit 8037de5

Browse files
committed
Add "bitmapfilter"
bitmapfilter.morph is taken from openmv's imlib. It is substantially faster than blur/sharpen implemented in ulab, by up to 10x. It also avoids making many allocations.
1 parent bbff8b5 commit 8037de5

File tree

11 files changed

+438
-12
lines changed

11 files changed

+438
-12
lines changed

locale/circuitpython.pot

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -896,10 +896,6 @@ msgstr ""
896896
msgid "Deep sleep pins must use a rising edge with pulldown"
897897
msgstr ""
898898

899-
#: shared-module/jpegio/JpegDecoder.c
900-
msgid "Destination bitmap too small to contain image"
901-
msgstr ""
902-
903899
#: shared-bindings/audiobusio/PDMIn.c
904900
msgid "Destination capacity is smaller than destination_length."
905901
msgstr ""
@@ -1382,6 +1378,10 @@ msgstr ""
13821378
msgid "Must be a %q subclass."
13831379
msgstr ""
13841380

1381+
#: shared-bindings/bitmapfilter/__init__.c
1382+
msgid "Must be an odd square number of weights"
1383+
msgstr ""
1384+
13851385
#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c
13861386
msgid "Must provide 5/6/5 RGB pins"
13871387
msgstr ""
@@ -2539,6 +2539,10 @@ msgstr ""
25392539
msgid "binary op %q not implemented"
25402540
msgstr ""
25412541

2542+
#: shared-module/bitmapfilter/__init__.c
2543+
msgid "bitmap size and depth must match"
2544+
msgstr ""
2545+
25422546
#: shared-bindings/bitmaptools/__init__.c
25432547
msgid "bitmap sizes must match"
25442548
msgstr ""
@@ -3879,10 +3883,6 @@ msgstr ""
38793883
msgid "parameters must be registers in sequence r0 to r3"
38803884
msgstr ""
38813885

3882-
#: shared-bindings/bitmaptools/__init__.c
3883-
msgid "pixel coordinates out of bounds"
3884-
msgstr ""
3885-
38863886
#: extmod/vfs_posix_file.c
38873887
msgid "poll on file not available on win32"
38883888
msgstr ""
@@ -4277,6 +4277,10 @@ msgstr ""
42774277
msgid "unsupported Xtensa instruction '%s' with %d arguments"
42784278
msgstr ""
42794279

4280+
#: shared-module/bitmapfilter/__init__.c
4281+
msgid "unsupported bitmap depth"
4282+
msgstr ""
4283+
42804284
#: shared-module/gifio/GifWriter.c
42814285
msgid "unsupported colorspace for GifWriter"
42824286
msgstr ""

ports/unix/variants/coverage/mpconfigvariant.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ SRC_BITMAP := \
3434
shared-bindings/audiomixer/__init__.c \
3535
shared-bindings/audiomixer/Mixer.c \
3636
shared-bindings/audiomixer/MixerVoice.c \
37+
shared-bindings/bitmapfilter/__init__.c \
3738
shared-bindings/bitmaptools/__init__.c \
3839
shared-bindings/codeop/__init__.c \
3940
shared-bindings/displayio/Bitmap.c \
@@ -60,6 +61,7 @@ SRC_BITMAP := \
6061
shared-module/audiomixer/__init__.c \
6162
shared-module/audiomixer/Mixer.c \
6263
shared-module/audiomixer/MixerVoice.c \
64+
shared-module/bitmapfilter/__init__.c \
6365
shared-module/bitmaptools/__init__.c \
6466
shared-module/displayio/area.c \
6567
shared-module/displayio/Bitmap.c \

py/circuitpy_defns.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ endif
144144
ifeq ($(CIRCUITPY_BITMAPTOOLS),1)
145145
SRC_PATTERNS += bitmaptools/%
146146
endif
147+
ifeq ($(CIRCUITPY_BITMAPFILTER),1)
148+
SRC_PATTERNS += bitmapfilter/%
149+
endif
147150
ifeq ($(CIRCUITPY_BITOPS),1)
148151
SRC_PATTERNS += bitops/%
149152
endif
@@ -609,6 +612,7 @@ SRC_SHARED_MODULE_ALL = \
609612
bitbangio/SPI.c \
610613
bitbangio/__init__.c \
611614
bitmaptools/__init__.c \
615+
bitmapfilter/__init__.c \
612616
bitops/__init__.c \
613617
board/__init__.c \
614618
adafruit_bus_device/__init__.c \

py/circuitpy_mpconfig.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,9 @@ CFLAGS += -DCIRCUITPY_DOTCLOCKFRAMEBUFFER=$(CIRCUITPY_DOTCLOCKFRAMEBUFFER)
236236
CIRCUITPY_DOTCLOCKFRAMEBUFFER_USES_SUPERVISOR_ALLOCATION ?= 1
237237
CFLAGS += -DCIRCUITPY_DOTCLOCKFRAMEBUFFER_USES_SUPERVISOR_ALLOCATION=$(CIRCUITPY_DOTCLOCKFRAMEBUFFER_USES_SUPERVISOR_ALLOCATION)
238238

239-
# bitmaptools and framebufferio rely on displayio
239+
# bitmaptools, bitmapfilter and framebufferio rely on displayio
240240
CIRCUITPY_BITMAPTOOLS ?= $(call enable-if-all,$(CIRCUITPY_FULL_BUILD) $(CIRCUITPY_DISPLAYIO))
241+
CIRCUITPY_BITMAPFILTER ?= $(call enable-if-all,$(CIRCUITPY_FULL_BUILD) $(CIRCUITPY_DISPLAYIO))
241242
CIRCUITPY_FRAMEBUFFERIO ?= $(call enable-if-all,$(CIRCUITPY_FULL_BUILD) $(CIRCUITPY_DISPLAYIO))
242243
CIRCUITPY_VECTORIO ?= $(CIRCUITPY_DISPLAYIO)
243244
CFLAGS += -DCIRCUITPY_BITMAPTOOLS=$(CIRCUITPY_BITMAPTOOLS)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 Kevin Matocha
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <math.h>
28+
29+
#include "py/runtime.h"
30+
#include "shared-bindings/displayio/Bitmap.h"
31+
#include "shared-bindings/bitmapfilter/__init__.h"
32+
33+
STATIC mp_obj_t bitmapfilter_morph(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
34+
enum { ARG_dest_bitmap, ARG_source_bitmap, ARG_weights, ARG_m, ARG_b };
35+
static const mp_arg_t allowed_args[] = {
36+
{ MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
37+
{ MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
38+
{ MP_QSTR_weights, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
39+
{ MP_QSTR_m, MP_ARG_OBJ, { .u_obj = MP_ROM_INT(1) } },
40+
{ MP_QSTR_b, MP_ARG_OBJ, { .u_obj = MP_ROM_INT(0) } },
41+
};
42+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
43+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
44+
45+
mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap);
46+
mp_arg_validate_type(args[ARG_source_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap);
47+
displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap
48+
displayio_bitmap_t *source = MP_OBJ_TO_PTR(args[ARG_source_bitmap].u_obj); // the source bitmap
49+
50+
mp_float_t m = mp_obj_get_float(args[ARG_m].u_obj);
51+
mp_int_t b = mp_obj_get_int(args[ARG_b].u_obj);
52+
53+
size_t n_weights;
54+
mp_obj_t weights = mp_arg_validate_type(args[ARG_weights].u_obj, &mp_type_tuple, MP_QSTR_weights);
55+
mp_obj_t *items;
56+
mp_obj_tuple_get(weights, &n_weights, &items);
57+
mp_arg_validate_length_min(n_weights, 9, MP_QSTR_items);
58+
size_t sq_n_weights = (int)MICROPY_FLOAT_C_FUN(sqrt)(n_weights);
59+
if (sq_n_weights % 2 == 0 || sq_n_weights * sq_n_weights != n_weights) {
60+
mp_raise_ValueError(MP_ERROR_TEXT("Must be an odd square number of weights"));
61+
}
62+
63+
int iweights[n_weights];
64+
for (size_t i = 0; i < n_weights; i++) {
65+
iweights[i] = mp_obj_get_int(items[i]);
66+
}
67+
68+
shared_module_bitmapfilter_morph(source, destination, sq_n_weights / 2, iweights, (float)m, b, false, 0, false);
69+
return mp_const_none;
70+
}
71+
72+
MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_morph_obj, 0, bitmapfilter_morph);
73+
74+
STATIC const mp_rom_map_elem_t bitmapfilter_module_globals_table[] = {
75+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitmapfilter) },
76+
{ MP_ROM_QSTR(MP_QSTR_morph), MP_ROM_PTR(&bitmapfilter_morph_obj) },
77+
};
78+
STATIC MP_DEFINE_CONST_DICT(bitmapfilter_module_globals, bitmapfilter_module_globals_table);
79+
80+
const mp_obj_module_t bitmapfilter_module = {
81+
.base = {&mp_type_module },
82+
.globals = (mp_obj_dict_t *)&bitmapfilter_module_globals,
83+
};
84+
85+
MP_REGISTER_MODULE(MP_QSTR_bitmapfilter, bitmapfilter_module);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2024 Jeff Epler for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#pragma once
28+
29+
#include "shared-module/displayio/Bitmap.h"
30+
31+
void shared_module_bitmapfilter_morph(
32+
displayio_bitmap_t *src,
33+
displayio_bitmap_t *dest,
34+
const int ksize,
35+
const int *krn,
36+
const float m,
37+
const int b,
38+
bool threshold,
39+
int offset,
40+
bool invert);

0 commit comments

Comments
 (0)