colorize_gtk
colorize_gtk_SOURCES = \
- ../src/ppm.c \
+ ../src/img.c \
../src/yuv.c \
../src/mark.c \
+ ../src/process.c \
image.c \
palette.c \
timeline.c \
static GtkWidget *bc_window = NULL;
static GtkObject *bright_adj;
static GtkObject *contrast_adj;
+static GtkObject *alpha_adj;
static void bc_destroy(GtkWidget *widget, gpointer priv)
{
mark_palette[mark_selected].bright = 0;
mark_palette[mark_selected].contrast = 1;
+ mark_palette[mark_selected].alpha = 1;
gtk_adjustment_set_value(GTK_ADJUSTMENT(bright_adj), mark_palette[mark_selected].bright * 100);
gtk_adjustment_set_value(GTK_ADJUSTMENT(contrast_adj), mark_palette[mark_selected].contrast * 100);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(alpha_adj), mark_palette[mark_selected].alpha * 100);
update_color(mark_selected);
- if (preview)
- draw_image(0, 0, -1, -1);
+ draw_image(0, 0, -1, -1); /* alpha may change, so always update */
}
static void apply_event(gpointer *priv)
mark_palette[mark_selected].bright = GTK_ADJUSTMENT(bright_adj)->value / 100.0;
mark_palette[mark_selected].contrast = GTK_ADJUSTMENT(contrast_adj)->value / 100.0;
+ mark_palette[mark_selected].alpha = GTK_ADJUSTMENT(alpha_adj)->value / 100.0;
update_color(mark_selected);
- if (preview)
- draw_image(0, 0, -1, -1);
+ draw_image(0, 0, -1, -1); /* alpha may change, so always update */
}
static GtkWidget *xpm_label_box( const gchar *stock_id,
GtkWidget *bright_scroll;
GtkWidget *contrast_label;
GtkWidget *contrast_scroll;
+ GtkWidget *alpha_label;
+ GtkWidget *alpha_scroll;
GtkWidget *button_apply;
GtkWidget *button_reset;
GtkWidget *box;
contrast_adj = gtk_adjustment_new(mark_palette[mark_selected].contrast * 100, -500, 501, 1, 1, 1);
contrast_scroll = gtk_hscale_new(GTK_ADJUSTMENT(contrast_adj));
gtk_widget_show(contrast_scroll);
+ alpha_label = gtk_label_new("Alpha:");
+ gtk_widget_show(GTK_WIDGET(alpha_label));
+ alpha_adj = gtk_adjustment_new(mark_palette[mark_selected].alpha * 100, 0, 101, 1, 1, 1);
+ alpha_scroll = gtk_hscale_new(GTK_ADJUSTMENT(alpha_adj));
+ gtk_widget_show(alpha_scroll);
/* buttons */
button_reset = gtk_button_new();
gtk_box_pack_start(GTK_BOX(vbox), bright_scroll, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(vbox), contrast_label, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(vbox), contrast_scroll, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), alpha_label, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), alpha_scroll, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 20);
gtk_widget_show(vbox);
gtk_adjustment_set_value(GTK_ADJUSTMENT(bright_adj), mark_palette[mark_selected].bright * 100);
gtk_adjustment_set_value(GTK_ADJUSTMENT(contrast_adj), mark_palette[mark_selected].contrast * 100);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(alpha_adj), mark_palette[mark_selected].alpha * 100);
}
#include "image.h"
#include "colorize.h"
#include "../src/mark.h"
-#include "../src/ppm.h"
+#include "../src/img.h"
#include "../src/yuv.h"
#include "../src/dir_seperator.h"
#include "../lib/darray.h"
#include "../lib/colorize.h"
+#include "../src/process.h"
#include "palette.h"
#include "timeline.h"
-#define min(x,y) ((x < y) ? x : y)
-
struct colorize_priv {
GtkWidget *window;
GdkPixbuf *pixbuf;
- int width, height;
+ int width, height, alpha;
char filename[256];
char folder[256];
+ unsigned short *img;
};
static void colorize_destroy(GtkWidget *widget, gpointer priv)
gtk_widget_destroy(cp->window);
g_object_unref(cp->pixbuf);
+ free(cp->img);
free(cp);
}
static void save_event(gpointer *priv)
{
struct colorize_priv *cp = (struct colorize_priv *) priv;
- guchar *data;
- int rs, i, j;
- unsigned short *buffer;
GtkWidget *dialog;
char *filename = NULL;
if (!filename)
return;
- data = gdk_pixbuf_get_pixels(cp->pixbuf);
- rs = gdk_pixbuf_get_rowstride(cp->pixbuf);
- buffer = malloc(cp->width*cp->height*3*sizeof(unsigned short));
-
- for (i = 0; i < cp->height; i++) {
- for (j = 0; j < cp->width; j++) {
- buffer[(i*cp->width+j)*3+0] = data[i*rs+j*3+0] << 8;
- buffer[(i*cp->width+j)*3+1] = data[i*rs+j*3+1] << 8;
- buffer[(i*cp->width+j)*3+2] = data[i*rs+j*3+2] << 8;
- }
- }
-
- save_img(buffer, cp->width, cp->height, filename, 0);
+ printf("alpha=%d\n", cp->alpha);
+ save_img(cp->img, cp->width, cp->height, cp->alpha, filename, 0);
}
static void dummy_event(gpointer *priv)
void colorize_image(void)
{
- darray_t *gI = NULL, *cI = NULL, *markIm = NULL, *ntscIm = NULL;
- double *ptr, *ptr2, *ptr3;
+ darray_t *gI = NULL, *cI = NULL, *I = NULL, *mI = NULL;
+ double *ptr_gI = NULL, *ptr_cI = NULL, *ptr_y = NULL, *ptr_u = NULL, *ptr_v = NULL, *ptr_a = NULL, *ptr_r = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_m = NULL;
int dims[4];
int width = img_width, height = img_height;
- int features, change_bc;
+ int features, change_bc, change_alpha;
+ char *feat_names[20];
int i, j;
int c;
int rc;
printerror("No memory: failed to create grey image array");
goto error;
}
- ptr = darrayGetPr(gI);
- img2array(img_grey_buffer, img_width, img_height, ptr, width, height);
+ ptr_gI = darrayGetPr(gI);
+ img2array_short(img_grey_buffer, width, height, ptr_gI, width, height);
/* generade marked color image */
dims[0] = width; dims[1] = height; dims[2] = 3; dims[3] = 1;
printerror("No memory: failed to create marked image array");
goto error;
}
- ptr = darrayGetPr(cI);
- img2array(img_grey_buffer, img_width, img_height, ptr, width, height);
- change_bc = 0;
- for (i = 0; i < img_height; i++) {
- for (j = 0; j < img_width; j++) {
+ ptr_cI = darrayGetPr(cI);
+ img2array_short(img_grey_buffer, width, height, ptr_cI, width, height);
+ change_bc = change_alpha = 0;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
/* do not apply mask on index 0 */
- c = img_mark_buffer[i*img_width+j];
+ c = img_mark_buffer[i*width+j];
if (c == 0)
continue;
/* check for any brightness/contrast change */
if (mark_palette[c-1].bright != 0 || mark_palette[c-1].contrast != 1)
change_bc = 1;
+ /* check for any alpha change */
+ if (mark_palette[c-1].alpha < 1)
+ change_alpha = 1;
/* do not apply white pixles, this meas: keep original color */
if (mark_palette[c-1].r == 255 && mark_palette[c-1].g == 255 && mark_palette[c-1].b == 255)
continue;
- ptr[i*width+j] = mark_palette[c-1].r / 255.0F;
- ptr[i*width+j + width*height] = mark_palette[c-1].g / 255.0F;
- ptr[i*width+j + width*height*2] = mark_palette[c-1].b / 255.0F;
+ ptr_cI[i*width+j] = mark_palette[c-1].r / 255.0F;
+ ptr_cI[i*width+j + width*height] = mark_palette[c-1].g / 255.0F;
+ ptr_cI[i*width+j + width*height*2] = mark_palette[c-1].b / 255.0F;
}
}
- // convert grey image into YUV
- ptr = darrayGetPr(gI);
- rgb2yuv(ptr, ptr, width, height);
+ rc = alloc_I_arrays(&I, &mI, width, height, 1, &features, feat_names, change_alpha, change_bc);
+ if (rc)
+ goto error;
- // convert marked image into YUV
- ptr = darrayGetPr(cI);
- rgb2yuv(ptr, ptr, width, height);
+ set_I_ptr(I, mI, width, height, 0, features, change_alpha, change_bc, &ptr_y, &ptr_u, &ptr_v, &ptr_a, &ptr_r, &ptr_b, &ptr_c, &ptr_m);
- /* create color mask and ntsc arrays for the colorization process */
- dims[0] = width; dims[1] = height; dims[2] = 1;
- markIm = darrayCreate(3, dims);
- if (!markIm) {
- printerror("No memory: failed to create color array");
- goto error;
- }
- features = (change_bc) ? 4 : 2;
- dims[0] = width; dims[1] = height; dims[2] = features+1; dims[3] = 1;
- ntscIm = darrayCreate(4, dims);
- if (!ntscIm) {
- printerror("No memory: failed to create ntsc array");
- goto error;
- }
+ // convert original image into YUV
+ rgb2yuv(ptr_gI, ptr_gI, width, height);
+ // convert maked image into YUV
+ rgb2yuv(ptr_cI, ptr_cI, width, height);
- /* apply mask to markIm */
- ptr = darrayGetPr(markIm);
- for (i = 0; i < img_height; i++) {
- for (j = 0; j < img_width; j++) {
+ /* apply mask to mI */
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
/* do not apply mask on index 0 */
- c = img_mark_buffer[i*img_width+j];
- ptr[i*width+j] = (c == 0) ? 0.0F : 1.0F;
+ c = img_mark_buffer[i*width+j];
+ ptr_m[i*width+j] = (c == 0) ? 0.0F : 1.0F;
}
}
- // generate NTSC image: use luminance from original image and chrominance from original or marked image
- ptr = darrayGetPr(gI);
- ptr2 = darrayGetPr(cI);
- ptr3 = darrayGetPr(ntscIm);
- memcpy(ptr3, ptr, width * height * sizeof(double));
- for (i = 0; i < img_height; i++) {
- for (j = 0; j < img_width; j++) {
- c = img_mark_buffer[i*img_width+j];
- if (c == 0) {
- ptr3[width * height + width * i + j] = ptr[width * height + width * i + j];
- ptr3[width * height * 2 + width * i + j] = ptr[width * height * 2 + width * i + j];
- } else {
- ptr3[width * height + width * i + j] = ptr2[width * height + width * i + j];
- ptr3[width * height * 2 + width * i + j] = ptr2[width * height * 2 + width * i + j];
- }
- }
- }
- /* if we have a change, we modify brightness+contrast first */
- if (change_bc) {
- /* apply brightness and contrast from makred pixles to grey image */
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- ptr3[i*width+j] = ptr[i*width+j];
- if (j < img_width && i < img_height) {
- /* use unchanged brightness and contrast on index 0 */
- c = img_mark_buffer[i*img_width+j];
- } else
- c = 0;
- if (c == 0) {
- ptr3[i*width+j + width*height*3] = 0;
- ptr3[i*width+j + width*height*4] = 0.1;
- } else {
- ptr3[i*width+j + width*height*3] = mark_palette[c-1].bright / 10.0;
- ptr3[i*width+j + width*height*4] = mark_palette[c-1].contrast / 10.0;
- }
- }
- }
- }
+ prepare_arrays(width, height, change_alpha, change_bc, img_mark_buffer, ptr_gI, ptr_cI, ptr_y, ptr_u, ptr_v, ptr_a, ptr_r, ptr_b, ptr_c, ptr_m, NO_TEST);
/* destroy temporary gI and cI */
darrayDestroy(gI);
cI = NULL;
/* render u and v change */
- rc = colorize(ntscIm, markIm, NULL, NULL, 5, 1, 0);
+ rc = colorize(I, mI, NULL, NULL, 5, 1, 0, feat_names);
if (rc < 0) {
printerror("No memory! Use smaller image or add more memory.");
goto error;
}
- /* if we have a change, we apply brightness+contrast from ntscIm */
- if (change_bc) {
- ptr = darrayGetPr(ntscIm);
- ptr2 = darrayGetPr(ntscIm);
- for (i = 0; i < img_height; i++) {
- for (j = 0; j < img_width; j++) {
- /* apply contrast */
- ptr2[width * i + j] = (ptr2[width * i + j] - 0.5) * ptr[width * height * 4 + width * i + j] * 10.0 + 0.5;
- /* apply brightness */
- ptr2[width * i + j] += ptr[width * height * 3 + width * i + j] * 10.0;
- if (ptr2[width * i + j] < 0)
- ptr2[width * i + j] = 0;
- if (ptr2[width * i + j] > 1)
- ptr2[width * i + j] = 1;
- }
- }
- }
+ postpare_arrays(width, height, change_alpha, change_bc, ptr_y, ptr_u, ptr_v, ptr_a, ptr_r, ptr_b, ptr_c, ptr_m, NO_TEST);
if (img_scale_y == img_scale_x*2)
zoom_field = 2;
else
zoom_field = 1;
- /* apply YUV to pixbuffer and display */
- pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, img_width, img_height * zoom_field);
- ptr = darrayGetPr(ntscIm);
- yuv2rgb(ptr, ptr, width, height);
+ /* convert YUV to RGB */
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height * zoom_field);
+ yuv2rgb(ptr_y, ptr_y, width, height);
+
+ /* private structure */
+ cp = calloc(sizeof(struct colorize_priv), 1);
+ cp->width = width*zoom_field;
+ cp->height = height*zoom_field;
+ cp->alpha = change_alpha;
+
+ /* apply image to be saved later */
+ cp->img = malloc(width*height*(3+change_alpha)*sizeof(unsigned short));
+ array2img_short(ptr_y, width, height, cp->img, width, height, change_alpha);
+
+ /* create image */
+ if (change_alpha) {
+ /* simulate alpha by pattern */
+ double pat, a;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ pat = (((j>>3)&1) == ((i>>3)&1)) ? 0.5 : 0.75;
+ a = ptr_a[i*width+j];
+ /* yuv is actually RGB */
+ ptr_y[i*width+j] = a * ptr_y[i*width+j] + (1.0 - a) * pat;
+ ptr_u[i*width+j] = a * ptr_u[i*width+j] + (1.0 - a) * pat;
+ ptr_v[i*width+j] = a * ptr_v[i*width+j] + (1.0 - a) * pat;
+ }
+ }
+ }
data = gdk_pixbuf_get_pixels(pixbuf);
rs = gdk_pixbuf_get_rowstride(pixbuf);
- for (i = 0; i < img_height*zoom_field; i++) {
- for (j = 0; j < img_width; j++) {
- c = ptr[(i/zoom_field)*width+j] * 255.0F;
+ for (i = 0; i < height*zoom_field; i++) {
+ for (j = 0; j < width; j++) {
+ /* yuv is actually RGB */
+ c = ptr_y[(i/zoom_field)*width+j] * 255.0F;
if (c < 0)
c = 0;
else if (c > 255)
c = 255;
data[i*rs + 3*j + 0] = c;
- c = ptr[(i/zoom_field)*width+j + width*height] * 255.0F;
+ c = ptr_u[(i/zoom_field)*width+j] * 255.0F;
if (c < 0)
c = 0;
else if (c > 255)
c = 255;
data[i*rs + 3*j + 1] = c;
- c = ptr[(i/zoom_field)*width+j + width*height*2] * 255.0F;
+ c = ptr_v[(i/zoom_field)*width+j] * 255.0F;
if (c < 0)
c = 0;
else if (c > 255)
}
}
- /* create image */
image = gtk_image_new_from_pixbuf(pixbuf);
gtk_widget_show(image);
- darrayDestroy(markIm);
- markIm = NULL;
- darrayDestroy(ntscIm);
- ntscIm = NULL;
+ darrayDestroy(mI);
+ mI = NULL;
+ darrayDestroy(I);
+ I = NULL;
darrayDone();
- /* private structure */
- cp = calloc(sizeof(struct colorize_priv), 1);
-
/* create window */
colorize_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(colorize_window), "Colorized");
cp->window = colorize_window;
cp->pixbuf = pixbuf;
- cp->width = img_width*zoom_field;
- cp->height = img_height*zoom_field;
p = frame_list[timeline_selected].filename;
while((q = strchr(p, DIR_SEPERATOR)))
p = q + 1;
error:
darrayDestroy(gI);
darrayDestroy(cI);
- darrayDestroy(markIm);
- darrayDestroy(ntscIm);
+ darrayDestroy(mI);
+ darrayDestroy(I);
darrayDone();
}
#include <unistd.h>
#include <math.h>
#include "main.h"
-#include "../src/ppm.h"
+#include "../src/img.h"
#include "../src/mark.h"
#include "../src/yuv.h"
#include "image.h"
/* load image and create pixbuf */
void create_image(const char *filename, int resize)
{
- int rc;
static char imgfile[256];
destroy_image();
strcat(imgfile, p);
} else
strcpy(imgfile, filename);
- rc = load_img(-1, &img_grey_buffer, &img_width, &img_height, imgfile, 0);
- if (rc) {
+ img_grey_buffer = load_img(&img_width, &img_height, imgfile, 0);
+ if (!img_grey_buffer) {
img_grey_buffer = NULL;
if (!rendered)
printerror("Failed to load grey image '%s'", imgfile);
GdkDrawable *draw = gtk_widget_get_window(img_drawing_area);
int window_width, window_height, x_offset, y_offset;
gdk_drawable_get_size (draw, &window_width, &window_height);
- double _r, _g, _b, _y, _u, _v, u_palette, v_palette;
+ double _r, _g, _b, _y, _u, _v, u_palette, v_palette, pat, alpha;
int cr, cg, cb;
int _c, preview_asis = 0;
cr = mark_palette[c-1].r;
cg = mark_palette[c-1].g;
cb = mark_palette[c-1].b;
- if (cr == 255 && cg == 255 && cb == 255) {
- compose[j*3] = compose[j*3+1] = compose[j*3+2] = ((((i+y)>>3)&1) == (((j+x)>>3)&1)) ? 255 : 192;
- } else
- {
- compose[j*3] = cr;
- compose[j*3+1] = cg;
- compose[j*3+2] = cb;
+ alpha = mark_palette[c-1].alpha;
+ if (alpha < 1) {
+ pat = ((((i+y)>>3)&1) == (((j+x)>>3)&1)) ? 192.0 : 128.0;
+ _r = (double)cr * alpha + pat * (1-alpha);
+ _g = (double)cg * alpha + pat * (1-alpha);
+ _b = (double)cb * alpha + pat * (1-alpha);
+ cr = _r;
+ cg = _g;
+ cb = _b;
}
+ compose[j*3] = cr;
+ compose[j*3+1] = cg;
+ compose[j*3+2] = cb;
}
}
}
#define COLOR_WIDTH 100
#define COLOR_HEIGHT 20
-char *bc_pic[] = {
+static char *bc_pic[] = {
" * ",
" * * * ",
" * * ",
" * * * ",
" * ",
};
+
+static char *alpha_pic[] = {
+ " *** *",
+ " * * *",
+ " * * * ",
+ " * * * ",
+ "* * ",
+ "* * ",
+ "* * ",
+ " * ** ",
+ " * ** ",
+ " * * * ",
+ " *** *",
+};
static GdkPixbuf *draw_pixpuf(int i)
{
GdkPixbuf *pixbuf;
guchar *data;
- int j, k, rs;
+ int j, jj, k, kk, rs;
int cr, cg, cb;
- float bright, contrast;
- double r, g, b, y, u, v;
+ float bright, contrast, alpha;
+ double r, g, b, y, u, v, pat;
cr = mark_palette[i].r;
cg = mark_palette[i].g;
cb = mark_palette[i].b;
bright = mark_palette[i].bright;
contrast = mark_palette[i].contrast;
+ alpha = mark_palette[i].alpha;
r = cr / 255.0;
g = cg / 255.0;
b = cb / 255.0;
if (y > 1)
y = 1;
yuv2rgb_pixle(y, u, v, &r, &g, &b);
+ pat = ((k>>3)&1) ? 0.5 : 0.75;
+ r = r * alpha + pat * (1-alpha);
+ g = g * alpha + pat * (1-alpha);
+ b = b * alpha + pat * (1-alpha);
cr = r * 255.0F;
if (cr < 0)
cr = 0;
}
}
+ /* indicate a change in alpha */
+ if (alpha < 1) {
+ for (k = 0, kk = COLOR_HEIGHT - 11; k < 11; k++, kk++) {
+ for (j = 0, jj = COLOR_HEIGHT - 11; j < 11; j++, jj++) {
+ if (alpha_pic[j][k] == '*') {
+ data[jj * rs + kk * 3 + 0] = 255;
+ data[jj * rs + kk * 3 + 1] = 0;
+ data[jj * rs + kk * 3 + 2] = 0;
+ }
+ }
+ }
+ }
+
/* indicate a change in brightness + contrast */
if (bright != 0 || contrast != 1) {
for (k = 0; k < 11; k++) {
mark_palette[i].b = 0;
mark_palette[i].bright = 0;
mark_palette[i].contrast = 1;
+ mark_palette[i].alpha = 1;
}
strcpy(mark_palette[0].name, "red");
return rc;
}
-int colorize_solve(struct colorize *col, int quick)
+int colorize_solve(struct colorize *col, int quick, char **feat_names)
{
int z, d, c, ww, hh, kk;
int rc = -1;
int pixles, j;
double *value_ptr, *init_ptr, *mark_ptr;
- printf(" #%d", c); fflush(stdout);
+ printf(" #%d(%s)", c, feat_names[c-1]); fflush(stdout);
/* apply component
* - copy component into value array (level 0), otherwise 0
* - use maked colors for init array, otherwise use 0
darrayDestroy(col->init);
}
-int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int scalexyz)
+int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int scalexyz, char **feat_names)
{
struct colorize col;
int rc = -1;
if (rc < 0)
goto error;
- rc = colorize_solve(&col, 0);
+ rc = colorize_solve(&col, 0, feat_names);
if (rc < 0)
goto error;
};
int colorize_prepare(struct colorize *col);
-int colorize_solve(struct colorize *col, int quick);
+int colorize_solve(struct colorize *col, int quick, char **feat_names);
void colorize_free(struct colorize *col);
-int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int scalexyz);
+int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int scalexyz, char **feat_names);
#endif
#ifdef DEBUG_ARRAY
printf("darray: No memory to allocate (used %lu Mbytes)\n", arraysize/1024/1024);
sleep(2);
+#else
+ printf("%s: failed to allocate memory\n", __func__);
#endif
return NULL;
}
colorize_SOURCES = \
colorize.c \
- ppm.c \
+ process.c \
+ img.c \
yuv.c \
mark.c
if ENABLE_OPENCV
#include <time.h>
#include "../lib/darray.h"
#include "../lib/colorize.h"
-#include "ppm.h"
+#include "img.h"
#include "yuv.h"
#include "mark.h"
+#include "process.h"
#include "dir_seperator.h"
#ifdef WITH_OPENCV
#include "opticalflow.h"
#endif
-#define min(x,y) ((x < y) ? x : y)
-
static void print_help(const char *app);
static void print_test_help();
}
/*
- * scaling
- */
-
-/* scale down image in img_buffer by calculating average */
-static void scale_img(unsigned short *img_buffer, int width, int height, int scale)
-{
- int w, h, i, j, x, y;
- int r, g, b;
-
- if (scale == 1)
- return;
-
- w = width / scale;
- h = height / scale;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- r = g = b = 0;
- for (y = 0; y < scale; y++) {
- for (x = 0; x < scale; x++) {
- r += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 0];
- g += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 1];
- b += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 2];
- }
- }
- img_buffer[(i * w + j)*3 + 0] = r / scale / scale;
- img_buffer[(i * w + j)*3 + 1] = g / scale / scale;
- img_buffer[(i * w + j)*3 + 2] = b / scale / scale;
- }
- }
-}
-
-/* scale down mark map in mark_buffer */
-static void scale_mark(unsigned char *mark_buffer, int width, int height, int scale)
-{
- int w, h, i, j, x, y;
- unsigned char c, temp;
-
- if (scale == 1)
- return;
-
- w = width / scale;
- h = height / scale;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- c = 0;
- /* always use one index other than 0, if there is any in an areaa to be shrinked */
- for (y = 0; y < scale; y++) {
- for (x = 0; x < scale; x++) {
- temp = mark_buffer[(i*scale+y) * width + j*scale+x];
- if (temp)
- c = temp;
- }
- }
- mark_buffer[i * w + j] = c;
- }
- }
-}
-
-/*
* options
*/
-static int in_itr_num = 5, out_itr_num = 1, optical_flow = 1, bright_contrast = 1;
+static int in_itr_num = 5, out_itr_num = 1, optical_flow = 1, bright_contrast = 1, alpha_change = 1;
int scale = 1, scalexyz = 999;
-static enum test {
- NO_TEST = 0,
- FLOW_NEXT,
- FLOW_PREV,
- MARKED,
- MASK,
- MASK_COLOR,
- BC_ONLY,
- BC_IMAGE,
-} test = NO_TEST;
+static enum test test = NO_TEST;
static int parse_test(const char *arg)
{
return BC_ONLY;
if (!strcmp(arg, "bc-image"))
return BC_IMAGE;
+ if (!strcmp(arg, "alpha"))
+ return ALPHA;
+ if (!strcmp(arg, "no-alpha"))
+ return NO_ALPHA;
+ if (!strcmp(arg, "removal-image"))
+ return REMOVAL_IMAGE;
return NO_TEST;
}
bright_contrast = atoi(optarg);
skip_args += 2;
break;
+ case 'a':
+ alpha_change = atoi(optarg);
+ skip_args += 2;
+ break;
case 'f':
optical_flow = atoi(optarg);
skip_args += 2;
#include "../version.h"
);
printf("Usage: %s [options] <grey ppm image> <marked ppm image> <result ppm image> [<frames> <start>]\n", app);
- printf(" Colorize grey image using maked image and save to result image.\n");
+ printf(" Colorize grey image using marked image and save to result image.\n");
printf(" If frames and start frame is given, image names must include printf integer formatting (e.g. %%04d).\n");
printf("Usage: %s [options] <grey ppm image> marked <result ppm image>\n", app);
printf(" Colorize grey image using marked mask + palette and save to result image.\n");
else
printf("(default=infinite)\n");
printf(" -b --brightness-contrast [0 | 1] Apply brightnes and contrast, if defined in palette by GUI (default=%d)\n", bright_contrast);
+ printf(" -a --alpha-change [0 | 1] Apply alpha channel change, if defined in palette by GUI (default=%d)\n", alpha_change);
#ifdef WITH_OPENCV
printf(" -f --optical-flow [0 | 1] Apply optical flow, if defined by GUI (default=%d)\n", optical_flow);
#endif
printf(" flow-next Optical flow plane to next image\n");
printf(" flow-prev Optical flow plane to previous image\n");
#endif
- printf(" marked Only apply makred colors to grey image\n");
+ printf(" marked Only apply marked colors to grey image\n");
printf(" mask Show mask of marked areas\n");
printf(" mask+color Show mask of marked areas + color\n");
printf(" bc-only Only apply brightness+contrast, leave colors of grey image as is\n");
printf(" bc-image Show brightness+contrast change on grey image as uv components\n");
+ printf(" alpha Show the image with alpha channel only\n");
+ printf(" no-alpha Show the image without alpha channel, to see pixles that are made transparent\n");
+ printf(" removal-image Show the image with \"transparency removal layer\" only, but keep u and v\n");
}
/*
int main(int argc, char *argv[])
{
- darray_t *gI = NULL, *cI = NULL, *markIm = NULL, *ntscIm = NULL;
+ darray_t *gI = NULL, *cI = NULL, *mI = NULL, *I = NULL;
darray_t *flow = NULL, *flow_i = NULL;
- double *ptr, *ptr2, *ptr3;
+ double *ptr_gI = NULL, *ptr_cI = NULL, *ptr_y = NULL, *ptr_u = NULL, *ptr_v = NULL, *ptr_a = NULL, *ptr_r = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_m = NULL;
double diff, sum;
int dims[4];
int w = 0, h = 0, load_w, load_h, k = 1, index = 0, z;
- unsigned short *img_buffer, *img_buffer_all = NULL;
+ unsigned short *img = NULL;
unsigned char *mark_buffer = NULL;
int rc, x, y, i, ii;
time_t start, end;
const char* filename;
char first_filename[256];
int seq_offset = 0, seq_next = 0;
- int features, change_bc;
+ int features, change_bc, change_alpha;
+ char *feat_names[20];
int skip_args;
skip_args = handle_options(argc, argv);
time(&start);
- change_bc = 0;
+ change_bc = change_alpha = 0;
for (z = 0; z < k; z++) {
if (sequence) {
filename = sequence[z].filename;
}
#ifdef WITH_OPENCV
// load flow settings
- if (sequence || !strcmp(argv[2], "marked")) {
+ if (sequence && optical_flow) {
flow_default();
- if (optical_flow)
- load_flow(first_filename);
+ load_flow(first_filename);
if (flow_enable == 0 && (test == FLOW_NEXT || test == FLOW_PREV)) {
fprintf(stderr, "Cannot test optical flow, because it is not enabled by GUI.\n");
exit (0);
}
#endif
// load original image and convert their RGB components to double RGB array
- rc = load_img(-1, &img_buffer, &load_w, &load_h, filename, index + z);
- if (rc) {
+ img = load_img(&load_w, &load_h, filename, index + z);
+ if (!img) {
fprintf(stderr, "Failed to load grey image '%s'\n", filename);
return 0;
}
- scale_img(img_buffer, load_w, load_h, scale);
+ scale_img(img, load_w, load_h, scale);
if (z == 0) {
w = load_w / scale;
h = load_h / scale;
printf("failed to create marked image array\n");
exit (0);
}
- ptr = darrayGetPr(gI) + w*h*3*z;
- img2array(img_buffer, w, h, ptr, w, h);
-#ifdef WITH_OPENCV
- if (k > 1 && flow_enable) {
- if (!img_buffer_all)
- img_buffer_all = malloc(w*h*3*k*sizeof(unsigned short));
- if (!img_buffer_all) {
- printf("failed to create grey image array\n");
- exit (0);
- }
- memcpy(img_buffer_all + w*h*3*z, img_buffer, w*h*3*sizeof(unsigned short));
- }
-#endif
- free(img_buffer);
+ img2array_short(img, w, h, darrayGetPr(gI) + w*h*3*z, w, h);
+ free(img);
if (sequence || !strcmp(argv[2], "marked")) {
char name[256];
/* always load full unscaled image, then scale down */
if (load_marked(mark_buffer + w*h*z, load_w, load_h, name) == 0) {
scale_mark(mark_buffer + w*h*z, load_w, load_h, scale);
- ptr = darrayGetPr(cI) + w*h*3*z;
+ ptr_cI = darrayGetPr(cI) + w*h*3*z;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
/* do not apply mask on index 0 */
/* check for any brightness/contrast change */
if (bright_contrast && (mark_palette[c-1].bright != 0 || mark_palette[c-1].contrast != 1))
change_bc = 1;
+ /* check for any alpha change */
+ if (alpha_change && mark_palette[c-1].alpha < 1)
+ change_alpha = 1;
/* do not apply white pixles, this meas: keep original color */
if (mark_palette[c-1].r == 255 && mark_palette[c-1].g == 255 && mark_palette[c-1].b == 255)
continue;
- ptr[y*w+x] = mark_palette[c-1].r / 255.0F;
- ptr[y*w+x + w*h] = mark_palette[c-1].g / 255.0F;
- ptr[y*w+x + w*h*2] = mark_palette[c-1].b / 255.0F;
+ ptr_cI[y*w+x] = mark_palette[c-1].r / 255.0F;
+ ptr_cI[y*w+x + w*h] = mark_palette[c-1].g / 255.0F;
+ ptr_cI[y*w+x + w*h*2] = mark_palette[c-1].b / 255.0F;
}
}
} else
memset(mark_buffer + w*h*z, 0, w*h);
} else {
// load marked image and convert their RGB components to double YUV array
- rc = load_img(-1, &img_buffer, &load_w, &load_h, argv[2], index + z);
- if (!rc) {
+ img = load_img(&load_w, &load_h, argv[2], index + z);
+ if (!img) {
+ scale_img(img, load_w, load_h, scale);
if (load_w/scale != w || load_h/scale != h) {
fprintf(stderr, "Error: All input images must have equal dimenstions.\n");
return 0;
}
- ptr = darrayGetPr(cI) + w*h*3*z;
- img2array(img_buffer, w, h, ptr, w, h);
- free(img_buffer);
+ img2array_short(img, w, h, darrayGetPr(cI) + w*h*3*z, w, h);
+ free(img);
} else {
fprintf(stderr, "Failed to load marked image, omitting...\n");
memcpy(darrayGetPr(cI) + w*h*3*z, darrayGetPr(gI) + w*h*3*z, w*h*3 * sizeof(double));
}
}
- /* create color mask and ntsc arrays for the colorization process */
- dims[0] = w; dims[1] = h; dims[2] = k;
- markIm = darrayCreate(3, dims);
- if (!markIm) {
- printf("failed to create mark array\n");
- exit (0);
- }
- features = (change_bc) ? 4 : 2;
- dims[0] = w; dims[1] = h; dims[2] = features+1; dims[3] = k;
- ntscIm = darrayCreate(4, dims);
- if (!ntscIm) {
- printf("failed to create ntsc array\n");
- exit (0);
- }
+ rc = alloc_I_arrays(&I, &mI, w, h, k, &features, feat_names, change_alpha, change_bc);
+ if (rc)
+ exit(0);
for (z = 0; z < k; z++) {
+ set_I_ptr(I, mI, w, h, z, features, change_alpha, change_bc, &ptr_y, &ptr_u, &ptr_v, &ptr_a, &ptr_r, &ptr_b, &ptr_c, &ptr_m);
+ ptr_gI = darrayGetPr(gI) + w*h*3*z;
+ ptr_cI = darrayGetPr(cI) + w*h*3*z;
+
+ // convert original image into YUV
+ rgb2yuv(ptr_gI, ptr_gI, w, h);
+ // convert maked image into YUV
+ rgb2yuv(ptr_cI, ptr_cI, w, h);
+
if (sequence || !strcmp(argv[2], "marked")) {
unsigned char c;
- ptr = darrayGetPr(markIm) + w*h*z;
// use marked mask to fill markIm
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
- if (x < w && y < h) {
- /* do not apply mask on index 0 */
- c = mark_buffer[y*w+x + w*h*z];
- } else
- c = 0;
+ /* do not apply mask on index 0 */
+ c = mark_buffer[y*w+x + w*h*z];
if (c)
- ptr[y*w+x] = 1.0F;
+ ptr_m[y*w+x] = 1.0F;
else
- ptr[y*w+x] = 0.0F;
+ ptr_m[y*w+x] = 0.0F;
}
}
} else {
// - convert into absolute (positive values)
// - sum all components to get grey image
// - apply threshold (pixle is 1F, if the absolute difference is > 0.01F)
- // original code: markIm=(sum(abs(gI-cI),3)>0.01);
- ptr = darrayGetPr(gI) + w*h*3*z;
- ptr2 = darrayGetPr(cI) + w*h*3*z;
- ptr3 = darrayGetPr(markIm) + w*h*z;
+ // original code: markIm=(sum(abs(gI-cI),3)>0.01); (according to developers of the algorithm)
for (i = 0, ii = w * h; i < ii; i++) {
diff = 0;
- sum = ptr[i] - ptr2[i];
+ sum = ptr_gI[i] - ptr_cI[i];
if (sum < 0)
diff -= sum;
else
diff += sum;
- sum = ptr[i + ii] - ptr2[i + ii];
+ sum = ptr_gI[i + ii] - ptr_cI[i + ii];
if (sum < 0)
diff -= sum;
else
diff += sum;
- sum = ptr[i + ii + ii] - ptr2[i + ii + ii];
+ sum = ptr_gI[i + ii + ii] - ptr_cI[i + ii + ii];
if (sum < 0)
diff -= sum;
else
diff += sum;
if (diff > 0.01)
- ptr3[i] = 1.0F;
+ ptr_m[i] = 1.0;
else
- ptr3[i] = 0.0F;
- }
- }
-
- // convert original image into YUV
- ptr = darrayGetPr(gI) + w*h*3*z;
- rgb2yuv(ptr, ptr, w, h);
-
- // convert maked image into YUV
- ptr = darrayGetPr(cI) + w*h*3*z;
- rgb2yuv(ptr, ptr, w, h);
-
- if (test != BC_ONLY) {
- if (sequence || !strcmp(argv[2], "marked")) {
- unsigned char c;
- // generate NTSC image: use luminance from original image and chrominance from original or marked image
- ptr = darrayGetPr(gI) + w*h*3*z;
- ptr2 = darrayGetPr(cI) + w*h*3*z;
- ptr3 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- /* use original y component */
- memcpy(ptr3, ptr, w * h * sizeof(double));
- /* apply new uv components */
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- c = mark_buffer[y*w+x + w*h*z];
- if (c == 0) {
- ptr3[w * h + w * y + x] = ptr[w * h + w * y + x];
- ptr3[w * h * 2 + w * y + x] = ptr[w * h * 2 + w * y + x];
- } else {
- ptr3[w * h + w * y + x] = ptr2[w * h + w * y + x];
- ptr3[w * h * 2 + w * y + x] = ptr2[w * h * 2 + w * y + x];
- }
- }
- }
- } else {
- // generate NTSC image: use luminance from original image and chrominance from maked image
- ptr = darrayGetPr(gI) + w*h*3*z;
- ptr2 = darrayGetPr(cI) + w*h*3*z;
- ptr3 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- memcpy(ptr3, ptr, w * h * sizeof(double));
- memcpy(ptr3 + w * h, ptr2 + w * h, w * h * sizeof(double));
- memcpy(ptr3 + w * h * 2, ptr2 + w * h * 2, w * h * sizeof(double));
+ ptr_m[i] = 0.0;
}
- } else {
- /* use grey image as result if BC_ONLY test is selected */
- ptr = darrayGetPr(gI) + w*h*3*z;
- ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- memcpy(ptr2, ptr, w * h * 3 * sizeof(double));
}
- if (change_bc) {
- unsigned char c;
- ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- /* use original y component */
- memcpy(ptr2, ptr, w * h * sizeof(double));
- /* apply brightness and contrast from makred pixles to uv components of grey image */
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- /* use unchanged brightness and contrast on index 0 */
- c = mark_buffer[y*w+x + w*h*z];
- if (c == 0) {
- ptr2[y*w+x + w*h*3] = 0;
- ptr2[y*w+x + w*h*4] = 0.1;
- } else {
- ptr2[y*w+x + w*h*3] = mark_palette[c-1].bright / 10.0;
- ptr2[y*w+x + w*h*4] = mark_palette[c-1].contrast / 10.0;
- }
- }
- }
- }
+ prepare_arrays(w, h, change_alpha, change_bc, mark_buffer+w*h*z, ptr_gI, ptr_cI, ptr_y, ptr_u, ptr_v, ptr_a, ptr_r, ptr_b, ptr_c, ptr_m, test);
}
#ifdef WITH_OPENCV
printf("Note: Optical flow is not activated!\n");
for (z = 0; z < k-1; z++) {
if (flow)
- create_flow_maps(NULL, img_buffer_all + w*h*3*(z+1), img_buffer_all + w*h*3*z, w, h, flow_window/scale, 0, NULL, NULL, darrayGetPr(flow) + w*h*z, darrayGetPr(flow) + w*h*z + w*h*(k-1), NULL);
+ create_flow_maps(NULL, darrayGetPr(gI) + w*h*3*(z+1), darrayGetPr(gI) + w*h*3*z, w, h, flow_window/scale, 0, NULL, NULL, darrayGetPr(flow) + w*h*z, darrayGetPr(flow) + w*h*z + w*h*(k-1), NULL);
if (flow_i)
- create_flow_maps(img_buffer_all + w*h*3*z, NULL, img_buffer_all + w*h*3*(z+1), w, h, flow_window/scale, 0, darrayGetPr(flow_i) + w*h*z, darrayGetPr(flow_i) + w*h*z + w*h*(k-1), NULL, NULL, NULL);
+ create_flow_maps(darrayGetPr(gI) + w*h*3*z, NULL, darrayGetPr(gI) + w*h*3*(z+1), w, h, flow_window/scale, 0, darrayGetPr(flow_i) + w*h*z, darrayGetPr(flow_i) + w*h*z + w*h*(k-1), NULL, NULL, NULL);
}
#else
if (k > 1)
printf("Note: Optical flow is not compiled in!\n");
#endif
- free(img_buffer_all);
- img_buffer_all = NULL;
darrayDestroy(gI);
gI = NULL;
if (test != FLOW_NEXT && test != FLOW_PREV && test != MARKED && test != MASK && test != MASK_COLOR && test != BC_ONLY && test != BC_IMAGE) {
printf("Colorizing %d frames, please wait...\n", k);
- rc = colorize(ntscIm, markIm, flow, flow_i, in_itr_num, out_itr_num, scalexyz);
+ rc = colorize(I, mI, flow, flow_i, in_itr_num, out_itr_num, scalexyz, feat_names);
if (rc < 0) {
if (k > 1)
printf("No memory! Use smaller frames or less frames between key frames or add more memory.");
}
}
- /* if we have a change, we apply brightness+contrast from ntscIm */
- if (change_bc) {
- for (z = 0; z < k; z++) {
- ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- /* apply contrast */
- ptr2[w * y + x] = (ptr2[w * y + x] - 0.5) * ptr[w * h * 4 + w * y + x] * 10.0 + 0.5;
- /* apply brightness */
- ptr2[w * y + x] += ptr[w * h * 3 + w * y + x] * 10.0;
- if (ptr2[w * y + x] < 0)
- ptr2[w * y + x] = 0;
- if (ptr2[w * y + x] > 1)
- ptr2[w * y + x] = 1;
-#if 0
-#warning TEST: show brightness and contrast change as uv vectors on a grey array */
-ptr2[w * y + x] = 0.5;
-ptr2[w * h + w * y + x] = ptr[w * h + w * y + x] * 10;
-ptr2[w * h * 2 + w * y + x] = ptr[w * h * 2 + w * y + x] * 10 - 1;
-#endif
- }
- }
- }
- }
+ for (z = 0; z < k; z++) {
+ set_I_ptr(I, mI, w, h, z, features, change_alpha, change_bc, &ptr_y, &ptr_u, &ptr_v, &ptr_a, &ptr_r, &ptr_b, &ptr_c, &ptr_m);
+ postpare_arrays(w, h, change_alpha, change_bc, ptr_y, ptr_u, ptr_v, ptr_a, ptr_r, ptr_b, ptr_c, ptr_m, test);
#ifdef WITH_OPENCV
- if (test == FLOW_NEXT || test == FLOW_PREV) {
- /* apply flow planes to result image as u and y vector */
- for (z = 0; z < k; z++) {
- ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
+ if (test == FLOW_NEXT || test == FLOW_PREV) {
+ double *ptr_f1 = NULL, *ptr_f2 = NULL;
+ /* apply flow planes to result image as u and y vector */
if (test == FLOW_NEXT) {
- ptr2 = darrayGetPr(flow) + w*h*z;
- ptr3 = darrayGetPr(flow) + w*h*z*(k-1);
+ if (flow) {
+ ptr_f1 = darrayGetPr(flow) + w*h*z;
+ ptr_f2 = darrayGetPr(flow) + w*h*z*(k-1);
+ }
} else {
- ptr2 = darrayGetPr(flow_i) + w*h*z;
- ptr3 = darrayGetPr(flow_i) + w*h*z*(k-1);
+ if (flow_i) {
+ ptr_f1 = darrayGetPr(flow_i) + w*h*z;
+ ptr_f2 = darrayGetPr(flow_i) + w*h*z*(k-1);
+ }
}
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- ptr[w * y + x] = 0.5;
- if (z < k-1) {
- ptr[w * y + x + w*h] = ptr2[w * y + x] / 50;
- ptr[w * y + x + w*h*2] = ptr3[w * y + x] / 50;
- } else {
- ptr[w * y + x + w*h] = 0;
- ptr[w * y + x + w*h*2] = 0;
+ if (ptr_f1 && ptr_f1) {
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ ptr_y[w*y+x] = 0.5;
+ if (z < k-1) {
+ ptr_u[w*y+x] = ptr_f1[w * y + x] / 50;
+ ptr_v[w*y+x] = ptr_f2[w * y + x] / 50;
+ } else {
+ ptr_u[w*y+x] = 0;
+ ptr_v[w*y+x] = 0;
+ }
}
}
}
}
- }
#endif
- if (test == MASK) {
- /* apply maked mask as image */
- for (z = 0; z < k; z++) {
- ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- ptr2 = darrayGetPr(markIm) + w*h*z;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- ptr[w * y + x] = ptr2[w * y + x];
- ptr[w * y + x + w*h] = ptr2[w * y + x];
- ptr[w * y + x + w*h*2] = ptr2[w * y + x];
- }
- }
- }
- }
-
- if (test == MASK_COLOR) {
- /* apply maked mask on grey image */
- for (z = 0; z < k; z++) {
- ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- ptr2 = darrayGetPr(markIm) + w*h*z;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- /* darken unmarked areas, make maked areas with uniformed brightness */
- if (ptr2[w * y + x] < 0.5F)
- ptr[w * y + x] = ptr[w * y + x] / 4;
- else
- ptr[w * y + x] = 0.5F;
- }
- }
- }
- }
-
- if (test == BC_IMAGE) {
- /* apply bc image as result image */
- for (z = 0; z < k; z++) {
- ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- /* use uniformed brightness as y component */
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- ptr[w * y + x] = 0.5F;
- }
- }
- if (change_bc) {
- ptr2 = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- memcpy(ptr+w*h, ptr2+w*h*3, w * h * sizeof(double));
- memcpy(ptr+w*h*2, ptr2+w*h*4, w * h * sizeof(double));
- } else {
- memset(ptr+w*h, 0, w * h * sizeof(double));
- memset(ptr+w*h*2, 0, w * h * sizeof(double));
- }
- }
- }
-
- // save result YUV array to image with RGB components
- img_buffer = (unsigned short *)malloc(w*h*3*sizeof(unsigned short));
- if (!img_buffer) {
- fprintf(stderr, "Failed to allocate image buffer\n");
- return 0;
- }
- for (z = 0; z < k; z++) {
- ptr = darrayGetPr(ntscIm) + w*h*(features+1)*z;
- yuv2rgb(ptr, ptr, w, h);
- array2img(ptr, w, h, img_buffer, w, h);
+ // save result YUV array to image with RGB components
+ yuv2rgb(ptr_y, ptr_y, w, h);
if (sequence) {
static char name[256], *p, *q;
p = sequence[z].filename;
filename = name;
} else
filename = argv[3];
- save_img(img_buffer, w, h, filename, index + z);
+ /* don't save alpha on these tests */
+ if (test == ALPHA || test == REMOVAL_IMAGE || test == NO_ALPHA)
+ save_img_array(ptr_y, w, h, 0, filename, index + z);
+ else
+ save_img_array(ptr_y, w, h, change_alpha, filename, index + z);
}
- free(img_buffer);
time(&end);
printf("Elapsed time: %d minutes, %d seconds\n", (int)(end-start)/60, (int)(end-start)%60);
// destroy
- darrayDestroy(ntscIm);
- ntscIm = NULL;
+ darrayDestroy(I);
+ I = NULL;
+ darrayDestroy(mI);
+ mI = NULL;
darrayDestroy(flow);
flow = NULL;
darrayDestroy(flow_i);
flow_i = NULL;
- darrayDestroy(markIm);
- markIm = NULL;
free(mark_buffer);
mark_buffer = NULL;
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "img.h"
+
+int save_depth = 16;
+
+#ifdef WITH_MAGICK
+#include <magick/api.h>
+
+/* load given image to memory. return short RGB values */
+unsigned short *load_img(int *width, int *height, const char *filename, int index)
+{
+ Image *image = NULL;
+ ImageInfo *imageinfo = NULL;
+ ExceptionInfo exception;
+ unsigned short *img = NULL;
+
+// MagickCoreGenesis(NULL,MagickFalse);
+ InitializeMagick(NULL);
+ imageinfo = CloneImageInfo(0);
+ GetExceptionInfo(&exception);
+
+ sprintf(imageinfo->filename, filename, index);
+
+ image = ReadImage(imageinfo, &exception);
+ if (!image) {
+// printf("failed to read image '%s' via *magick\n", filename);
+ goto exit;
+ }
+
+ *width = image->columns;
+ *height = image->rows;
+
+ img = (unsigned short *)malloc((*width) * (*height) * 3 * 2);
+ if (!img) {
+ printf("%s:failed to allocate image data\n", __func__);
+ goto exit;
+ }
+
+// ExportImagePixels(image, 0, 0, *width, *height, "RGB", ShortPixel, darrayGetPr(darray), NULL);
+ DispatchImage(image, 0, 0, *width, *height, "RGB", ShortPixel, img, NULL);
+
+exit:
+ if (image)
+ DestroyImage(image);
+
+ if (imageinfo)
+ DestroyImageInfo(imageinfo);
+
+// MagickCoreTerminus();
+ DestroyMagick();
+
+ return img;
+}
+
+/* save given image */
+int save_img(unsigned short *img, int width, int height, int alpha, const char *filename, int index)
+{
+ int rc = -1;
+ Image *image = NULL;
+ ImageInfo *imageinfo = NULL;
+ ExceptionInfo exception;
+
+// MagickCoreGenesis(NULL,MagickFalse);
+ InitializeMagick(NULL);
+ imageinfo = CloneImageInfo(0);
+ GetExceptionInfo(&exception);
+
+ imageinfo->quality = 100;
+
+ image=ConstituteImage(width, height, (alpha)?"RGBA":"RGB", ShortPixel, img, &exception);
+ if (!image) {
+ printf("%s:failed to prepare to write image\n", __func__);
+ goto exit;
+ }
+
+ /* store as 16 bit, if lib and format supports it */
+ image->depth = save_depth;
+
+ sprintf(image->filename, filename, index); /* ACHTUNG: nicht imageinfo!!! */
+ if (!WriteImage(imageinfo, image)) {
+ printf("%s:failed to write image\n", __func__);
+ goto exit;
+ }
+
+ rc = 0;
+
+exit:
+ if (image)
+ DestroyImage(image);
+
+ if (imageinfo)
+ DestroyImageInfo(imageinfo);
+
+// MagickCoreTerminus();
+ DestroyMagick();
+
+ return rc;
+}
+#else
+
+/* load given image to memory. return short RGB values */
+unsigned short *load_img(int *width, int *height, const char *filename, int index)
+{
+ FILE *fp = NULL;
+ unsigned short *img = NULL;
+ char line[256];
+ int words, i;
+
+ sprintf(line, filename, index);
+// printf("reading image: %s\n", line);
+ fp = fopen(line, "r");
+ if (!fp) {
+// printf("failed to read ppm image '%s'\n", filename);
+ goto exit;
+ }
+again1:
+ if (!fgets(line, sizeof(line), fp)) {
+ printf("%s:failed to read image depth\n", __func__);
+ goto exit;
+ }
+ line[sizeof(line)-1] = '\0';
+ if (line[0]) line[strlen(line)-1] = '\0';
+ if (line[0] == '#')
+ goto again1;
+ if (!!strcmp(line, "P6")) {
+ printf("%s:expecting image depth 'P6'\n", __func__);
+ goto exit;
+ }
+again2:
+ if (!fgets(line, sizeof(line), fp)) {
+ printf("%s:failed to read image size\n", __func__);
+ goto exit;
+ }
+ line[sizeof(line)-1] = '\0';
+ if (line[0]) line[strlen(line)-1] = '\0';
+ if (line[0] == '#')
+ goto again2;
+ sscanf(line, "%d %d", width, height);
+// printf("Image size: w=%d h=%d\n", *width, *height);
+again3:
+ if (!fgets(line, sizeof(line), fp)) {
+ printf("%s:failed to read line '255' or '65535'\n", __func__);
+ goto exit;
+ }
+ line[sizeof(line)-1] = '\0';
+ if (line[0]) line[strlen(line)-1] = '\0';
+ if (line[0] == '#')
+ goto again3;
+ if (!strcmp(line, "255")) {
+ words = 1;
+ } else
+ if (!strcmp(line, "65535")) {
+ words = 2;
+ } else {
+ printf("%s:expecting line '255' or '65535'\n", __func__);
+ goto exit;
+ }
+
+ img = (unsigned short *)malloc((*width) * (*height) * 3 * 2);
+ if (!img) {
+ printf("%s:failed to allocate image data\n", __func__);
+ goto exit;
+ }
+ if (fread(img, (*width) * (*height) * 3 * words, 1, fp) != 1) {
+ printf("%s:failed to read image data\n", __func__);
+ goto exit;
+ }
+
+ /* char to short (255 -> 65535) */
+ if (words == 1) {
+ unsigned char *from = (unsigned char *)img, c;
+ for (i = (*width) * (*height) * 3 - 1; i >= 0; i--) {
+ c = from[i];
+ img[i] = (c << 8) | c;
+ }
+ } else {
+ /* correct byte order */
+ unsigned short v;
+ unsigned char *from = (unsigned char *)img;
+ for (i = 0; i < (*width) * (*height) * 3; i++) {
+ v = ((*from++) << 8);
+ v |= (*from++);
+ img[i] = v;
+ }
+ }
+
+exit:
+ if (fp)
+ fclose(fp);
+
+ return img;
+}
+
+/* save given image */
+int save_img(unsigned short *img, int width, int height, int alpha, const char *filename, int index)
+{
+ FILE *fp = NULL;
+ int rc = -1;
+ char line[256];
+ int i;
+ unsigned short v;
+ unsigned char *to;
+
+ if (alpha) {
+ printf("%s:cannot save alpha component with PPM support only\n", __func__);
+ alpha = 0;
+ goto exit;
+ }
+
+ sprintf(line, filename, index);
+// printf("writing image: %s\n", line);
+ fp = fopen(line, "w");
+ if (!fp) {
+ printf("%s:failed to write image\n", __func__);
+ goto exit;
+ }
+ fprintf(fp, "P6\n%d %d\n65535\n", width, height);
+
+ /* correct byte order, write and restore byte order */
+ to = (unsigned char *)img;
+ for (i = 0; i < width * height * 3; i++) {
+ v = img[i];
+ if (i/100*i == i) { printf("%04x ", v); }
+ (*to++) = v >> 8;
+ (*to++) = v;
+ }
+ rc = fwrite(img, width * height * 3 * 2, 1, fp);
+ to = (unsigned char *)img;
+ for (i = 0; i < width * height * 3; i++) {
+ v = (*to++) << 8;
+ v |= (*to++);
+ img[i] = v;
+ }
+ if (rc != 1) {
+ printf("%s:failed to write image data\n", __func__);
+ goto exit;
+ }
+
+ rc = 0;
+
+exit:
+ if (fp)
+ fclose(fp);
+
+ return rc;
+}
+#endif
+
+int save_img_array(double *array, int width, int height, int alpha, const char *filename, int index)
+{
+ int rc = -1;
+ unsigned short *img = NULL;
+ int components;
+
+#ifndef WITH_MAGICK
+ if (alpha) {
+ printf("%s:warning, cannot save alpha component with PPM support only\n", __func__);
+ alpha = 0;
+ }
+#endif
+ components = (alpha) ? 4 : 3;
+
+ img = (unsigned short *)malloc(width * height * components * 2);
+ if (!img) {
+ printf("%s:failed to allocate image data\n", __func__);
+ goto exit;
+ }
+
+ array2img_short(array, width, height, img, width, height, alpha);
+
+ save_img(img, width, height, alpha, filename, index);
+
+ rc = 0;
+
+exit:
+ if (img)
+ free(img);
+
+ return rc;
+}
+
+/* convert an image to a three dimensional array of double
+ * the size is: width, height, 3
+ */
+void img2array_short(unsigned short *img, int iw, int ih, double *array, int aw, int ah)
+{
+ int x, y;
+ int channel;
+ double r, g, b;
+
+ channel = aw * ah;
+
+ for (y = 0; y < ih; y++) {
+ for (x = 0; x < iw; x++) {
+ r = img[(x+iw*y)*3] / 65535.0F;
+ g = img[(x+iw*y)*3+1] / 65535.0F;
+ b = img[(x+iw*y)*3+2] / 65535.0F;
+ array[x+aw*y] = r;
+ array[x+aw*y+channel] = g;
+ array[x+aw*y+channel+channel] = b;
+ }
+ }
+}
+
+/* convert a three dimensional array of double to an image
+ * the size is: width, height, 3
+ */
+void array2img_short(double *array, int aw, int ah, unsigned short *img, int iw, int ih, int alpha)
+{
+ int x, y, c;
+ int channel, components;
+ double r, g, b, a;
+
+ channel = aw * ah;
+ components = (alpha) ? 4 : 3;
+
+ for (y = 0; y < ih; y++) {
+ for (x = 0; x < iw; x++) {
+ r = array[x+aw*y];
+ c = (r * 65535.0F + 0.5F);
+ if (c < 0)
+ c = 0;
+ else if (c > 65535)
+ c = 65535;
+ img[(x+iw*y)*components] = c;
+ g = array[x+aw*y+channel];
+ c = (g * 65535.0F + 0.5F);
+ if (c < 0)
+ c = 0;
+ else if (c > 65535)
+ c = 65535;
+ img[(x+iw*y)*components+1] = c;
+ b = array[x+aw*y+channel+channel];
+ c = (b * 65535.0F + 0.5F);
+ if (c < 0)
+ c = 0;
+ else if (c > 65535)
+ c = 65535;
+ img[(x+iw*y)*components+2] = c;
+ if (alpha) {
+ a = array[x+aw*y+channel+channel+channel];
+ c = (a * 65535.0F + 0.5F);
+ if (c < 0)
+ c = 0;
+ else if (c > 65535)
+ c = 65535;
+ img[(x+iw*y)*components+3] = c;
+ }
+ }
+ }
+}
+
+/*
+ * scale down image in img_buffer by calculating average
+ */
+void scale_img(unsigned short *img, int width, int height, int scale)
+{
+ int w, h, i, j, x, y;
+ int r, g, b;
+
+ if (scale == 1)
+ return;
+
+ w = width / scale;
+ h = height / scale;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ r = g = b = 0;
+ for (y = 0; y < scale; y++) {
+ for (x = 0; x < scale; x++) {
+ r += img[((i*scale+y) * width + j*scale+x) * 3 + 0];
+ g += img[((i*scale+y) * width + j*scale+x) * 3 + 1];
+ b += img[((i*scale+y) * width + j*scale+x) * 3 + 2];
+ }
+ }
+ img[(i * w + j)*3 + 0] = r / scale / scale;
+ img[(i * w + j)*3 + 1] = g / scale / scale;
+ img[(i * w + j)*3 + 2] = b / scale / scale;
+ }
+ }
+}
+
+
--- /dev/null
+extern int save_depth;
+unsigned short *load_img(int *width, int *height, const char *filename, int index);
+int save_img(unsigned short *img, int width, int height, int alpha, const char *filename, int index);
+int save_img_array(double *array, int width, int height, int alpha, const char *filename, int index);
+void img2array_short(unsigned short *img, int iw, int ih, double *array, int aw, int ah);
+void array2img_short(double *array, int aw, int ah, unsigned short *img, int iw, int ih, int alpha);
+void scale_img(unsigned short *img, int width, int height, int scale);
return;
}
for (i = 0; i < 255; i++)
- fprintf(fp, "%03d %03d %03d \"%s\" %f %f\n", mark_palette[i].r, mark_palette[i].g, mark_palette[i].b, mark_palette[i].name, mark_palette[i].bright, mark_palette[i].contrast);
+ fprintf(fp, "%03d %03d %03d \"%s\" %f %f %f\n", mark_palette[i].r, mark_palette[i].g, mark_palette[i].b, mark_palette[i].name, mark_palette[i].bright, mark_palette[i].contrast, mark_palette[i].alpha);
fprintf(fp, "blacklevel %f\n", black_level);
fprintf(fp, "whitelevel %f\n", white_level);
fprintf(fp, "fadelevel %f\n", fade_level);
FILE *fp;
int i;
int r, g, b;
- float bright = 0, contrast = 1;
+ float bright, contrast, alpha;
sprintf(name, "%s_palette", filename);
// printf("loading palette '%s'\n", name);
*q = '\0';
if ((p = strchr(p, '\"'))) {
p++;
- sscanf(p, "%f %f", &bright, &contrast);
+ bright = 0;
+ contrast = 1;
+ alpha = 1;
+ sscanf(p, "%f %f %f", &bright, &contrast, &alpha);
}
mark_palette[i].r = r;
mark_palette[i].g = g;
mark_palette[i].b = b;
mark_palette[i].bright = bright;
mark_palette[i].contrast = contrast;
+ mark_palette[i].alpha = alpha;
}
fclose(fp);
return 0;
return 0;
}
+/* scale down mark map in mark_buffer */
+void scale_mark(unsigned char *mark_buffer, int width, int height, int scale)
+{
+ int w, h, i, j, x, y;
+ unsigned char c, temp;
+
+ if (scale == 1)
+ return;
+
+ w = width / scale;
+ h = height / scale;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ c = 0;
+ /* always use one index other than 0, if there is any in an areaa to be shrinked */
+ for (y = 0; y < scale; y++) {
+ for (x = 0; x < scale; x++) {
+ temp = mark_buffer[(i*scale+y) * width + j*scale+x];
+ if (temp)
+ c = temp;
+ }
+ }
+ mark_buffer[i * w + j] = c;
+ }
+ }
+}
+
unsigned char b;
float bright;
float contrast;
+ float alpha;
char name[64];
};
int load_palette(const char *filename);
int save_marked(unsigned char *img_mark_buffer, int width, int height, const char *filename);
int load_marked(unsigned char *img_mark_buffer, int width, int height, const char *filename);
+void scale_mark(unsigned char *mark_buffer, int width, int height, int scale);
#include <stdio.h>
-#include "ppm.h"
+#include "img.h"
#include "opticalflow.h"
#include "yuv.h"
#include <opencv2/core/core_c.h>
* flow_map_y_next = flow map for delta y of next image (result is stored here)
*
*/
-void *create_flow_maps(const unsigned short *img_prev_buffer, const unsigned short *img_next_buffer, unsigned short *img_buffer, int width, int height, int win_size, int steps, double *flow_map_x_prev, double *flow_map_y_prev, double *flow_map_x_next, double *flow_map_y_next, void *_image_preview)
+void *create_flow_maps(const double *img_prev_buffer, const double *img_next_buffer, const double *img_buffer, int width, int height, int win_size, int steps, double *flow_map_x_prev, double *flow_map_y_prev, double *flow_map_x_next, double *flow_map_y_next, void *_image_preview)
{
IplImage *image_prev = NULL, *image = NULL, *image_next = NULL, *image_preview = _image_preview;
CvMat *flow;
if (image_prev) {
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
- /* copy green channel */
- CV_IMAGE_ELEM(image_prev, uchar, i, j) = img_prev_buffer[(i*width+j)*3 + 1] >> 8;
+ CV_IMAGE_ELEM(image_prev, uchar, i, j) = img_prev_buffer[i*width+j] * 255.0;
}
}
}
if (image) {
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
- /* copy green channel */
- CV_IMAGE_ELEM(image, uchar, i, j) = img_buffer[(i*width+j)*3 + 1] >> 8;
+ CV_IMAGE_ELEM(image, uchar, i, j) = img_buffer[i*width+j] * 255.0;
if (image_preview)
- CV_IMAGE_ELEM(image_preview, uchar, i, j) = (img_buffer[(i*width+j)*3 + 1] / 2) >> 8;
+ CV_IMAGE_ELEM(image_preview, uchar, i, j) = (img_buffer[i*width+j] / 2) * 255.0;
}
}
}
if (image_next) {
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
- /* copy green channel */
- CV_IMAGE_ELEM(image_next, uchar, i, j) = img_next_buffer[(i*width+j)*3 + 1] >> 8;
+ CV_IMAGE_ELEM(image_next, uchar, i, j) = img_next_buffer[i*width+j] * 255.0;
}
}
}
}
}
+#if 0
+#include<opencv/highgui.h>
+cvNamedWindow( "Display window", 0 );// Create a window for display.
+cvShowImage( "Display window", image ); // Show our image inside it.
+#endif
+
if (image)
cvReleaseImage(&image);
if (image_prev)
* uv_scale = apply vector (pointing to next plane) by applying uv-color (0 to disable)
*
*/
-void create_flow_view(const char *filename_prev, const char *filename_next, unsigned short *img_buffer, int width, int height, int win_size, int steps, int uv_scale)
+void create_flow_view(const char *filename_prev, const char *filename_next, unsigned short *_img_buffer, int width, int height, int win_size, int steps, int uv_scale)
{
- unsigned short *img_prev_buffer = NULL, *img_next_buffer = NULL;
+ double *img_prev_buffer = NULL, *img_next_buffer = NULL, *img_buffer;
double *flow_map_x_prev = NULL, *flow_map_y_prev = NULL, *flow_map_x_next = NULL, *flow_map_y_next = NULL;
IplImage *image_preview = NULL;
CvSize size;
unsigned char c;
double r, g, b;
- int w, h, rc;
+ int w, h;
int i, j;
+ unsigned short *img;
#if 0
cvInitMatHeader(&kernel, 3, 3, CV_64FC1, vals, 0);
#endif
//printf("%s %s\n", filename_prev, filename_next);
+
+ /* convert current image to double */
+ img_buffer = (double *)malloc(width*height*3*sizeof(double));
+ if (!img_buffer) {
+ printf("%s:failed to allocate memory\n", __func__);
+ return;
+ }
+ img2array_short(_img_buffer, width, height, img_buffer, width, height);
+ rgb2yuv(img_buffer, img_buffer, width, height);
+
/* read previous image */
if (filename_prev) {
- rc = load_img(-1, &img_prev_buffer, &w, &h, filename_prev, 0);
- if (rc == 0) {
- if (w != width || h != height) {
- rc = -1;
- free(img_prev_buffer);
- img_prev_buffer = NULL;
+ img = load_img(&w, &h, filename_prev, 0);
+ if (img) {
+ if (w == width && h == height) {
+ img_prev_buffer = (double *)malloc(w*h*3*sizeof(double));
+ if (img_prev_buffer) {
+ img2array_short(img, w, h, img_prev_buffer, w, h);
+ rgb2yuv(img_prev_buffer, img_prev_buffer, width, height);
+ }
}
+ free(img);
}
}
/* read next image */
if (filename_next) {
- rc = load_img(-1, &img_next_buffer, &w, &h, filename_next, 0);
- if (rc == 0) {
- if (w != width || h != height) {
- rc = -1;
- free(img_next_buffer);
- img_next_buffer = NULL;
+ img = load_img(&w, &h, filename_next, 0);
+ if (img) {
+ if (w == width && h == height) {
+ img_next_buffer = (double *)malloc(w*h*3*sizeof(double));
+ if (img_next_buffer) {
+ img2array_short(img, w, h, img_next_buffer, w, h);
+ rgb2yuv(img_next_buffer, img_next_buffer, width, height);
+ }
}
+ free(img);
}
}
/* apply images to opencv image */
size.width = width;
size.height = height;
- if (img_buffer) {
- image_preview = cvCreateImage(size, IPL_DEPTH_8U, 1);
- }
+ image_preview = cvCreateImage(size, IPL_DEPTH_8U, 1);
flow_map_x_prev = (double *)malloc(sizeof(double)*width*height);
flow_map_y_prev = (double *)malloc(sizeof(double)*width*height);
flow_map_x_next = (double *)malloc(sizeof(double)*width*height);
flow_map_y_next = (double *)malloc(sizeof(double)*width*height);
- if (image_preview)
+ if (image_preview) {
image_preview = create_flow_maps(img_prev_buffer, img_next_buffer, img_buffer, width, height, win_size, steps, flow_map_x_prev, flow_map_y_prev, flow_map_x_next, flow_map_y_next, image_preview);
- if (img_buffer && image_preview) {
/* paint vectors from image_preview to img_buffer */
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
flow_map_y_next[width * i + j] / uv_scale,
&r, &g, &b);
} else {
- r = (double)c / 255.0;
- g = (double)c / 255.0;
- b = (double)c / 255.0;
+ r = ((double)c) / 255.0;
+ g = ((double)c) / 255.0;
+ b = ((double)c) / 255.0;
}
}
- img_buffer[(i*width+j)*3 + 0] = r * 65535.0;
- img_buffer[(i*width+j)*3 + 1] = g * 65535.0;
- img_buffer[(i*width+j)*3 + 2] = b * 65535.0;
+ _img_buffer[(i*width+j)*3 + 0] = r * 65535.0;
+ _img_buffer[(i*width+j)*3 + 1] = g * 65535.0;
+ _img_buffer[(i*width+j)*3 + 2] = b * 65535.0;
}
}
}
/* free stuff */
+ if (img_buffer)
+ free(img_buffer);
if (img_prev_buffer)
free(img_prev_buffer);
if (img_next_buffer)
void save_flow(const char *filename);
int load_flow(const char *filename);
-void *create_flow_maps(const unsigned short *img_prev_buffer, const unsigned short *img_next_buffer, unsigned short *img_buffer, int width, int height, int win_size, int steps, double *flow_map_x_prev, double *flow_map_y_prev, double *flow_map_x_next, double *flow_map_y_next, void *_image_preview);
+void *create_flow_maps(const double *img_prev_buffer, const double *img_next_buffer, const double *img_buffer, int width, int height, int win_size, int steps, double *flow_map_x_prev, double *flow_map_y_prev, double *flow_map_x_next, double *flow_map_y_next, void *_image_preview);
void create_flow_view(const char *filename_prev, const char *filename_next, unsigned short *img_buffer, int width, int height, int win_size, int steps, int uv_scale);
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "ppm.h"
-
-#ifdef WITH_MAGICK
-#include <magick/api.h>
-
-int save_depth = 16;
-
-/* load given image to memory. return memory pointer, witdth and height
- * if offset is given, no memory is allocated */
-int load_img(int offset, unsigned short **buffer, int *width, int *height,
- const char *filename, int index)
-{
- int rc = -1;
- Image *image = NULL;
- ImageInfo *imageinfo = NULL;
- ExceptionInfo exception;
-
-// MagickCoreGenesis(NULL,MagickFalse);
- InitializeMagick(NULL);
- imageinfo = CloneImageInfo(0);
- GetExceptionInfo(&exception);
-
- sprintf(imageinfo->filename, filename, index);
-
- image = ReadImage(imageinfo, &exception);
- if (!image) {
-// printf("failed to read image '%s' via *magick\n", filename);
- goto exit;
- }
- *width = image->columns;
- *height = image->rows;
-
- if (offset < 0) {
- *buffer = (unsigned short *)malloc((*width) * (*height) * 3 * sizeof(unsigned short));
- if (!*buffer) {
- printf("failed to allocate image data\n");
- goto exit;
- }
- offset = 0;
- }
-// ExportImagePixels(image, 0, 0, *width, *height, "RGB", CharPixel, *buffer, NULL);
- DispatchImage(image, 0, 0, *width, *height, "RGB", ShortPixel, *buffer, NULL);
-
- rc = 0;
-
-exit:
- if (image)
- DestroyImage(image);
-
- if (imageinfo)
- DestroyImageInfo(imageinfo);
-
-// MagickCoreTerminus();
- DestroyMagick();
-
- return rc;
-}
-
-/* save given image */
-int save_img(unsigned short *buffer, int width, int height, const char *filename,
- int index)
-{
- int rc = -1;
- Image *image = NULL;
- ImageInfo *imageinfo = NULL;
- ExceptionInfo exception;
-
-// MagickCoreGenesis(NULL,MagickFalse);
- InitializeMagick(NULL);
- imageinfo = CloneImageInfo(0);
- GetExceptionInfo(&exception);
-
- imageinfo->quality = 100;
-
- image=ConstituteImage(width, height, "RGB", ShortPixel, buffer, &exception);
- if (!image) {
- printf("failed to prepare to write image\n");
- goto exit;
- }
-
- /* store as 16 bit, if lib and format supports it */
- image->depth = save_depth;
-
- sprintf(image->filename, filename, index); /* ACHTUNG: nicht imageinfo!!! */
- if (!WriteImage(imageinfo, image)) {
- printf("failed to write image\n");
- goto exit;
- }
-
- rc = 0;
-
-exit:
- if (image)
- DestroyImage(image);
-
- if (imageinfo)
- DestroyImageInfo(imageinfo);
-
-// MagickCoreTerminus();
- DestroyMagick();
-
- return rc;
-}
-#else
-
-/* load given PPM image to memory. return memory pointer, witdth and height
- * if offset is given, no memory is allocated */
-int load_img(int offset, unsigned short **buffer, int *width, int *height,
- const char *filename, int index)
-{
- FILE *fp;
- char line[256];
- int words, i;
-
- sprintf(line, filename, index);
-// printf("reading image: %s\n", line);
- fp = fopen(line, "r");
- if (!fp) {
-// printf("failed to read ppm image '%s'\n", filename);
- return -1;
- }
-again1:
- if (!fgets(line, sizeof(line), fp)) {
- printf("failed to read image depth\n");
- fclose(fp);
- return -1;
- }
- line[sizeof(line)-1] = '\0';
- if (line[0]) line[strlen(line)-1] = '\0';
- if (line[0] == '#')
- goto again1;
- if (!!strcmp(line, "P6")) {
- printf("expecting image depth 'P6'\n");
- fclose(fp);
- return -1;
- }
-again2:
- if (!fgets(line, sizeof(line), fp)) {
- printf("failed to read image size\n");
- fclose(fp);
- return -1;
- }
- line[sizeof(line)-1] = '\0';
- if (line[0]) line[strlen(line)-1] = '\0';
- if (line[0] == '#')
- goto again2;
- sscanf(line, "%d %d", width, height);
-// printf("Image size: w=%d h=%d\n", *width, *height);
-again3:
- if (!fgets(line, sizeof(line), fp)) {
- printf("failed to read line '255' or '65535'\n");
- fclose(fp);
- return -1;
- }
- line[sizeof(line)-1] = '\0';
- if (line[0]) line[strlen(line)-1] = '\0';
- if (line[0] == '#')
- goto again3;
- if (!strcmp(line, "255")) {
- words = 1;
- } else
- if (!strcmp(line, "65535")) {
- words = 2;
- } else {
- printf("expecting line '255' or '65535'\n");
- fclose(fp);
- return -1;
- }
- if (offset < 0) {
- *buffer = (unsigned short *)malloc((*width) * (*height) * 3 * words * sizeof(unsigned short));
- if (!*buffer) {
- printf("failed to allocate image data\n");
- fclose(fp);
- return -1;
- }
- offset = 0;
- }
- if (fread((*buffer) + offset, (*width) * (*height) * 3 * words, 1, fp) != 1) {
- printf("failed to read image data\n");
- free(*buffer);
- fclose(fp);
- return -1;
- }
-
- /* convert 8 to 16 bits */
- if (words == 8) {
- for (i = (*width) * (*height) * 3 - 1; i >= 0; i--) {
- (*buffer)[offset + i] = ((unsigned char *)((*buffer) - offset + (i >> 1)))[0] << 8;
- (*buffer)[offset + i] = ((unsigned char *)((*buffer) - offset + (i >> 1)))[1] << 8;
- }
- } else {
- for (i = 0; i < (*width) * (*height) * 3; i++) {
- /* correct bit order */
- (*buffer)[offset + i] = ((unsigned char *)((*buffer) - offset + i))[0] << 8;
- (*buffer)[offset + i] |= ((unsigned char *)((*buffer) - offset + i))[1];
- }
- }
-
- fclose(fp);
-
- return 0;
-}
-
-/* save given image */
-int save_img(unsigned short *buffer, int width, int height, const char *filename,
- int index)
-{
- FILE *fp;
- int rc;
- char line[256];
-
- sprintf(line, filename, index);
-// printf("writing image: %s\n", line);
- fp = fopen(line, "w");
- if (!fp) {
- printf("failed to write image\n");
- return -1;
- }
- fprintf(fp, "P6\n%d %d\n65535\n", width, height);
- for (i = 0; i < (*width) * (*height) * 3; i++) {
- /* correct bit order */
- rc = fputc(((unsigned char *)((*buffer) - offset + i))[0] >> 8, fp);
- rc = fputc(((unsigned char *)((*buffer) - offset + i))[1], fp);
- }
-
- fclose(fp);
-
- return rc;
-}
-#endif
-
-/* convert an image to a three dimensional array of double
- * the size is: width, height, 3
- */
-void img2array(unsigned short *img, int iw, int ih, double *array, int aw,
- int ah)
-{
- int x, y;
- int plane = aw * ah;
- double r, g, b;
-
- for (y = 0; y < ih; y++) {
- for (x = 0; x < iw; x++) {
- r = img[(x+iw*y)*3] / 65535.0F;
- g = img[(x+iw*y)*3+1] / 65535.0F;
- b = img[(x+iw*y)*3+2] / 65535.0F;
- array[x+aw*y] = r;
- array[x+aw*y+plane] = g;
- array[x+aw*y+plane+plane] = b;
- }
- }
-}
-
-/* convert a three dimensional array of double to an image
- * the size is: width, height, 3
- */
-void array2img(double *array, int aw, int ah, unsigned short *img, int iw,
- int ih)
-{
- int x, y, c;
- int plane = aw * ah;
- double r, g, b;
-
- for (y = 0; y < ih; y++) {
- for (x = 0; x < iw; x++) {
- r = array[x+aw*y];
- g = array[x+aw*y+plane];
- b = array[x+aw*y+plane+plane];
- c = (r * 65535.0F + 0.5F);
- if (c < 0)
- c = 0;
- else if (c > 65535)
- c = 65535;
- img[(x+iw*y)*3] = c;
- c = (g * 65535.0F + 0.5F);
- if (c < 0)
- c = 0;
- else if (c > 65535)
- c = 65535;
- img[(x+iw*y)*3+1] = c;
- c = (b * 65535.0F + 0.5F);
- if (c < 0)
- c = 0;
- else if (c > 65535)
- c = 65535;
- img[(x+iw*y)*3+2] = c;
- }
- }
-}
-
-
+++ /dev/null
-extern int save_depth;
-int load_img(int offset, unsigned short **buffer, int *width, int *height, const char *filename, int index);
-int save_img(unsigned short *buffer, int width, int height, const char *filename, int index);
-void img2array(unsigned short *img, int iw, int ih, double *array, int aw, int ah);
-void array2img(double *array, int aw, int ah, unsigned short *img, int iw, int ih);
-
--- /dev/null
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <math.h>
+#include <time.h>
+#include "../lib/darray.h"
+#include "yuv.h"
+#include "mark.h"
+#include "process.h"
+
+/*
+ * create image array and marked array
+ */
+int alloc_I_arrays(darray_t **I, darray_t **mI, int w, int h, int k, int *features, char **feat_names, int change_alpha, int change_bc)
+{
+ int dims[4];
+
+ dims[0] = w; dims[1] = h; dims[2] = k;
+ *mI = darrayCreate(3, dims);
+ if (!*mI) {
+ printf("%s:failed to create mark array\n", __func__);
+ goto exit;
+ }
+ *features = 2; /* u and v */
+ feat_names[0] = "u";
+ feat_names[1] = "v";
+ if (change_alpha) {
+ *features += 2;
+ feat_names[2] = "alpha";
+ feat_names[3] = "y-removal";
+ }
+ if (change_bc) {
+ *features += 2;
+ if (change_alpha) {
+ feat_names[4] = "brightness";
+ feat_names[5] = "contrast";
+ } else {
+ feat_names[2] = "brightness";
+ feat_names[3] = "contrast";
+ }
+ }
+ dims[0] = w; dims[1] = h; dims[2] = *features + 1; dims[3] = k;
+ *I = darrayCreate(4, dims);
+ if (!*I) {
+ printf("%s:failed to create image array\n", __func__);
+ goto exit;
+ }
+
+ return 0;
+
+exit:
+ if (*I)
+ darrayDestroy(*I);
+ if (*mI)
+ darrayDestroy(*mI);
+
+ return -1;
+}
+
+/*
+ * set pointers to image/mark arrays
+ */
+void set_I_ptr(darray_t *I, darray_t *mI, int w, int h, int z, int features, int change_alpha, int change_bc, double **ptr_y, double **ptr_u, double **ptr_v, double **ptr_a, double **ptr_r, double **ptr_b, double **ptr_c, double **ptr_m)
+{
+ *ptr_y = darrayGetPr(I) + w*h*(features+1)*z;
+ *ptr_u = *ptr_y + w*h;
+ *ptr_v = *ptr_u + w*h;
+ if (change_alpha) {
+ *ptr_a = *ptr_v + w*h;
+ *ptr_r = *ptr_a + w*h;
+ }
+ if (change_bc) {
+ if (change_alpha)
+ *ptr_b = *ptr_r + w*h;
+ else
+ *ptr_b = *ptr_v + w*h;
+ *ptr_c = *ptr_b + w*h;
+ }
+ *ptr_m = darrayGetPr(mI) + w*h*z;
+}
+
+/*
+ * use cI, gI and mI to prepare image array
+ */
+void prepare_arrays(int w, int h, int change_alpha, int change_bc, unsigned char *mark_buffer, double *ptr_gI, double *ptr_cI, double *ptr_y, double *ptr_u, double *ptr_v, double *ptr_a, double *ptr_r, double *ptr_b, double *ptr_c, double *ptr_m, enum test test)
+{
+ int x, y;
+
+ if (test != BC_ONLY) {
+ unsigned char c;
+ // generate I image: use luminance from original image and chrominance from original or marked image
+ /* use original y component */
+ memcpy(ptr_y, ptr_gI, w*h*sizeof(double));
+ /* apply new uv components */
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ c = mark_buffer[y*w+x];
+ if (c == 0) {
+ ptr_u[w*y+x] = ptr_gI[w*h + w*y+x];
+ ptr_v[w*y+x] = ptr_gI[w*h*2 + w*y+x];
+ } else {
+ ptr_u[w*y+x] = ptr_cI[w*h + w*y+x];
+ ptr_v[w*y+x] = ptr_cI[w*h*2 + w*y+x];
+ }
+ }
+ }
+ } else {
+ /* use grey image as result if BC_ONLY test is selected */
+ memcpy(ptr_y, ptr_gI, w*h*3*sizeof(double));
+ }
+
+ if (change_alpha) {
+ double alpha;
+ unsigned char c;
+ /* apply alpha from marked pixles to alpha component of grey image
+ * also create a removal image to remove luminance from alpha after colorization
+ * also remove color from u and v marks now */
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ c = mark_buffer[y*w+x];
+ if (c == 0) {
+ ptr_a[y*w+x] = 0.5;
+ ptr_r[y*w+x] = 0.0;
+ } else {
+ alpha = mark_palette[c-1].alpha;
+ /* opaqueness */
+ ptr_a[y*w+x] = alpha;
+ /* keep luminance according to transparency */
+ ptr_r[y*w+x] = (1.0 - alpha) * ptr_y[y*w+x];
+ /* remove color from u and v, according to transparency */
+ ptr_u[y*w+x] *= alpha;
+ ptr_v[y*w+x] *= alpha;
+ }
+ }
+ }
+ }
+
+ if (change_bc) {
+ unsigned char c;
+ /* apply brightness and contrast from makred pixles to bc components of grey image */
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ /* use unchanged brightness and contrast on index 0 */
+ c = mark_buffer[y*w+x];
+ if (c == 0) {
+ ptr_b[y*w+x] = 0.0;
+ ptr_c[y*w+x] = 0.1;
+ } else {
+ ptr_b[y*w+x] = mark_palette[c-1].bright / 10.0;
+ ptr_c[y*w+x] = mark_palette[c-1].contrast / 10.0;
+ }
+ }
+ }
+ }
+}
+
+void postpare_arrays(int w, int h, int change_alpha, int change_bc, double *ptr_y, double *ptr_u, double *ptr_v, double *ptr_a, double *ptr_r, double *ptr_b, double *ptr_c, double *ptr_m, enum test test)
+{
+ int x, y;
+
+ /* if we have a change, we remove y from transparent pixles, according to transparency
+ * also we normalize the remaining pixles according to transparency
+ *
+ * y = y - r / alpha (r = removal image)
+ * u = u / alpha
+ * v = v / alpha
+ */
+ if (change_alpha && test != REMOVAL_IMAGE) {
+ double alpha, lum;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ alpha = ptr_a[w*y+x];
+ /* if transparent, the result is undefined */
+ if (alpha < 0.0001)
+ continue;
+ lum = ptr_y[w*y+x] - ptr_r[w*y+x];
+ /* if negative, assume black pixle */
+ if (lum < 0)
+ lum = 0;
+ /* normalize yuv */
+ ptr_y[w*y+x] = lum / alpha;
+ ptr_u[w*y+x] /= alpha;
+ ptr_v[w*y+x] /= alpha;
+ }
+ }
+ }
+
+ /* if we have a change, we apply brightness+contrast from image array */
+ if (change_bc) {
+ double lum;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ /* apply contrast */
+ lum = ptr_y[w*y+x];
+ lum = (lum - 0.5) * ptr_c[w*y+x] * 10.0 + 0.5;
+ /* apply brightness */
+ lum += ptr_b[w * y + x] * 10.0;
+ if (lum < 0)
+ lum = 0;
+ if (lum > 1)
+ lum = 1;
+ ptr_y[w*y+x] = lum;
+#if 0
+#warning TEST: show brightness and contrast change as uv vectors on a grey array */
+ptr_y[w*y+x] = 0.5;
+ptr_u[w*y+x] = ptr_b[w*y+x] * 10;
+ptr_v[w*y+x] = ptr_c[w*y+x] * 10 - 1;
+#endif
+ }
+ }
+ }
+
+ if (test == MASK) {
+ /* apply maked mask as image */
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ ptr_y[w*y+x] = ptr_m[w*y+x];
+ ptr_u[w*y+x] = 0;
+ ptr_v[w*y+x] = 0;
+ }
+ }
+ }
+
+ if (test == MASK_COLOR) {
+ /* apply maked mask on grey image */
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ /* darken unmarked areas, make maked areas with uniformed brightness */
+ if (ptr_m[w*y+x] < 0.5)
+ ptr_y[w*y+x] = ptr_y[w*y+x] / 4;
+ else
+ ptr_y[w*y+x] = 0.5;
+ }
+ }
+ }
+
+ if (test == BC_IMAGE) {
+ /* apply bc image as result image */
+ /* use uniformed brightness as y component */
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ ptr_y[w*y+x] = 0.5;
+ }
+ }
+ /* display B and C as U and V */
+ if (change_bc) {
+ memcpy(ptr_u, ptr_b, w*h*sizeof(double));
+ memcpy(ptr_v, ptr_c, w*h*sizeof(double));
+ } else {
+ memset(ptr_u, 0, w*h*sizeof(double));
+ memset(ptr_v, 0, w*h*sizeof(double));
+ }
+ }
+
+ if (test == ALPHA) {
+ /* apply alpha image as result y component only */
+ memcpy(ptr_y, ptr_a, w*h*sizeof(double));
+ memset(ptr_u, 0, w*h*sizeof(double));
+ memset(ptr_v, 0, w*h*sizeof(double));
+ }
+
+ if (test == REMOVAL_IMAGE) {
+ /* apply removal image as result y component */
+ memcpy(ptr_y, ptr_r, w*h*sizeof(double));
+ }
+}
+
--- /dev/null
+
+enum test {
+ NO_TEST = 0,
+ FLOW_NEXT,
+ FLOW_PREV,
+ MARKED,
+ MASK,
+ MASK_COLOR,
+ BC_ONLY,
+ BC_IMAGE,
+ ALPHA,
+ NO_ALPHA,
+ REMOVAL_IMAGE,
+};
+
+int alloc_I_arrays(darray_t **I, darray_t **mI, int w, int h, int k, int *features, char **feat_names, int change_alpha, int change_bc);
+void set_I_ptr(darray_t *I, darray_t *mI, int w, int h, int z, int features, int change_alpha, int change_bc, double **ptr_y, double **ptr_u, double **ptr_v, double **ptr_a, double **ptr_r, double **ptr_b, double **ptr_c, double **ptr_m);
+void prepare_arrays(int w, int h, int change_alpha, int change_bc, unsigned char *mark_buffer, double *ptr_gI, double *ptr_cI, double *ptr_y, double *ptr_u, double *ptr_v, double *ptr_a, double *ptr_r, double *ptr_b, double *ptr_c, double *ptr_m, enum test test);
+void postpare_arrays(int w, int h, int change_alpha, int change_bc, double *ptr_y, double *ptr_u, double *ptr_v, double *ptr_a, double *ptr_r, double *ptr_b, double *ptr_c, double *ptr_m, enum test test);
+
fields
fields_SOURCES = \
- ../src/ppm.c \
+ ../src/img.c \
fields.c
fields_LDADD = \
$(COMMON_LA) $(GRAPHICSMAGICK_LIBS) $(IMAGEMAGICK_LIBS)
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
-#include "../src/ppm.h"
+#include "../src/img.h"
/* split interlaced image into two fields */
static void split_image(const unsigned short *source, unsigned short *dest1,
next_frame:
printf("\n\nProcessing frame %d, field %d+%d\n", frame, field, field+1);
if (mode == MODE_FRAME_2_FIELD) {
- if (load_img(-1, &frame_img, &width, &height, argv[_arg+1], frame++))
+ frame_img = load_img(&width, &height, argv[_arg+1], frame++);
+ if (!frame_img)
goto out;
if (!(field1_img = malloc(width * height/2 * 3 * sizeof(unsigned short))))
goto out;
if (!(field2_img = malloc(width * height/2 * 3 * sizeof(unsigned short))))
goto out;
split_image(frame_img, field1_img, field2_img, width, height);
- if (save_img(field1_img, width, height/2, argv[_arg+2], field++))
+ if (save_img(field1_img, width, height/2, 0, argv[_arg+2], field++))
goto out;
- if (save_img(field2_img, width, height/2, argv[_arg+2], field++))
+ if (save_img(field2_img, width, height/2, 0, argv[_arg+2], field++))
goto out;
free(frame_img);
free(field1_img);
goto next_frame;
}
if (mode == MODE_FIELD_2_FRAME) {
- if (load_img(-1, &field1_img, &width, &height, argv[_arg+1], field++))
+ field1_img = load_img(&width, &height, argv[_arg+1], field++);
+ if (!field1_img)
goto out;
- if (load_img(-1, &field2_img, &width, &height, argv[_arg+1], field++))
+ field2_img = load_img(&width, &height, argv[_arg+1], field++);
+ if (!field2_img)
goto out;
if (!(frame_img = malloc(width * height*2 * 3 * sizeof(unsigned short))))
goto out;
join_image(field1_img, field2_img, frame_img, width, height*2);
- if (save_img(frame_img, width, height*2, argv[_arg+2], frame++))
+ if (save_img(frame_img, width, height*2, 0, argv[_arg+2], frame++))
goto out;
free(field1_img);
free(field2_img);