Add min()/max() for frame differencing.

These have cool ghost image like affects and are useful for frame
differencing.
This commit is contained in:
Kwabena W. Agyeman 2018-01-17 02:13:55 -05:00
parent abf836519f
commit 432b39bc17
4 changed files with 102 additions and 0 deletions

View File

@ -1022,6 +1022,58 @@ void imlib_blend(image_t *img, const char *path, image_t *other, int alpha)
imlib_image_operation(img, path, other, imlib_blend_line_op, (void *) __PKHBT((256-alpha), alpha, 16));
}
static void imlib_max_line_op(image_t *img, int line, uint8_t *other, void *data)
{
data = data;
if (IM_IS_GS(img)) {
uint8_t *pixels = img->pixels + (img->w * line);
for (int i=0; i<img->w; i++) {
pixels[i] = IM_MAX(pixels[i], other[i]);
}
} else {
uint16_t *pixels = ((uint16_t *) img->pixels) + (img->w * line);
for (int i=0; i<img->w; i++) {
const int pixel = pixels[i], other_pixel = ((uint16_t *) other)[i];
const int r = IM_MAX(IM_R565(pixel), IM_R565(other_pixel));
const int g = IM_MAX(IM_G565(pixel), IM_G565(other_pixel));
const int b = IM_MAX(IM_B565(pixel), IM_B565(other_pixel));
pixels[i] = IM_RGB565(r, g, b);
}
}
}
void imlib_max(image_t *img, const char *path, image_t *other)
{
imlib_image_operation(img, path, other, imlib_max_line_op, NULL);
}
static void imlib_min_line_op(image_t *img, int line, uint8_t *other, void *data)
{
data = data;
if (IM_IS_GS(img)) {
uint8_t *pixels = img->pixels + (img->w * line);
for (int i=0; i<img->w; i++) {
pixels[i] = IM_MIN(pixels[i], other[i]);
}
} else {
uint16_t *pixels = ((uint16_t *) img->pixels) + (img->w * line);
for (int i=0; i<img->w; i++) {
const int pixel = pixels[i], other_pixel = ((uint16_t *) other)[i];
const int r = IM_MIN(IM_R565(pixel), IM_R565(other_pixel));
const int g = IM_MIN(IM_G565(pixel), IM_G565(other_pixel));
const int b = IM_MIN(IM_B565(pixel), IM_B565(other_pixel));
pixels[i] = IM_RGB565(r, g, b);
}
}
}
void imlib_min(image_t *img, const char *path, image_t *other)
{
imlib_image_operation(img, path, other, imlib_min_line_op, NULL);
}
////////////////////////////////////////////////////////////////////////////////
void imlib_chrominvar(image_t *img)

View File

@ -1118,6 +1118,8 @@ void imlib_negate(image_t *img);
void imlib_difference(image_t *img, const char *path, image_t *other);
void imlib_replace(image_t *img, const char *path, image_t *other);
void imlib_blend(image_t *img, const char *path, image_t *other, int alpha);
void imlib_max(image_t *img, const char *path, image_t *other);
void imlib_min(image_t *img, const char *path, image_t *other);
/* Image Morphing */
void imlib_morph(image_t *img, const int ksize, const int8_t *krn, const float m, const int b);

View File

@ -1288,6 +1288,44 @@ static mp_obj_t py_image_gaussian(uint n_args, const mp_obj_t *args, mp_map_t *k
return args[0];
}
static mp_obj_t py_image_max(mp_obj_t img_obj, mp_obj_t other_obj)
{
image_t *arg_img = py_image_cobj(img_obj);
PY_ASSERT_TRUE_MSG(IM_IS_MUTABLE(arg_img), "Image format is not supported.");
if (MP_OBJ_IS_STR(other_obj)) {
fb_alloc_mark();
imlib_max(arg_img, mp_obj_str_get_str(other_obj), NULL);
fb_alloc_mark();
} else {
image_t *arg_other = py_image_cobj(other_obj);
fb_alloc_mark();
imlib_max(arg_img, NULL, arg_other);
fb_alloc_free_till_mark();
}
return img_obj;
}
static mp_obj_t py_image_min(mp_obj_t img_obj, mp_obj_t other_obj)
{
image_t *arg_img = py_image_cobj(img_obj);
PY_ASSERT_TRUE_MSG(IM_IS_MUTABLE(arg_img), "Image format is not supported.");
if (MP_OBJ_IS_STR(other_obj)) {
fb_alloc_mark();
imlib_min(arg_img, mp_obj_str_get_str(other_obj), NULL);
fb_alloc_mark();
} else {
image_t *arg_other = py_image_cobj(other_obj);
fb_alloc_mark();
imlib_min(arg_img, NULL, arg_other);
fb_alloc_free_till_mark();
}
return img_obj;
}
static mp_obj_t py_image_linpolar(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
image_t *arg_img = py_image_cobj(args[0]);
@ -4143,6 +4181,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_negate_obj, py_image_negate);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_difference_obj, py_image_difference);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_replace_obj, py_image_replace);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_blend_obj, 2, py_image_blend);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_max_obj, py_image_max);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_min_obj, py_image_min);
/* Image Morphing */
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_morph_obj, 3, py_image_morph);
/* Image Filtering */
@ -4257,6 +4297,8 @@ static const mp_map_elem_t locals_dict_table[] = {
{MP_OBJ_NEW_QSTR(MP_QSTR_difference), (mp_obj_t)&py_image_difference_obj},
{MP_OBJ_NEW_QSTR(MP_QSTR_replace), (mp_obj_t)&py_image_replace_obj},
{MP_OBJ_NEW_QSTR(MP_QSTR_blend), (mp_obj_t)&py_image_blend_obj},
{MP_OBJ_NEW_QSTR(MP_QSTR_max), (mp_obj_t)&py_image_max_obj},
{MP_OBJ_NEW_QSTR(MP_QSTR_min), (mp_obj_t)&py_image_min_obj},
/* Image Morphing */
{MP_OBJ_NEW_QSTR(MP_QSTR_morph), (mp_obj_t)&py_image_morph_obj},
/* Image Filtering */

View File

@ -349,6 +349,12 @@ Q(CPUFREQ_216MHZ)
Q(get_frequency)
Q(set_frequency)
// Max
// duplicate Q(max)
// Min
// duplicate Q(min)
// Log Polar
Q(linpolar)
Q(reverse)