mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Upgrade Drawing Features
Heavily upgraded the drawing features onboard the OpenMV Cam. We now have all the basic drawing methods folks expect along with all the parameters you need. Finally! You can make big text fonts. * Added line thickness support * Added shape fills * Added text scaling * Added draw arrow.
This commit is contained in:
parent
6339815ae3
commit
fc74e70c32
@ -153,6 +153,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \
|
||||
FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/img/,\
|
||||
binary.o \
|
||||
blob.o \
|
||||
draw.o \
|
||||
qrcode.o \
|
||||
apriltag.o \
|
||||
dmtx.o \
|
||||
|
||||
@ -24,6 +24,7 @@ SRCS += $(addprefix , \
|
||||
SRCS += $(addprefix img/, \
|
||||
binary.c \
|
||||
blob.c \
|
||||
draw.c \
|
||||
qrcode.c \
|
||||
apriltag.c \
|
||||
dmtx.c \
|
||||
|
||||
205
src/omv/img/draw.c
Normal file
205
src/omv/img/draw.c
Normal file
@ -0,0 +1,205 @@
|
||||
/* This file is part of the OpenMV project.
|
||||
* Copyright (c) 2013-2018 Ibrahim Abdelkader <iabdalkader@openmv.io> & Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "font.h"
|
||||
#include "imlib.h"
|
||||
|
||||
// Get pixel (handles boundary check and image type check).
|
||||
int imlib_get_pixel(image_t *img, int x, int y)
|
||||
{
|
||||
if ((0 <= x) && (x < img->w) && (0 <= y) && (y < img->h)) {
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
return IMAGE_GET_BINARY_PIXEL(img, x, y);
|
||||
}
|
||||
case IMAGE_BPP_GRAYSCALE: {
|
||||
return IMAGE_GET_GRAYSCALE_PIXEL(img, x, y);
|
||||
}
|
||||
case IMAGE_BPP_RGB565: {
|
||||
return IMAGE_GET_RGB565_PIXEL(img, x, y);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set pixel (handles boundary check and image type check).
|
||||
void imlib_set_pixel(image_t *img, int x, int y, int p)
|
||||
{
|
||||
if ((0 <= x) && (x < img->w) && (0 <= y) && (y < img->h)) {
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
IMAGE_PUT_BINARY_PIXEL(img, x, y, p);
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_GRAYSCALE: {
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL(img, x, y, p);
|
||||
break;
|
||||
}
|
||||
case IMAGE_BPP_RGB565: {
|
||||
IMAGE_PUT_RGB565_PIXEL(img, x, y, p);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/1201200/fast-algorithm-for-drawing-filled-circles
|
||||
static void point_fill(image_t *img, int cx, int cy, int r, int c)
|
||||
{
|
||||
for (int y = -r; y <= r; y++) {
|
||||
for (int x = -r; x <= r; x++) {
|
||||
if ((x * x) + (y * y) <= (r * r)) {
|
||||
imlib_set_pixel(img, cx + x, cy + y, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
|
||||
void imlib_draw_line(image_t *img, int x0, int y0, int x1, int y1, int c, int thickness)
|
||||
{
|
||||
int dx = abs(x1 - x0), sx = (x0 < x1) ? 1 : -1;
|
||||
int dy = abs(y1 - y0), sy = (y0 < y1) ? 1 : -1;
|
||||
int err = ((dx > dy) ? dx : -dy) / 2;
|
||||
|
||||
for (;;) {
|
||||
point_fill(img, x0, y0, thickness - 1, c);
|
||||
if ((x0 == x1) && (y0 == y1)) break;
|
||||
int e2 = err;
|
||||
if (e2 > -dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
static void xLine(image_t *img, int x1, int x2, int y, int c)
|
||||
{
|
||||
while (x1 <= x2) imlib_set_pixel(img, x1++, y, c);
|
||||
}
|
||||
|
||||
static void yLine(image_t *img, int x, int y1, int y2, int c)
|
||||
{
|
||||
while (y1 <= y2) imlib_set_pixel(img, x, y1++, c);
|
||||
}
|
||||
|
||||
void imlib_draw_rectangle(image_t *img, int rx, int ry, int rw, int rh, int c, int thickness, bool fill)
|
||||
{
|
||||
if (fill) {
|
||||
|
||||
for (int y = ry, yy = ry + rh; y < yy; y++) {
|
||||
for (int x = rx, xx = rx + rw; x < xx; x++) {
|
||||
imlib_set_pixel(img, x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (thickness > 0) {
|
||||
|
||||
for (int i = rx - ((thickness - 0) / 2), j = rx + rw + ((thickness - 1) / 2),
|
||||
k = ry + rh - 1; i < j; i++) {
|
||||
yLine(img, i, ry - ((thickness - 0) / 2), ry + ((thickness - 1) / 2), c);
|
||||
yLine(img, i, k - ((thickness - 0) / 2), k + ((thickness - 1) / 2), c);
|
||||
}
|
||||
|
||||
for (int i = ry - ((thickness - 0) / 2), j = ry + rh + ((thickness - 1) / 2),
|
||||
k = rx + rw - 1; i < j; i++) {
|
||||
xLine(img, rx - ((thickness - 0) / 2), rx + ((thickness - 1) / 2), i, c);
|
||||
xLine(img, k - ((thickness - 0) / 2), k + ((thickness - 1) / 2), i, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/27755514/circle-with-thickness-drawing-algorithm
|
||||
void imlib_draw_circle(image_t *img, int cx, int cy, int r, int c, int thickness, bool fill)
|
||||
{
|
||||
if (fill) {
|
||||
point_fill(img, cx, cy, r, c);
|
||||
} else if (thickness > 0) {
|
||||
thickness = IM_MIN(thickness, r);
|
||||
|
||||
int xo = r + ((thickness - 0) / 2);
|
||||
int xi = r - ((thickness - 1) / 2);
|
||||
int y = 0;
|
||||
int erro = 1 - xo;
|
||||
int erri = 1 - xi;
|
||||
|
||||
while(xo >= y) {
|
||||
xLine(img, cx + xi, cx + xo, cy + y, c);
|
||||
yLine(img, cx + y, cy + xi, cy + xo, c);
|
||||
xLine(img, cx - xo, cx - xi, cy + y, c);
|
||||
yLine(img, cx - y, cy + xi, cy + xo, c);
|
||||
xLine(img, cx - xo, cx - xi, cy - y, c);
|
||||
yLine(img, cx - y, cy - xo, cy - xi, c);
|
||||
xLine(img, cx + xi, cx + xo, cy - y, c);
|
||||
yLine(img, cx + y, cy - xo, cy - xi, c);
|
||||
|
||||
y++;
|
||||
|
||||
if (erro < 0) {
|
||||
erro += 2 * y + 1;
|
||||
} else {
|
||||
xo--;
|
||||
erro += 2 * (y - xo + 1);
|
||||
}
|
||||
|
||||
if (y > (r - ((thickness - 1) / 2))) {
|
||||
xi = y;
|
||||
} else {
|
||||
if (erri < 0) {
|
||||
erri += 2 * y + 1;
|
||||
} else {
|
||||
xi--;
|
||||
erri += 2 * (y - xi + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c, int scale)
|
||||
{
|
||||
const int anchor = x_off;
|
||||
|
||||
for(char ch, last = '\0'; (ch = *str); str++, last = ch) {
|
||||
|
||||
if ((last == '\r') && (ch == '\n')) { // handle "\r\n" strings
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ch == '\n') || (ch == '\r')) { // handle '\n' or '\r' strings
|
||||
x_off = anchor;
|
||||
y_off += font[0].h * scale; // newline height == space height
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ch < ' ') || (ch > '~')) { // handle unknown characters
|
||||
imlib_draw_rectangle(img,
|
||||
x_off + ((scale * 3) / 2),
|
||||
y_off + ((scale * 3) / 2),
|
||||
(font[0].w * scale) - (((scale * 3) / 2) * 2),
|
||||
(font[0].h * scale) - (((scale * 3) / 2) * 2),
|
||||
c, scale, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
const glyph_t *g = &font[ch - ' '];
|
||||
|
||||
for (int y = 0, yy = g->h * scale; y < yy; y++) {
|
||||
for (int x = 0, xx = g->w * scale; x < xx; x++) {
|
||||
if (g->data[y / scale] & (1 << (g->w - (x / scale)))) {
|
||||
imlib_set_pixel(img, (x_off + x), (y_off + y), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x_off += g->w * scale;
|
||||
}
|
||||
}
|
||||
@ -117,7 +117,7 @@ void imlib_find_hog(image_t *src, rectangle_t *roi, int cell_size)
|
||||
bin_t *bin = array_at(gds, i);
|
||||
int x2 = l * cos_table[bin->d];
|
||||
int y2 = l * sin_table[bin->d];
|
||||
imlib_draw_line(src, (x1 - x2), (y1 + y2), (x1 + x2), (y1 - y2), bin->m);
|
||||
imlib_draw_line(src, (x1 - x2), (y1 + y2), (x1 + x2), (y1 - y2), bin->m, 1);
|
||||
}
|
||||
|
||||
hog_index += N_BINS;
|
||||
|
||||
@ -519,139 +519,6 @@ void imlib_save_image(image_t *img, const char *path, rectangle_t *roi, int qual
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_copy_image(image_t *dst, image_t *src, rectangle_t *roi)
|
||||
{
|
||||
if (IM_IS_JPEG(src)) {
|
||||
dst->w = src->w;
|
||||
dst->h = src->h;
|
||||
dst->bpp = src->bpp;
|
||||
dst->pixels = xalloc(src->bpp);
|
||||
memcpy(dst->pixels, src->pixels, src->bpp);
|
||||
} else {
|
||||
rectangle_t rect;
|
||||
if (!rectangle_subimg(src, roi, &rect)) ff_no_intersection(NULL);
|
||||
dst->w = rect.w;
|
||||
dst->h = rect.h;
|
||||
dst->bpp = src->bpp;
|
||||
dst->pixels = xalloc(rect.w * rect.h * src->bpp);
|
||||
uint8_t *dst_pointer = dst->pixels;
|
||||
for (int i = rect.y; i < (rect.y + rect.h); i++) {
|
||||
int length = rect.w * src->bpp;
|
||||
memcpy(dst_pointer,
|
||||
src->pixels + (rect.x * src->bpp) + (i * src->w * src->bpp),
|
||||
length);
|
||||
dst_pointer += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Get pixel (handles boundary check and image type check).
|
||||
int imlib_get_pixel(image_t *img, int x, int y)
|
||||
{
|
||||
return (IM_X_INSIDE(img, x) && IM_Y_INSIDE(img, y)) ?
|
||||
( IM_IS_GS(img)
|
||||
? IM_GET_GS_PIXEL(img, x, y)
|
||||
: IM_GET_RGB565_PIXEL(img, x, y) )
|
||||
: 0;
|
||||
}
|
||||
|
||||
// Set pixel (handles boundary check and image type check).
|
||||
void imlib_set_pixel(image_t *img, int x, int y, int p)
|
||||
{
|
||||
if (IM_X_INSIDE(img, x) && IM_Y_INSIDE(img, y)) {
|
||||
if (IM_IS_GS(img)) {
|
||||
IM_SET_GS_PIXEL(img, x, y, p);
|
||||
} else {
|
||||
IM_SET_RGB565_PIXEL(img, x, y, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void imlib_draw_line(image_t *img, int x0, int y0, int x1, int y1, int c)
|
||||
{
|
||||
int dx = abs(x1-x0);
|
||||
int dy = abs(y1-y0);
|
||||
int sx = x0<x1 ? 1 : -1;
|
||||
int sy = y0<y1 ? 1 : -1;
|
||||
int err = (dx>dy ? dx : -dy)/2;
|
||||
for (;;) {
|
||||
imlib_set_pixel(img, x0, y0, c);
|
||||
if (x0==x1 && y0==y1) break;
|
||||
int e2 = err;
|
||||
if (e2 > -dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_draw_rectangle(image_t *img, int rx, int ry, int rw, int rh, int c)
|
||||
{
|
||||
if (rw<=0 || rh<=0) {
|
||||
return;
|
||||
}
|
||||
for (int i=rx, j=rx+rw, k=ry+rh-1; i<j; i++) {
|
||||
imlib_set_pixel(img, i, ry, c);
|
||||
imlib_set_pixel(img, i, k, c);
|
||||
}
|
||||
for (int i=ry+1, j=ry+rh-1, k=rx+rw-1; i<j; i++) {
|
||||
imlib_set_pixel(img, rx, i, c);
|
||||
imlib_set_pixel(img, k, i, c);
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_draw_circle(image_t *img, int cx, int cy, int r, int c)
|
||||
{
|
||||
int x = r, y = 0, radiusError = 1-x;
|
||||
while (x>=y) {
|
||||
imlib_set_pixel(img, x + cx, y + cy, c);
|
||||
imlib_set_pixel(img, y + cx, x + cy, c);
|
||||
imlib_set_pixel(img, -x + cx, y + cy, c);
|
||||
imlib_set_pixel(img, -y + cx, x + cy, c);
|
||||
imlib_set_pixel(img, -x + cx, -y + cy, c);
|
||||
imlib_set_pixel(img, -y + cx, -x + cy, c);
|
||||
imlib_set_pixel(img, x + cx, -y + cy, c);
|
||||
imlib_set_pixel(img, y + cx, -x + cy, c);
|
||||
y++;
|
||||
if (radiusError<0) {
|
||||
radiusError += 2 * y + 1;
|
||||
} else {
|
||||
x--;
|
||||
radiusError += 2 * (y - x + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c)
|
||||
{
|
||||
const int anchor = x_off;
|
||||
for(char ch, last='\0'; (ch=*str); str++, last=ch) {
|
||||
if (last=='\r' && ch=='\n') { // handle "\r\n" strings
|
||||
continue;
|
||||
}
|
||||
if (ch=='\n' || ch=='\r') { // handle '\n' or '\r' strings
|
||||
x_off = anchor;
|
||||
y_off += font[0].h; // newline height == space height
|
||||
continue;
|
||||
}
|
||||
if (ch<' ' || ch>'~') {
|
||||
imlib_draw_rectangle(img,(x_off+1),(y_off+1),font[0].w-2,font[0].h-2,c);
|
||||
continue;
|
||||
}
|
||||
const glyph_t *g = &font[ch-' '];
|
||||
for (int y=0; y<g->h; y++) {
|
||||
for (int x=0; x<g->w; x++) {
|
||||
if (g->data[y] & (1<<(g->w-x))) {
|
||||
imlib_set_pixel(img, (x_off+x), (y_off+y), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
x_off += g->w;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void imlib_histeq(image_t *img)
|
||||
|
||||
@ -218,7 +218,7 @@ extern const uint8_t g826_table[256];
|
||||
__typeof__ (r5) _r5 = (r5); \
|
||||
__typeof__ (g6) _g6 = (g6); \
|
||||
__typeof__ (b5) _b5 = (b5); \
|
||||
(_r5 << 3) | (_g6 >> 3) | (_g6 << 13) | (_b5 << 8); \
|
||||
(_r5 << 3) | (_g6 >> 3) | ((_g6 & 0x7) << 13) | (_b5 << 8); \
|
||||
})
|
||||
|
||||
#define COLOR_R8_G8_B8_TO_RGB565(r8, g8, b8) COLOR_R5_G6_B5_TO_RGB565(COLOR_R8_TO_R5(r8), COLOR_G8_TO_G6(g8), COLOR_B8_TO_B5(b8))
|
||||
@ -1107,7 +1107,6 @@ bool imlib_read_geometry(FIL *fp, image_t *img, const char *path, img_read_setti
|
||||
void imlib_image_operation(image_t *img, const char *path, image_t *other, line_op_t op, void *data);
|
||||
void imlib_load_image(image_t *img, const char *path);
|
||||
void imlib_save_image(image_t *img, const char *path, rectangle_t *roi, int quality);
|
||||
void imlib_copy_image(image_t *dst, image_t *src, rectangle_t *roi);
|
||||
|
||||
/* GIF functions */
|
||||
void gif_open(FIL *fp, int width, int height, bool color, bool loop);
|
||||
@ -1119,10 +1118,6 @@ void mjpeg_open(FIL *fp, int width, int height);
|
||||
void mjpeg_add_frame(FIL *fp, uint32_t *frames, uint32_t *bytes, image_t *img, int quality);
|
||||
void mjpeg_close(FIL *fp, uint32_t *frames, uint32_t *bytes, float fps);
|
||||
|
||||
/* Basic image functions */
|
||||
int imlib_get_pixel(image_t *img, int x, int y);
|
||||
void imlib_set_pixel(image_t *img, int x, int y, int p);
|
||||
|
||||
/* Point functions */
|
||||
point_t *point_alloc(int16_t x, int16_t y);
|
||||
bool point_equal(point_t *p1, point_t *p2);
|
||||
@ -1136,12 +1131,6 @@ bool rectangle_subimg(image_t *img, rectangle_t *r, rectangle_t *r_out);
|
||||
array_t *rectangle_merge(array_t *rectangles);
|
||||
void rectangle_expand(rectangle_t *r, int x, int y);
|
||||
|
||||
/* Drawing functions */
|
||||
void imlib_draw_line(image_t *img, int x0, int y0, int x1, int y1, int c);
|
||||
void imlib_draw_rectangle(image_t *img, int rx, int ry, int rw, int rh, int c);
|
||||
void imlib_draw_circle(image_t *img, int cx, int cy, int r, int c);
|
||||
void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c);
|
||||
|
||||
/* Image Morphing */
|
||||
void imlib_morph(image_t *img, const int ksize, const int8_t *krn, const float m, const int b);
|
||||
|
||||
@ -1226,6 +1215,13 @@ void imlib_edge_canny(image_t *src, rectangle_t *roi, int low_thresh, int high_t
|
||||
// HoG
|
||||
void imlib_find_hog(image_t *src, rectangle_t *roi, int cell_size);
|
||||
|
||||
// Drawing Functions
|
||||
int imlib_get_pixel(image_t *img, int x, int y);
|
||||
void imlib_set_pixel(image_t *img, int x, int y, int p);
|
||||
void imlib_draw_line(image_t *img, int x0, int y0, int x1, int y1, int c, int thickness);
|
||||
void imlib_draw_rectangle(image_t *img, int rx, int ry, int rw, int rh, int c, int thickness, bool fill);
|
||||
void imlib_draw_circle(image_t *img, int cx, int cy, int r, int c, int thickness, bool fill);
|
||||
void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c, int scale);
|
||||
// Binary Functions
|
||||
void imlib_binary(image_t *img, list_t *thresholds, bool invert, bool zero);
|
||||
void imlib_invert(image_t *img);
|
||||
|
||||
@ -181,9 +181,9 @@ int py_helper_keyword_color(image_t *img, uint n_args, const mp_obj_t *args, uin
|
||||
} else {
|
||||
mp_obj_t *arg_color;
|
||||
mp_obj_get_array_fixed_n(kw_arg->value, 3, &arg_color);
|
||||
default_val = COLOR_R5_G6_B5_TO_RGB565(COLOR_R8_TO_R5(mp_obj_get_int(arg_color[0])),
|
||||
COLOR_G8_TO_G6(mp_obj_get_int(arg_color[1])),
|
||||
COLOR_B8_TO_B5(mp_obj_get_int(arg_color[2])));
|
||||
default_val = COLOR_R8_G8_B8_TO_RGB565(IM_MAX(IM_MIN(mp_obj_get_int(arg_color[0]), COLOR_R8_MAX), COLOR_R8_MIN),
|
||||
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[1]), COLOR_G8_MAX), COLOR_G8_MIN),
|
||||
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[2]), COLOR_B8_MAX), COLOR_B8_MIN));
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
default_val = COLOR_RGB565_TO_BINARY(default_val);
|
||||
@ -204,9 +204,9 @@ int py_helper_keyword_color(image_t *img, uint n_args, const mp_obj_t *args, uin
|
||||
} else {
|
||||
mp_obj_t *arg_color;
|
||||
mp_obj_get_array_fixed_n(args[arg_index], 3, &arg_color);
|
||||
default_val = COLOR_R5_G6_B5_TO_RGB565(COLOR_R8_TO_R5(mp_obj_get_int(arg_color[0])),
|
||||
COLOR_G8_TO_G6(mp_obj_get_int(arg_color[1])),
|
||||
COLOR_B8_TO_B5(mp_obj_get_int(arg_color[2])));
|
||||
default_val = COLOR_R8_G8_B8_TO_RGB565(IM_MAX(IM_MIN(mp_obj_get_int(arg_color[0]), COLOR_R8_MAX), COLOR_R8_MIN),
|
||||
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[1]), COLOR_G8_MAX), COLOR_G8_MIN),
|
||||
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[2]), COLOR_B8_MAX), COLOR_B8_MIN));
|
||||
switch(img->bpp) {
|
||||
case IMAGE_BPP_BINARY: {
|
||||
default_val = COLOR_RGB565_TO_BINARY(default_val);
|
||||
|
||||
@ -106,6 +106,12 @@ static const mp_obj_type_t py_kp_type = {
|
||||
.unary_op = py_kp_unary_op,
|
||||
};
|
||||
|
||||
py_kp_obj_t *py_kpts_obj(mp_obj_t kpts_obj)
|
||||
{
|
||||
PY_ASSERT_TYPE(kpts_obj, &py_kp_type);
|
||||
return kpts_obj;
|
||||
}
|
||||
|
||||
// LBP descriptor /////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct _py_lbp_obj_t {
|
||||
@ -1012,9 +1018,11 @@ STATIC mp_obj_t py_image_draw_line(uint n_args, const mp_obj_t *args, mp_map_t *
|
||||
int arg_y1 = mp_obj_get_int(arg_vec[3]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset, kw_args, -1); // White.
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset + 0, kw_args, -1); // White.
|
||||
int arg_thickness =
|
||||
py_helper_keyword_int(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thickness), 1);
|
||||
|
||||
imlib_draw_line(arg_img, arg_x0, arg_y0, arg_x1, arg_y1, arg_c);
|
||||
imlib_draw_line(arg_img, arg_x0, arg_y0, arg_x1, arg_y1, arg_c, arg_thickness);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_line_obj, 2, py_image_draw_line);
|
||||
@ -1031,9 +1039,13 @@ STATIC mp_obj_t py_image_draw_rectangle(uint n_args, const mp_obj_t *args, mp_ma
|
||||
int arg_rh = mp_obj_get_int(arg_vec[3]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset, kw_args, -1); // White.
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset + 0, kw_args, -1); // White.
|
||||
int arg_thickness =
|
||||
py_helper_keyword_int(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thickness), 1);
|
||||
bool arg_fill =
|
||||
py_helper_keyword_int(n_args, args, offset + 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_fill), false);
|
||||
|
||||
imlib_draw_rectangle(arg_img, arg_rx, arg_ry, arg_rw, arg_rh, arg_c);
|
||||
imlib_draw_rectangle(arg_img, arg_rx, arg_ry, arg_rw, arg_rh, arg_c, arg_thickness, arg_fill);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_rectangle_obj, 2, py_image_draw_rectangle);
|
||||
@ -1049,9 +1061,13 @@ STATIC mp_obj_t py_image_draw_circle(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
int arg_cr = mp_obj_get_int(arg_vec[2]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset, kw_args, -1); // White.
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset + 0, kw_args, -1); // White.
|
||||
int arg_thickness =
|
||||
py_helper_keyword_int(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thickness), 1);
|
||||
bool arg_fill =
|
||||
py_helper_keyword_int(n_args, args, offset + 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_fill), false);
|
||||
|
||||
imlib_draw_circle(arg_img, arg_cx, arg_cy, arg_cr, arg_c);
|
||||
imlib_draw_circle(arg_img, arg_cx, arg_cy, arg_cr, arg_c, arg_thickness, arg_fill);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_circle_obj, 4, py_image_draw_circle);
|
||||
@ -1067,9 +1083,11 @@ STATIC mp_obj_t py_image_draw_string(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
const char *arg_str = mp_obj_str_get_str(arg_vec[2]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset, kw_args, -1); // White.
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset + 0, kw_args, -1); // White.
|
||||
int arg_scale =
|
||||
py_helper_keyword_int(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_scale), 1);
|
||||
|
||||
imlib_draw_string(arg_img, arg_x_off, arg_y_off, arg_str, arg_c);
|
||||
imlib_draw_string(arg_img, arg_x_off, arg_y_off, arg_str, arg_c, arg_scale);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_string_obj, 4, py_image_draw_string);
|
||||
@ -1084,36 +1102,83 @@ STATIC mp_obj_t py_image_draw_cross(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
int arg_y = mp_obj_get_int(arg_vec[1]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset, kw_args, -1); // White.
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset + 0, kw_args, -1); // White.
|
||||
int arg_s =
|
||||
py_helper_keyword_int(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_size), 5);
|
||||
int arg_thickness =
|
||||
py_helper_keyword_int(n_args, args, offset + 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thickness), 1);
|
||||
|
||||
imlib_draw_line(arg_img, arg_x-arg_s, arg_y , arg_x+arg_s, arg_y , arg_c);
|
||||
imlib_draw_line(arg_img, arg_x , arg_y-arg_s, arg_x , arg_y+arg_s, arg_c);
|
||||
imlib_draw_line(arg_img, arg_x - arg_s, arg_y , arg_x + arg_s, arg_y , arg_c, arg_thickness);
|
||||
imlib_draw_line(arg_img, arg_x , arg_y - arg_s, arg_x , arg_y + arg_s, arg_c, arg_thickness);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_cross_obj, 2, py_image_draw_cross);
|
||||
|
||||
STATIC mp_obj_t py_image_draw_arrow(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||
|
||||
const mp_obj_t *arg_vec;
|
||||
uint offset = py_helper_consume_array(n_args, args, 1, 4, &arg_vec);
|
||||
int arg_x0 = mp_obj_get_int(arg_vec[0]);
|
||||
int arg_y0 = mp_obj_get_int(arg_vec[1]);
|
||||
int arg_x1 = mp_obj_get_int(arg_vec[2]);
|
||||
int arg_y1 = mp_obj_get_int(arg_vec[3]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, offset + 0, kw_args, -1); // White.
|
||||
int arg_s =
|
||||
py_helper_keyword_int(n_args, args, offset + 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_size), 10);
|
||||
int arg_thickness =
|
||||
py_helper_keyword_int(n_args, args, offset + 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thickness), 1);
|
||||
|
||||
// https://stackoverflow.com/questions/4165881/c-draw-a-line-in-gdi-with-a-filled-arrow-head-at-the-end
|
||||
|
||||
int dx = (arg_x1 - arg_x0);
|
||||
int dy = (arg_y1 - arg_y0);
|
||||
|
||||
float length = fast_sqrtf((dx * dx) + (dy * dy));
|
||||
|
||||
float ux = dx / length;
|
||||
float uy = dy / length;
|
||||
float vx = -uy;
|
||||
float vy = ux;
|
||||
|
||||
int a0x = arg_x1 - (arg_s * ux) + (arg_s * vx * 0.5);
|
||||
int a0y = arg_y1 - (arg_s * uy) + (arg_s * vy * 0.5);
|
||||
int a1x = arg_x1 - (arg_s * ux) - (arg_s * vx * 0.5);
|
||||
int a1y = arg_y1 - (arg_s * uy) - (arg_s * vy * 0.5);
|
||||
|
||||
imlib_draw_line(arg_img, arg_x0, arg_y0, arg_x1, arg_y1, arg_c, arg_thickness);
|
||||
imlib_draw_line(arg_img, arg_x1, arg_y1, a0x, a0y, arg_c, arg_thickness);
|
||||
imlib_draw_line(arg_img, arg_x1, arg_y1, a1x, a1y, arg_c, arg_thickness);
|
||||
return args[0];
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_arrow_obj, 2, py_image_draw_arrow);
|
||||
|
||||
STATIC mp_obj_t py_image_draw_keypoints(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||
{
|
||||
image_t *arg_img = py_helper_arg_to_image_mutable(args[0]);
|
||||
py_kp_obj_t *kpts_obj = (py_kp_obj_t*) args[1];
|
||||
PY_ASSERT_TYPE(kpts_obj, &py_kp_type);
|
||||
py_kp_obj_t *kpts_obj = py_kpts_obj(args[1]);
|
||||
|
||||
int arg_c =
|
||||
py_helper_keyword_color(arg_img, n_args, args, 2, kw_args, -1); // White.
|
||||
int arg_s =
|
||||
py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_size), arg_img->w * 0.1f);
|
||||
py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_size), arg_img->w / 10);
|
||||
int arg_thickness =
|
||||
py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_thickness), 1);
|
||||
bool arg_fill =
|
||||
py_helper_keyword_int(n_args, args, 5, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_fill), false);
|
||||
|
||||
for (int i=0; i<array_length(kpts_obj->kpts); i++) {
|
||||
for (int i = 0, ii = array_length(kpts_obj->kpts); i < ii; i++) {
|
||||
kp_t *kp = array_at(kpts_obj->kpts, i);
|
||||
int cx = kp->x;
|
||||
int cy = kp->y;
|
||||
int size = arg_s/2;
|
||||
int size = arg_s / 2;
|
||||
int si = sin_table[kp->angle] * size;
|
||||
int co = cos_table[kp->angle] * size;
|
||||
imlib_draw_line(arg_img, cx, cy, cx+co, cy+si, arg_c);
|
||||
imlib_draw_circle(arg_img, cx, cy, size, arg_c);
|
||||
imlib_draw_line(arg_img, cx, cy, cx + co, cy + si, arg_c, arg_thickness);
|
||||
imlib_draw_circle(arg_img, cx, cy, size, arg_c, arg_thickness, arg_fill);
|
||||
}
|
||||
|
||||
return args[0];
|
||||
@ -4572,6 +4637,7 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_draw_circle), MP_ROM_PTR(&py_image_draw_circle_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_draw_string), MP_ROM_PTR(&py_image_draw_string_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_draw_cross), MP_ROM_PTR(&py_image_draw_cross_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_draw_arrow), MP_ROM_PTR(&py_image_draw_arrow_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_draw_keypoints), MP_ROM_PTR(&py_image_draw_keypoints_obj)},
|
||||
/* Binary Methods */
|
||||
{MP_ROM_QSTR(MP_QSTR_binary), MP_ROM_PTR(&py_image_binary_obj)},
|
||||
|
||||
@ -38,15 +38,6 @@ Q(width)
|
||||
Q(height)
|
||||
Q(format)
|
||||
Q(size)
|
||||
Q(get_pixel)
|
||||
Q(rgbtuple)
|
||||
Q(set_pixel)
|
||||
Q(draw_line)
|
||||
Q(draw_rectangle)
|
||||
Q(draw_circle)
|
||||
Q(draw_string)
|
||||
Q(draw_cross)
|
||||
Q(draw_keypoints)
|
||||
Q(morph)
|
||||
Q(midpoint)
|
||||
Q(mean)
|
||||
@ -70,7 +61,6 @@ Q(find_edges)
|
||||
Q(find_hog)
|
||||
Q(cmp_lbp)
|
||||
Q(quality)
|
||||
Q(color)
|
||||
Q(roi)
|
||||
Q(offset)
|
||||
Q(threshold)
|
||||
@ -330,6 +320,55 @@ Q(CPUFREQ_216MHZ)
|
||||
Q(get_frequency)
|
||||
Q(set_frequency)
|
||||
|
||||
// Get Pixel
|
||||
Q(get_pixel)
|
||||
Q(rgbtuple)
|
||||
|
||||
// Set Pixel
|
||||
Q(set_pixel)
|
||||
Q(color)
|
||||
|
||||
// Draw Line
|
||||
Q(draw_line)
|
||||
// duplicate Q(color)
|
||||
Q(thickness)
|
||||
|
||||
// Draw Rectangle
|
||||
Q(draw_rectangle)
|
||||
// duplicate Q(color)
|
||||
// duplicate Q(thickness)
|
||||
Q(fill)
|
||||
|
||||
// Draw Circle
|
||||
Q(draw_circle)
|
||||
// duplicate Q(color)
|
||||
// duplicate Q(thickness)
|
||||
// duplicate Q(fill)
|
||||
|
||||
// Draw String
|
||||
Q(draw_string)
|
||||
// duplicate Q(color)
|
||||
// duplicate Q(scale)
|
||||
|
||||
// Draw Cross
|
||||
Q(draw_cross)
|
||||
// duplicate Q(color)
|
||||
// duplicate Q(size)
|
||||
// duplicate Q(thickness)
|
||||
|
||||
// Draw Arrow
|
||||
Q(draw_arrow)
|
||||
// duplicate Q(color)
|
||||
// duplicate Q(size)
|
||||
// duplicate Q(thickness)
|
||||
|
||||
// Draw Keypoints
|
||||
Q(draw_keypoints)
|
||||
// duplicate Q(color)
|
||||
// duplicate Q(size)
|
||||
// duplicate Q(thickness)
|
||||
// duplicate Q(fill)
|
||||
|
||||
// Binary
|
||||
Q(binary)
|
||||
Q(invert)
|
||||
|
||||
31
usr/examples/03-Drawing/arrow_drawing.py
Normal file
31
usr/examples/03-Drawing/arrow_drawing.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Arrow Drawing
|
||||
#
|
||||
# This example shows off drawing arrows on the OpenMV Cam.
|
||||
|
||||
import sensor, image, time, pyb
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565) # or GRAYSCALE...
|
||||
sensor.set_framesize(sensor.QVGA) # or QQVGA...
|
||||
sensor.skip_frames(time = 2000)
|
||||
clock = time.clock()
|
||||
|
||||
while(True):
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
|
||||
for i in range(10):
|
||||
x0 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y0 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
x1 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y1 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
r = (pyb.rng() % 127) + 128
|
||||
g = (pyb.rng() % 127) + 128
|
||||
b = (pyb.rng() % 127) + 128
|
||||
|
||||
# If the first argument is a scaler then this method expects
|
||||
# to see x0, y0, x1, and y1. Otherwise, it expects a (x0,y0,x1,y1) tuple.
|
||||
img.draw_arrow(x0, y0, x1, y1, color = (r, g, b), size = 30, thickness = 2)
|
||||
|
||||
print(clock.fps())
|
||||
31
usr/examples/03-Drawing/circle_drawing.py
Normal file
31
usr/examples/03-Drawing/circle_drawing.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Circle Drawing
|
||||
#
|
||||
# This example shows off drawing circles on the OpenMV Cam.
|
||||
|
||||
import sensor, image, time, pyb
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565) # or GRAYSCALE...
|
||||
sensor.set_framesize(sensor.QVGA) # or QQVGA...
|
||||
sensor.skip_frames(time = 2000)
|
||||
clock = time.clock()
|
||||
|
||||
while(True):
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
|
||||
for i in range(10):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
radius = pyb.rng() % (max(img.height(), img.width())//2)
|
||||
|
||||
r = (pyb.rng() % 127) + 128
|
||||
g = (pyb.rng() % 127) + 128
|
||||
b = (pyb.rng() % 127) + 128
|
||||
|
||||
# If the first argument is a scaler then this method expects
|
||||
# to see x, y, and radius. Otherwise, it expects a (x,y,radius) tuple.
|
||||
img.draw_circle(x, y, radius, color = (r, g, b), thickness = 2, fill = False)
|
||||
|
||||
print(clock.fps())
|
||||
@ -1,55 +0,0 @@
|
||||
# Color Drawing Example
|
||||
#
|
||||
# This example shows off your OpenMV Cam's built-in drawing capabilities. This
|
||||
# example was originally a test but serves as good reference code. Please put
|
||||
# your IDE into non-JPEG mode to see the best drawing quality.
|
||||
|
||||
import sensor, image, time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_framesize(sensor.QVGA)
|
||||
|
||||
# All drawing functions use the same code to pass color.
|
||||
# So we just need to test one function.
|
||||
|
||||
while(True):
|
||||
|
||||
# Test Draw Line (GRAYSCALE)
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for i in range(img.width()):
|
||||
c = ((i * 255) + (img.width()/2)) / img.width()
|
||||
img.draw_line([i, 0, i, img.height()-1], color = int(c))
|
||||
sensor.snapshot()
|
||||
time.sleep(1000)
|
||||
|
||||
# Test Draw Line (RGB565)
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for i in range(img.width()):
|
||||
c = ((i * 255) + (img.width()/2)) / img.width()
|
||||
img.draw_line([i, 0, i, img.height()-1], color = [int(c), 0, 0])
|
||||
sensor.snapshot()
|
||||
time.sleep(1000)
|
||||
|
||||
# Test Draw Line (RGB565)
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for i in range(img.width()):
|
||||
c = ((i * 255) + (img.width()/2)) / img.width()
|
||||
img.draw_line([i, 0, i, img.height()-1], color = [0, int(c), 0])
|
||||
sensor.snapshot()
|
||||
time.sleep(1000)
|
||||
|
||||
# Test Draw Line (RGB565)
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for i in range(img.width()):
|
||||
c = ((i * 255) + (img.width()/2)) / img.width()
|
||||
img.draw_line([i, 0, i, img.height()-1], color = [0, 0, int(c)])
|
||||
sensor.snapshot()
|
||||
time.sleep(1000)
|
||||
@ -1,118 +0,0 @@
|
||||
# Crazy Drawing Example
|
||||
#
|
||||
# This example shows off your OpenMV Cam's built-in drawing capabilities. This
|
||||
# example was originally a test but serves as good reference code. Please put
|
||||
# your IDE into non-JPEG mode to see the best drawing quality.
|
||||
|
||||
import pyb, sensor, image, math
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_framesize(sensor.QVGA)
|
||||
|
||||
while(True):
|
||||
|
||||
# Test Set Pixel
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.set_pixel(x, y, 255)
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.set_pixel(x, y, (255, 255, 255))
|
||||
|
||||
# Test Draw Line
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x0 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y0 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
x1 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y1 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.draw_line([x0, y0, x1, y1])
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x0 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y0 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
x1 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y1 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.draw_line([x0, y0, x1, y1])
|
||||
|
||||
# Test Draw Rectangle
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
w = (pyb.rng() % img.width())
|
||||
h = (pyb.rng() % img.height())
|
||||
img.draw_rectangle([x, y, w, h])
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
w = (pyb.rng() % img.width())
|
||||
h = (pyb.rng() % img.height())
|
||||
img.draw_rectangle([x, y, w, h])
|
||||
|
||||
# Test Draw Circle
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
r = (pyb.rng() % (img.width() if (img.width() > img.height()) else img.height()))
|
||||
img.draw_circle(x, y, r)
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
r = (pyb.rng() % (img.width() if (img.width() > img.height()) else img.height()))
|
||||
img.draw_circle(x, y, r)
|
||||
|
||||
# Test Draw String
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.draw_string(x, y, "Hello\nWorld!")
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.draw_string(x, y, "Hello\nWorld!")
|
||||
|
||||
# Test Draw Cross
|
||||
sensor.set_pixformat(sensor.GRAYSCALE)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.draw_cross(x, y)
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
for i in range(10):
|
||||
img = sensor.snapshot()
|
||||
for j in range(100):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
img.draw_cross(x, y)
|
||||
29
usr/examples/03-Drawing/cross_drawing.py
Normal file
29
usr/examples/03-Drawing/cross_drawing.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Cross Drawing
|
||||
#
|
||||
# This example shows off drawing crosses on the OpenMV Cam.
|
||||
|
||||
import sensor, image, time, pyb
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565) # or GRAYSCALE...
|
||||
sensor.set_framesize(sensor.QVGA) # or QQVGA...
|
||||
sensor.skip_frames(time = 2000)
|
||||
clock = time.clock()
|
||||
|
||||
while(True):
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
|
||||
for i in range(10):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
r = (pyb.rng() % 127) + 128
|
||||
g = (pyb.rng() % 127) + 128
|
||||
b = (pyb.rng() % 127) + 128
|
||||
|
||||
# If the first argument is a scaler then this method expects
|
||||
# to see x and y. Otherwise, it expects a (x,y) tuple.
|
||||
img.draw_cross(x, y, color = (r, g, b), size = 10, thickness = 2)
|
||||
|
||||
print(clock.fps())
|
||||
31
usr/examples/03-Drawing/line_drawing.py
Normal file
31
usr/examples/03-Drawing/line_drawing.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Line Drawing
|
||||
#
|
||||
# This example shows off drawing lines on the OpenMV Cam.
|
||||
|
||||
import sensor, image, time, pyb
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565) # or GRAYSCALE...
|
||||
sensor.set_framesize(sensor.QVGA) # or QQVGA...
|
||||
sensor.skip_frames(time = 2000)
|
||||
clock = time.clock()
|
||||
|
||||
while(True):
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
|
||||
for i in range(10):
|
||||
x0 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y0 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
x1 = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y1 = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
r = (pyb.rng() % 127) + 128
|
||||
g = (pyb.rng() % 127) + 128
|
||||
b = (pyb.rng() % 127) + 128
|
||||
|
||||
# If the first argument is a scaler then this method expects
|
||||
# to see x0, y0, x1, and y1. Otherwise, it expects a (x0,y0,x1,y1) tuple.
|
||||
img.draw_line(x0, y0, x1, y1, color = (r, g, b), thickness = 2)
|
||||
|
||||
print(clock.fps())
|
||||
31
usr/examples/03-Drawing/rectangle_drawing.py
Normal file
31
usr/examples/03-Drawing/rectangle_drawing.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Rectangle Drawing
|
||||
#
|
||||
# This example shows off drawing rectangles on the OpenMV Cam.
|
||||
|
||||
import sensor, image, time, pyb
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565) # or GRAYSCALE...
|
||||
sensor.set_framesize(sensor.QVGA) # or QQVGA...
|
||||
sensor.skip_frames(time = 2000)
|
||||
clock = time.clock()
|
||||
|
||||
while(True):
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
|
||||
for i in range(10):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
w = (pyb.rng() % (img.width()//2))
|
||||
h = (pyb.rng() % (img.height()//2))
|
||||
r = (pyb.rng() % 127) + 128
|
||||
g = (pyb.rng() % 127) + 128
|
||||
b = (pyb.rng() % 127) + 128
|
||||
|
||||
# If the first argument is a scaler then this method expects
|
||||
# to see x, y, w, and h. Otherwise, it expects a (x,y,w,h) tuple.
|
||||
img.draw_rectangle(x, y, w, h, color = (r, g, b), thickness = 2, fill = False)
|
||||
|
||||
print(clock.fps())
|
||||
29
usr/examples/03-Drawing/text_drawing.py
Normal file
29
usr/examples/03-Drawing/text_drawing.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Text Drawing
|
||||
#
|
||||
# This example shows off drawing text on the OpenMV Cam.
|
||||
|
||||
import sensor, image, time, pyb
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565) # or GRAYSCALE...
|
||||
sensor.set_framesize(sensor.QVGA) # or QQVGA...
|
||||
sensor.skip_frames(time = 2000)
|
||||
clock = time.clock()
|
||||
|
||||
while(True):
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
|
||||
for i in range(10):
|
||||
x = (pyb.rng() % (2*img.width())) - (img.width()//2)
|
||||
y = (pyb.rng() % (2*img.height())) - (img.height()//2)
|
||||
r = (pyb.rng() % 127) + 128
|
||||
g = (pyb.rng() % 127) + 128
|
||||
b = (pyb.rng() % 127) + 128
|
||||
|
||||
# If the first argument is a scaler then this method expects
|
||||
# to see x, y, and text. Otherwise, it expects a (x,y,text) tuple.
|
||||
img.draw_string(x, y, "Hello World!", color = (r, g, b), scale = 2)
|
||||
|
||||
print(clock.fps())
|
||||
Loading…
Reference in New Issue
Block a user