diff --git a/src/omv/img/bmp.c b/src/omv/img/bmp.c index 819f5ef06..34eb9145a 100644 --- a/src/omv/img/bmp.c +++ b/src/omv/img/bmp.c @@ -22,8 +22,8 @@ bool bmp_read_geometry(FIL *fp, image_t *img, const char *path, bmp_read_setting uint32_t file_size; read_long(fp, &file_size); - read_long_ignore(fp); - read_long_ignore(fp); + read_word_ignore(fp); + read_word_ignore(fp); uint32_t header_size; read_long(fp, &header_size); diff --git a/src/omv/img/imlib.c b/src/omv/img/imlib.c index dc72fa59f..9688561ee 100644 --- a/src/omv/img/imlib.c +++ b/src/omv/img/imlib.c @@ -406,156 +406,126 @@ void imlib_invert(image_t *img) } } -void imlib_and(image_t *img, const char *file, image_t *other) +static void imlib_and_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] &= other[i]; } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] &= ((uint16_t *) other)[i]; } } } -void imlib_nand(image_t *img, const char *file, image_t *other) +void imlib_and(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_and_line_op); +} + +static void imlib_nand_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = ~(pixels[i] & other[i]); } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = ~(pixels[i] & ((uint16_t *) other)[i]); } } } -void imlib_or(image_t *img, const char *file, image_t *other) +void imlib_nand(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_nand_line_op); +} + +static void imlib_or_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] |= other[i]; } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] |= ((uint16_t *) other)[i]; } } } -void imlib_nor(image_t *img, const char *file, image_t *other) +void imlib_or(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_or_line_op); +} + +static void imlib_nor_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = ~(pixels[i] | other[i]); } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = ~(pixels[i] | ((uint16_t *) other)[i]); } } } -void imlib_xor(image_t *img, const char *file, image_t *other) +void imlib_nor(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_nor_line_op); +} + +static void imlib_xor_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] ^= other[i]; } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] ^= ((uint16_t *) other)[i]; } } } -void imlib_xnor(image_t *img, const char *file, image_t *other) +void imlib_xor(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_xor_line_op); +} + +static void imlib_xnor_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = ~(pixels[i] ^ other[i]); } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = ~(pixels[i] ^ ((uint16_t *) other)[i]); } } } +void imlib_xnor(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_xnor_line_op); +} + int imlib_pixels(image_t *img, rectangle_t *r) { rectangle_t rect; @@ -682,35 +652,30 @@ void imlib_negate(image_t *img) } } -void imlib_difference(image_t *img, const char *file, image_t *other) +static void imlib_difference_line_op(image_t *img, int line, uint8_t *other) { if (IM_IS_GS(img)) { - uint8_t *pixels = img->pixels; - if (file) { - - } else { - uint8_t *other_pixels = other->pixels; - for (int i=0, j=img->w*img->h; ipixels + (img->w * line); + for (int i=0; iw; i++) { + pixels[i] = abs(pixels[i] - other[i]); } } else { - uint16_t *pixels = (uint16_t *) img->pixels; - if (file) { - - } else { - uint16_t *other_pixels = (uint16_t *) img->pixels; - for (int i=0, j=img->w*img->h; ipixels) + (img->w * line); + for (int i=0; iw; i++) { + const int pixel = pixels[i], other_pixel = ((uint16_t *) other)[i]; + const int r = abs(IM_R565(pixel) - IM_R565(other_pixel)); + const int g = abs(IM_G565(pixel) - IM_G565(other_pixel)); + const int b = abs(IM_B565(pixel) - IM_B565(other_pixel)); + pixels[i] = IM_RGB565(r, g, b); } } } +void imlib_difference(image_t *img, const char *path, image_t *other) +{ + imlib_image_operation(img, path, other, imlib_difference_line_op); +} + //////////////////////////////////////////////////////////////////////////////// uint32_t imlib_lab_distance(struct color *c0, struct color *c1) diff --git a/src/omv/img/imlib.h b/src/omv/img/imlib.h index 665839ef8..548723e18 100644 --- a/src/omv/img/imlib.h +++ b/src/omv/img/imlib.h @@ -355,12 +355,12 @@ void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int /* Binary functions */ void imlib_binary(image_t *img, int num_thresholds, simple_color_t *l_thresholds, simple_color_t *h_thresholds, bool invert); void imlib_invert(image_t *img); -void imlib_and(image_t *img, const char *file, image_t *other); -void imlib_nand(image_t *img, const char *file, image_t *other); -void imlib_or(image_t *img, const char *file, image_t *other); -void imlib_nor(image_t *img, const char *file, image_t *other); -void imlib_xor(image_t *img, const char *file, image_t *other); -void imlib_xnor(image_t *img, const char *file, image_t *other); +void imlib_and(image_t *img, const char *path, image_t *other); +void imlib_nand(image_t *img, const char *path, image_t *other); +void imlib_or(image_t *img, const char *path, image_t *other); +void imlib_nor(image_t *img, const char *path, image_t *other); +void imlib_xor(image_t *img, const char *path, image_t *other); +void imlib_xnor(image_t *img, const char *path, image_t *other); int imlib_pixels(image_t *img, rectangle_t *r); int imlib_centroid(image_t *img, int *x_center, int *y_center, rectangle_t *r); float imlib_orientation_radians(image_t *img, int *sum, int *x_center, int *y_center, rectangle_t *r); @@ -368,7 +368,7 @@ float imlib_orientation_degrees(image_t *img, int *sum, int *x_center, int *y_ce /* Background Subtraction (Frame Differencing) functions */ void imlib_negate(image_t *img); -void imlib_difference(image_t *img, const char *file, image_t *other); +void imlib_difference(image_t *img, const char *path, image_t *other); /* Clustering functions */ array_t *cluster_kmeans(array_t *points, int k); diff --git a/src/omv/py/py_image.c b/src/omv/py/py_image.c index 768b1a814..7fe82d01a 100644 --- a/src/omv/py/py_image.c +++ b/src/omv/py/py_image.c @@ -439,8 +439,6 @@ static mp_obj_t py_image_and(mp_obj_t img_obj, mp_obj_t other_obj) imlib_and(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_and(arg_img, NULL, arg_other); } return mp_const_none; @@ -456,8 +454,6 @@ static mp_obj_t py_image_nand(mp_obj_t img_obj, mp_obj_t other_obj) imlib_nand(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_nand(arg_img, NULL, arg_other); } return mp_const_none; @@ -473,8 +469,6 @@ static mp_obj_t py_image_or(mp_obj_t img_obj, mp_obj_t other_obj) imlib_or(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_or(arg_img, NULL, arg_other); } return mp_const_none; @@ -490,8 +484,6 @@ static mp_obj_t py_image_nor(mp_obj_t img_obj, mp_obj_t other_obj) imlib_nor(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_nor(arg_img, NULL, arg_other); } return mp_const_none; @@ -507,8 +499,6 @@ static mp_obj_t py_image_xor(mp_obj_t img_obj, mp_obj_t other_obj) imlib_xor(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_xor(arg_img, NULL, arg_other); } return mp_const_none; @@ -524,8 +514,6 @@ static mp_obj_t py_image_xnor(mp_obj_t img_obj, mp_obj_t other_obj) imlib_xnor(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_xnor(arg_img, NULL, arg_other); } return mp_const_none; @@ -607,8 +595,6 @@ static mp_obj_t py_image_difference(mp_obj_t img_obj, mp_obj_t other_obj) imlib_difference(arg_img, mp_obj_str_get_str(other_obj), NULL); } else { image_t *arg_other = py_image_cobj(other_obj); - PY_ASSERT_TRUE_MSG(IM_EQUAL(arg_img, arg_other), - "Invalid Argument: img_0_geometry != img_1_geometry"); imlib_difference(arg_img, NULL, arg_other); } return mp_const_none; diff --git a/usr/examples/motion_detection.py b/usr/examples/motion_detection.py new file mode 100644 index 000000000..6d731b57f --- /dev/null +++ b/usr/examples/motion_detection.py @@ -0,0 +1,41 @@ +# Motion Detection Example: +# +# This example demonstrates using frame differencing with your OpenMV Cam to do +# motion detection. After motion is detected your OpenMV Cam will take picture. + +import os, pyb, sensor, image, time + +if not "temp" in os.listdir(): os.mkdir("temp") # Make a temp directory + +sensor.reset() +sensor.set_framesize(sensor.QVGA) + +while(True): + sensor.set_pixformat(sensor.GRAYSCALE) # Grayscale is much faster than RGB. + + # Warm up the cam + for i in range(10): + sensor.snapshot() + + for i in [5, 4, 3, 2, 1]: + print("Saving background in... %d" % i) + time.sleep(1000) + + print("Saving background...") + sensor.snapshot().save("temp/bg.bmp") + + diff = 30 # wait 30 snapshot before taking picture + while(diff): + img = sensor.snapshot() + img.difference("temp/bg.bmp") + img.binary([(32, 255)]) + sum, x, y = img.centroid() + if sum > 100: # 100 pixels detected + img.draw_cross(x, y, color = 127) + diff -= 1 + + sensor.set_pixformat(sensor.RGB565) + # Warm up the cam + for i in range(10): + sensor.snapshot() + sensor.snapshot().save("temp/movement-%d" % pyb.rng()) # Save movement