From 88cd8dcb5c24f36d9e3d6f6b891f07d78bccfc2e Mon Sep 17 00:00:00 2001 From: MrDave Date: Sat, 23 Nov 2019 21:13:03 -0700 Subject: [PATCH] Add motion roi option --- src/conf.cpp | 14 +++++++++----- src/conf.hpp | 2 +- src/event.cpp | 28 +++++++++++++++++++--------- src/motion_loop.cpp | 22 +++++++++++++++------- src/picture.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/picture.hpp | 1 + 6 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/conf.cpp b/src/conf.cpp index d99227cf..ca9642a3 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -349,7 +349,7 @@ struct ctx_parm config_parms[] = { { "picture_output_motion", "# Output pictures with only the pixels moving object (ghost images)", - 0, PARM_TYP_BOOL, PARM_CAT_03, WEBUI_LEVEL_LIMITED }, + 0, PARM_TYP_STRING, PARM_CAT_03, WEBUI_LEVEL_LIMITED }, { "picture_type", "# Format for the output pictures.", @@ -1945,12 +1945,16 @@ static void conf_edit_picture_output(struct ctx_cam *cam, std::string &parm, enu MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","picture_output",_("picture_output")); } static void conf_edit_picture_output_motion(struct ctx_cam *cam, std::string &parm, enum PARM_ACT pact) { - if (pact == PARM_ACT_DFLT){ - cam->conf->picture_output_motion = FALSE; + if (pact == PARM_ACT_DFLT) { + cam->conf->picture_output_motion = "off"; } else if (pact == PARM_ACT_SET){ - conf_edit_set_bool(cam->conf->picture_output_motion, parm); + if ((parm == "on") || (parm == "off") || (parm == "roi")) { + cam->conf->picture_output_motion = parm; + } else { + MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, _("Invalid picture_output_motion %s"), parm); + } } else if (pact == PARM_ACT_GET){ - conf_edit_get_bool(parm, cam->conf->picture_output_motion); + parm = cam->conf->picture_output; } return; MOTION_LOG(DBG, TYPE_ALL, NO_ERRNO,"%s:%s","picture_output_motion",_("picture_output_motion")); diff --git a/src/conf.hpp b/src/conf.hpp index d9a987ee..addf8609 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -101,7 +101,7 @@ /* Picture output configuration parameters */ std::string picture_output; - int picture_output_motion; + std::string picture_output_motion; std::string picture_type; int picture_quality; std::string picture_exif; diff --git a/src/event.cpp b/src/event.cpp index f63860a0..94a1a5aa 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -345,9 +345,8 @@ static void event_imagem_detect(struct ctx_cam *cam, motion_event evnt ,struct ctx_image_data *img_data, char *fname ,void *ftype, struct timespec *ts1) { - struct ctx_config *conf = cam->conf; - char fullfilenamem[PATH_MAX]; - char filenamem[PATH_MAX]; + char fullfilename[PATH_MAX]; + char filename[PATH_MAX]; int retcd; (void)evnt; @@ -355,17 +354,28 @@ static void event_imagem_detect(struct ctx_cam *cam, motion_event evnt (void)fname; (void)ftype; - if (conf->picture_output_motion) { - mystrftime(cam, filenamem, sizeof(filenamem), cam->conf->picture_filename.c_str(), ts1, NULL, 0); - retcd = snprintf(fullfilenamem, PATH_MAX, "%s/%sm.%s" - , cam->conf->target_dir.c_str(), filenamem, imageext(cam)); + if (cam->conf->picture_output_motion == "on") { + mystrftime(cam, filename, sizeof(filename), cam->conf->picture_filename.c_str(), ts1, NULL, 0); + retcd = snprintf(fullfilename, PATH_MAX, "%s/%sm.%s" + , cam->conf->target_dir.c_str(), filename, imageext(cam)); if ((retcd < 0) || (retcd >= PATH_MAX)){ MOTION_LOG(ERR, TYPE_EVENTS, NO_ERRNO ,_("Error creating image motion file name")); return; } - pic_save_norm(cam, fullfilenamem, cam->imgs.image_motion.image_norm, FTYPE_IMAGE_MOTION); - event(cam, EVENT_FILECREATE, NULL, fullfilenamem, (void *)FTYPE_IMAGE, ts1); + pic_save_norm(cam, fullfilename, cam->imgs.image_motion.image_norm, FTYPE_IMAGE_MOTION); + event(cam, EVENT_FILECREATE, NULL, fullfilename, (void *)FTYPE_IMAGE, ts1); + } else if (cam->conf->picture_output_motion == "roi") { + mystrftime(cam, filename, sizeof(filename), cam->conf->picture_filename.c_str(), ts1, NULL, 0); + retcd = snprintf(fullfilename, PATH_MAX, "%s/%sr.%s" + , cam->conf->target_dir.c_str(), filename, imageext(cam)); + if ((retcd < 0) || (retcd >= PATH_MAX)){ + MOTION_LOG(ERR, TYPE_EVENTS, NO_ERRNO + ,_("Error creating image motion roi file name")); + return; + } + pic_save_roi(cam, fullfilename, cam->current_image->image_norm); + event(cam, EVENT_FILECREATE, NULL, fullfilename, (void *)FTYPE_IMAGE, ts1); } } diff --git a/src/motion_loop.cpp b/src/motion_loop.cpp index d6cc8911..26a97a81 100644 --- a/src/motion_loop.cpp +++ b/src/motion_loop.cpp @@ -229,7 +229,7 @@ static void mlp_detected(struct ctx_cam *cam, int dev, struct ctx_image_data *im if (conf->stream_motion && !cam->motapp->setup_mode && img->shot != 1){ event(cam, EVENT_STREAM, img, NULL, NULL, &img->imgts); } - if (conf->picture_output_motion){ + if (conf->picture_output_motion != "off"){ event(cam, EVENT_IMAGEM_DETECTED, NULL, NULL, NULL, &img->imgts); } } @@ -947,16 +947,24 @@ static void mlp_overlay(struct ctx_cam *cam){ char tmp[PATH_MAX]; if (cam->smartmask_speed && - (cam->conf->picture_output_motion || cam->conf->movie_output_motion || - cam->motapp->setup_mode || (cam->stream.motion.cnct_count > 0))) + ((cam->conf->picture_output_motion != "off") || + cam->conf->movie_output_motion || + cam->motapp->setup_mode || + (cam->stream.motion.cnct_count > 0))) draw_smartmask(cam, cam->imgs.image_motion.image_norm); - if (cam->imgs.largest_label && (cam->conf->picture_output_motion || cam->conf->movie_output_motion || - cam->motapp->setup_mode || (cam->stream.motion.cnct_count > 0))) + if (cam->imgs.largest_label && + ((cam->conf->picture_output_motion != "off") || + cam->conf->movie_output_motion || + cam->motapp->setup_mode || + (cam->stream.motion.cnct_count > 0))) draw_largest_label(cam, cam->imgs.image_motion.image_norm); - if (cam->imgs.mask && (cam->conf->picture_output_motion || cam->conf->movie_output_motion || - cam->motapp->setup_mode || (cam->stream.motion.cnct_count > 0))) + if (cam->imgs.mask && + ((cam->conf->picture_output_motion != "off") || + cam->conf->movie_output_motion || + cam->motapp->setup_mode || + (cam->stream.motion.cnct_count > 0))) draw_fixed_mask(cam, cam->imgs.image_motion.image_norm); if (cam->conf->text_changes) { diff --git a/src/picture.cpp b/src/picture.cpp index c10cab4b..f505dd53 100644 --- a/src/picture.cpp +++ b/src/picture.cpp @@ -308,6 +308,46 @@ void pic_save_norm(struct ctx_cam *cam, char *file, unsigned char *image, int ft myfclose(picture); } +/* Saves image to a file in format requested */ +void pic_save_roi(struct ctx_cam *cam, char *file, unsigned char *image) { + FILE *picture; + int image_size, sz, indxh; + ctx_coord *bx; + unsigned char *buf, *img; + + picture = myfopen(file, "w"); + if (!picture) { + MOTION_LOG(ERR, TYPE_ALL, SHOW_ERRNO + ,_("Can't write picture to file %s"), file); + return; + } + + bx = &cam->current_image->location; + + if ((bx->width <64) || (bx->height <64)) return; + + image_size = bx->width * bx->height; + + buf =(unsigned char*) mymalloc(image_size); + img =(unsigned char*) mymalloc(image_size); + + for (indxh=bx->miny; indxhmaxy; indxh++){ + memcpy(img+((indxh-bx->miny)*bx->width), image+(indxh*cam->imgs.width)+bx->minx, bx->width); + } + + sz = jpgutl_put_grey(buf, image_size, img + ,bx->width, bx->height + ,cam->conf->picture_quality, cam + ,&(cam->current_image->imgts), bx); + + fwrite(buf, sz, 1, picture); + + free(buf); + free(img); + + myfclose(picture); +} + /** Get the pgm file used as fixed mask */ unsigned char *pic_load_pgm(FILE *picture, int width, int height) { diff --git a/src/picture.hpp b/src/picture.hpp index f48440a0..85df9fa4 100644 --- a/src/picture.hpp +++ b/src/picture.hpp @@ -15,6 +15,7 @@ int pic_put_memory(struct ctx_cam *cam, unsigned char* dest_image , int image_size, unsigned char *image, int quality, int width, int height); void pic_save_norm(struct ctx_cam *cam, char *file, unsigned char *image, int ftype); + void pic_save_roi(struct ctx_cam *cam, char *file, unsigned char *image); unsigned char *pic_load_pgm(FILE *picture, int width, int height); void pic_scale_img(int width_src, int height_src, unsigned char *img_src, unsigned char *img_dst); void pic_save_preview(struct ctx_cam *cam, struct ctx_image_data *img);