8 #include "../lib/darray.h"
9 #include "../lib/colorize.h"
13 #include "dir_seperator.h"
15 #include "opticalflow.h"
18 #define min(x,y) ((x < y) ? x : y)
20 static void print_help(const char *app);
21 static void print_test_help();
24 //#define SINGLE_K_TEST 2
33 static struct sequence *sequence = NULL;
35 /* load sequence list and return number of images in sequence */
36 static int load_sequence(int *start, int *next, char *first_filename)
38 const char *name = "sequence";
40 int i, j, keyframe_before_start, eof;
44 /* free previously used sequence */
50 /* get number of frames until next keyframe or end of squence */
51 fp = fopen(name, "r");
53 printf("failed to load sequence '%s'\n", name);
59 keyframe_before_start = 0;
60 while(fgets(buffer, sizeof(buffer), fp)) {
61 p = strchr(buffer + 1, '\"');
66 strcpy(first_filename, buffer + 1);
68 if ((*start) && j == (*start) - 1) {
69 if (strstr(p, "keyframe"))
70 keyframe_before_start = 1;
77 printf("counting %d\n", j);
81 /* skip start frame, since it is always a keyframe */
84 if (strstr(p, "keyframe")) {
91 /* end of file case */
100 #ifdef DEBUG_SEQUENCE
104 #ifdef DEBUG_SEQUENCE
105 puts("end of file at last frame");
110 /* we are done, because we already had the last sequence */
111 if (!keyframe_before_start) {
112 #ifdef DEBUG_SEQUENCE
113 puts("no keyframe before start");
118 #ifdef DEBUG_SEQUENCE
119 puts("keyframe before start");
121 /* we just have a single last frame */
123 (*next) = (*start) + 1;
125 /* if we have two keyframes side by side, we ignore it */
126 if (count == 2 && !eof) {
127 #ifdef DEBUG_SEQUENCE
130 /* only if the frame before start is not a keyframe
131 * and we are not the first sequence, because that would mean
132 * that the first frame is a single sequence */
133 if (!keyframe_before_start && (*start) > 0) {
134 #ifdef DEBUG_SEQUENCE
135 puts("no keyframe before start");
140 #ifdef DEBUG_SEQUENCE
141 puts("keyframe before start or first frame");
143 /* now the start frame has one keyframe before and one after */
145 (*next) = (*start) + 1;
147 (*next) = (*start) + count - 1;
150 /* alloc memory for sequence and fill with data */
151 sequence = (struct sequence *)malloc(sizeof(struct sequence) * count);
153 printf("no memory for sequence\n");
156 memset((struct sequence *)sequence, 0, sizeof(struct sequence) * count);
157 fp = fopen(name, "r");
159 printf("failed to load sequence '%s'\n", name);
164 while(fgets(buffer, sizeof(buffer), fp)) {
165 p = strchr(buffer + 1, '\"');
173 strcpy(sequence[i].filename, buffer + 1);
187 /* scale down image in img_buffer by calculating average */
188 static void scale_img(unsigned char *img_buffer, int width, int height, int scale)
190 int w, h, i, j, x, y;
199 for (i = 0; i < h; i++) {
200 for (j = 0; j < w; j++) {
202 for (y = 0; y < scale; y++) {
203 for (x = 0; x < scale; x++) {
204 r += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 0];
205 g += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 1];
206 b += img_buffer[((i*scale+y) * width + j*scale+x) * 3 + 2];
209 img_buffer[(i * w + j)*3 + 0] = r / scale / scale;
210 img_buffer[(i * w + j)*3 + 1] = g / scale / scale;
211 img_buffer[(i * w + j)*3 + 2] = b / scale / scale;
216 /* scale down mark map in mark_buffer */
217 static void scale_mark(unsigned char *mark_buffer, int width, int height, int scale)
219 int w, h, i, j, x, y;
220 unsigned char c, temp;
228 for (i = 0; i < h; i++) {
229 for (j = 0; j < w; j++) {
231 /* always use one index other than 0, if there is any in an areaa to be shrinked */
232 for (y = 0; y < scale; y++) {
233 for (x = 0; x < scale; x++) {
234 temp = mark_buffer[(i*scale+y) * width + j*scale+x];
239 mark_buffer[i * w + j] = c;
248 static int in_itr_num = 5, out_itr_num = 1, optical_flow = 1, bright_contrast = 1;
249 int scale = 1, scalexyz = 999;
262 static int parse_test(const char *arg)
264 if (!strcmp(arg, "help")) {
269 if (!strcmp(arg, "flow-next"))
271 if (!strcmp(arg, "flow-prev"))
274 if (!strcmp(arg, "marked"))
276 if (!strcmp(arg, "mask"))
278 if (!strcmp(arg, "mask+color"))
280 if (!strcmp(arg, "bc-only"))
282 if (!strcmp(arg, "bc-image"))
288 static int handle_options(int argc, char **argv)
293 int option_index = 0, c;
294 static struct option long_options[] = {
296 {"in-itr-num", 1, 0, 'i'},
297 {"out-itr-num", 1, 0, 'o'},
298 {"zscale", 1, 0, 'z'},
299 {"brightness-contrast", 1, 0, 'b'},
300 {"optical-flow", 1, 0, 'f'},
301 {"scale", 1, 0, 's'},
306 c = getopt_long(argc, argv, "hi:o:z:b:f:s:t:", long_options, &option_index);
316 in_itr_num = atoi(optarg);
320 out_itr_num = atoi(optarg);
324 scalexyz = atoi(optarg);
328 bright_contrast = atoi(optarg);
332 optical_flow = atoi(optarg);
336 scale = atoi(optarg);
340 test = parse_test(optarg);
342 fprintf(stderr, "Invalid test '%s', use '--test help' to get a list of tests\n", optarg);
359 static void print_help(const char *app)
361 printf("Colorize version %s\n\n",
362 #include "../version.h"
364 printf("Usage: %s [options] <grey ppm image> <marked ppm image> <result ppm image> [<frames> <start>]\n", app);
365 printf(" Colorize grey image using maked image and save to result image.\n");
366 printf(" If frames and start frame is given, image names must include printf integer formatting (e.g. %%04d).\n");
367 printf("Usage: %s [options] <grey ppm image> marked <result ppm image>\n", app);
368 printf(" Colorize grey image using marked mask + palette and save to result image.\n");
369 printf("Usage: %s [options] sequence [list | <start with frame> [<stop with frame>]]\n", app);
370 printf(" Colorize movie sequence (generated by colorize gui) as found in the current directory.\n");
371 printf(" Use list to view sequence segments between keyframes.\n");
372 printf("\nOptions:\n");
373 printf(" -h --help This help\n");
374 printf(" -i --in-itr-num <num> Alter inner iterations (weightening count) of colorization algorithm (default=%d)\n", in_itr_num);
375 printf(" -o --out-itr-num <num> Alter outer iterations (complete turns) of colorization algorithm (default=%d)\n", out_itr_num);
376 printf(" -z --zscale <levels> How many grids (staring with the finest) should be scaled in z direction to generate the next coarse grid ");
378 printf("(default=%d)\n", scalexyz);
380 printf("(default=infinite)\n");
381 printf(" -b --brightness-contrast [0 | 1] Apply brightnes and contrast, if defined in palette by GUI (default=%d)\n", bright_contrast);
383 printf(" -f --optical-flow [0 | 1] Apply optical flow, if defined by GUI (default=%d)\n", optical_flow);
385 printf(" -s --scale [1..n] Scale down by the given factor for quick and dirty previews (default=%d)\n", scale);
386 printf(" -t --test <test> Generate test images. Use 'help' for list of tests\n");
389 static void print_test_help()
391 printf(" -t --test <test> Generate test images...\n");
393 printf(" flow-next Optical flow plane to next image\n");
394 printf(" flow-prev Optical flow plane to previous image\n");
396 printf(" marked Only apply makred colors to grey image\n");
397 printf(" mask Show mask of marked areas\n");
398 printf(" mask+color Show mask of marked areas + color\n");
399 printf(" bc-only Only apply brightness+contrast, leave colors of grey image as is\n");
400 printf(" bc-image Show brightness+contrast change on grey image as uv components\n");
407 int main(int argc, char *argv[])
409 darray_t *gI = NULL, *cI = NULL, *markIm = NULL, *ntscIm = NULL, *resultIm;
410 darray_t *dx = NULL, *dy = NULL, *idx = NULL, *idy = NULL;
412 int *flow_map_x = NULL, *flow_map_y = NULL;
414 double *ptr, *ptr2, *ptr3;
417 int width = 0, height = 0, w, h, k = 1, index = 0, count;
418 unsigned char *img_buffer, *img_buffer_all = NULL, *mark_buffer = NULL;
421 const char* filename;
422 char first_filename[256];
423 int seq_offset = 0, seq_next = 0;
424 int features, change_bc;
427 skip_args = handle_options(argc, argv);
437 if (argc > 1 && !strcmp(argv[1], "sequence")) {
438 k = load_sequence(&seq_offset, &seq_next, first_filename);
441 printf("Got %d frames from sequence (frames %d..%d)\n", k, seq_offset, seq_offset + k - 1);
442 if (argc > 2 && (!strcmp(argv[2], "list") || atoi(argv[2]) > seq_offset)) {
443 seq_offset = seq_next;
446 } else if (argc <= 3) {
449 } else if (argc > 5) {
451 index = atoi(argv[5]);
457 if (k > SINGLE_K_TEST)
464 for (count = 0; count < k; count++) {
466 filename = sequence[count].filename;
467 /* first_filename is set by load_sequence */
470 strcpy(first_filename, argv[1]);
473 // load flow settings
474 if (sequence || !strcmp(argv[2], "marked")) {
477 load_flow(first_filename);
478 if (flow_enable == 0 && (test == FLOW_NEXT || test == FLOW_PREV)) {
479 fprintf(stderr, "Cannot test optical flow, because it is not enabled by GUI.\n");
484 // load original image and convert their RGB components to double RGB array
485 rc = load_img(-1, &img_buffer, &w, &h, filename, index + count);
487 fprintf(stderr, "Failed to load grey image\n");
490 scale_img(img_buffer, w, h, scale);
495 if (w/scale != width || h/scale != height) {
496 fprintf(stderr, "Error: All input images must have equal dimenstions.\n");
499 // now we know the dimensions, so we can create input arrays
501 dims[0] = width; dims[1] = height; dims[2] = 3; dims[3] = k;
502 gI = darrayCreate(4, dims);
505 printf("failed to create grey image array\n");
509 dims[0] = width; dims[1] = height; dims[2] = 3; dims[3] = k;
510 cI = darrayCreate(4, dims);
513 printf("failed to create marked image array\n");
516 ptr = darrayGetPr(gI) + width*height*3*count;
517 img2array(img_buffer, width, height, ptr, width, height);
519 if (k > 1 && flow_enable) {
521 img_buffer_all = malloc(width*height*3*k);
522 if (!img_buffer_all) {
523 printf("failed to create grey image array\n");
526 memcpy(img_buffer_all + width*height*3*count, img_buffer, width*height*3);
531 if (sequence || !strcmp(argv[2], "marked")) {
534 // load marked mask and convert their RGB components to double YUV array
535 memcpy(darrayGetPr(cI) + width*height*3*count, darrayGetPr(gI) + width*height*3*count, width*height*3 * sizeof(double));
536 /* add extra memory for unscaled data to prevent buffer overflow */
538 mark_buffer = (unsigned char *)malloc(width*height*k + w*h);
540 printf("no memory for mark buffer\n");
543 if (load_palette(first_filename)) {
544 printf("failed to load palette for file: '%s'\n", filename);
547 sprintf(name, filename, index + count);
548 /* always load full unscaled image, then scale down */
549 if (load_marked(mark_buffer + width*height*count, w, h, name) == 0) {
550 scale_mark(mark_buffer + width*height*count, w, h, scale);
551 ptr = darrayGetPr(cI) + width*height*3*count;
552 for (i = 0; i < height; i++) {
553 for (j = 0; j < width; j++) {
554 /* do not apply mask on index 0 */
555 c = mark_buffer[i*width+j + width*height*count];
558 /* check for any brightness/contrast change */
559 if (bright_contrast && (mark_palette[c-1].bright != 0 || mark_palette[c-1].contrast != 1))
561 /* do not apply white pixles, this meas: keep original color */
562 if (mark_palette[c-1].r == 255 && mark_palette[c-1].g == 255 && mark_palette[c-1].b == 255)
564 ptr[i*width+j] = mark_palette[c-1].r / 255.0F;
565 ptr[i*width+j + width*height] = mark_palette[c-1].g / 255.0F;
566 ptr[i*width+j + width*height*2] = mark_palette[c-1].b / 255.0F;
570 memset(mark_buffer + width*height*count, 0, width*height);
572 // load marked image and convert their RGB components to double YUV array
573 rc = load_img(-1, &img_buffer, &w, &h, argv[2], index + count);
575 if (w/scale != width || h/scale != height) {
576 fprintf(stderr, "Error: All input images must have equal dimenstions.\n");
579 ptr = darrayGetPr(cI) + width*height*3*count;
580 img2array(img_buffer, width, height, ptr, width, height);
583 fprintf(stderr, "Failed to load marked image, omitting...\n");
584 memcpy(darrayGetPr(cI) + width*height*3*count, darrayGetPr(gI) + width*height*3*count, width*height*3 * sizeof(double));
589 /* create color mask and ntsc arrays for the colorization process */
590 dims[0] = width; dims[1] = height; dims[2] = k;
591 markIm = darrayCreate(3, dims);
593 printf("failed to create mark array\n");
596 features = (change_bc) ? 4 : 2;
597 dims[0] = width; dims[1] = height; dims[2] = features+1; dims[3] = k;
598 ntscIm = darrayCreate(4, dims);
600 printf("failed to create ntsc array\n");
604 for (count = 0; count < k; count++) {
605 if (sequence || !strcmp(argv[2], "marked")) {
607 ptr = darrayGetPr(markIm) + width*height*count;
608 // use marked mask to fill markIm
609 for (i = 0; i < height; i++) {
610 for (j = 0; j < width; j++) {
611 if (j < width && i < height) {
612 /* do not apply mask on index 0 */
613 c = mark_buffer[i*width+j + width*height*count];
617 ptr[i*width+j] = 1.0F;
619 ptr[i*width+j] = 0.0F;
623 // fill color image with marked pixles
624 // - calculate the difference between two images (original image - color image)
625 // - convert into absolute (positive values)
626 // - sum all components to get grey image
627 // - apply threshold (pixle is 1F, if the absolute difference is > 0.01F)
628 // original code: markIm=(sum(abs(gI-cI),3)>0.01);
629 ptr = darrayGetPr(gI) + width*height*3*count;
630 ptr2 = darrayGetPr(cI) + width*height*3*count;
631 ptr3 = darrayGetPr(markIm) + width*height*count;
632 for (i = 0, ii = width * height; i < ii; i++) {
634 sum = ptr[i] - ptr2[i];
639 sum = ptr[i + ii] - ptr2[i + ii];
644 sum = ptr[i + ii + ii] - ptr2[i + ii + ii];
656 // convert original image into YUV
657 ptr = darrayGetPr(gI) + width*height*3*count;
658 rgb2yuv(ptr, ptr, width, height);
660 // convert maked image into YUV
661 ptr = darrayGetPr(cI) + width*height*3*count;
662 rgb2yuv(ptr, ptr, width, height);
664 if (test != BC_ONLY) {
665 if (sequence || !strcmp(argv[2], "marked")) {
667 // generate NTSC image: use luminance from original image and chrominance from original or marked image
668 ptr = darrayGetPr(gI) + width*height*3*count;
669 ptr2 = darrayGetPr(cI) + width*height*3*count;
670 ptr3 = darrayGetPr(ntscIm) + width*height*(features+1)*count;
671 /* use original y component */
672 memcpy(ptr3, ptr, width * height * sizeof(double));
673 /* apply new uv components */
674 for (i = 0; i < height; i++) {
675 for (j = 0; j < width; j++) {
676 c = mark_buffer[i*width+j + width*height*count];
678 ptr3[width * height + width * i + j] = ptr[width * height + width * i + j];
679 ptr3[width * height * 2 + width * i + j] = ptr[width * height * 2 + width * i + j];
681 ptr3[width * height + width * i + j] = ptr2[width * height + width * i + j];
682 ptr3[width * height * 2 + width * i + j] = ptr2[width * height * 2 + width * i + j];
687 // generate NTSC image: use luminance from original image and chrominance from maked image
688 ptr = darrayGetPr(gI) + width*height*3*count;
689 ptr2 = darrayGetPr(cI) + width*height*3*count;
690 ptr3 = darrayGetPr(ntscIm) + width*height*(features+1)*count;
691 memcpy(ptr3, ptr, width * height * sizeof(double));
692 memcpy(ptr3 + width * height, ptr2 + width * height, width * height * sizeof(double));
693 memcpy(ptr3 + width * height * 2, ptr2 + width * height * 2, width * height * sizeof(double));
696 /* use grey image as result if BC_ONLY test is selected */
697 ptr = darrayGetPr(gI) + width*height*3*count;
698 ptr2 = darrayGetPr(ntscIm) + width*height*(features+1)*count;
699 memcpy(ptr2, ptr, width * height * 3 * sizeof(double));
704 ptr2 = darrayGetPr(ntscIm) + width*height*(features+1)*count;
705 /* use original y component */
706 memcpy(ptr2, ptr, width * height * sizeof(double));
707 /* apply brightness and contrast from makred pixles to uv components of grey image */
708 for (i = 0; i < height; i++) {
709 for (j = 0; j < width; j++) {
710 /* use unchanged brightness and contrast on index 0 */
711 c = mark_buffer[i*width+j + width*height*count];
713 ptr2[i*width+j + width*height*3] = 0;
714 ptr2[i*width+j + width*height*4] = 0.1;
716 ptr2[i*width+j + width*height*3] = mark_palette[c-1].bright / 10.0;
717 ptr2[i*width+j + width*height*4] = mark_palette[c-1].contrast / 10.0;
724 /* create flow vectors */
725 dims[0] = width; dims[1] = height; dims[2] = k - 1;
726 dx = darrayCreate(3, dims);
728 printf("failed to create array\n");
731 dy = darrayCreate(3, dims);
733 printf("failed to create array\n");
736 idx = darrayCreate(3, dims);
738 printf("failed to create array\n");
741 idy = darrayCreate(3, dims);
743 printf("failed to create array\n");
747 if (k > 1 && flow_enable) {
748 printf("Calculating optical flow for %d frames: steps=%d win=%d max=%d\n", k, flow_steps/scale, flow_win/scale, flow_max/scale);
749 flow_map_x = (int *)malloc(sizeof(int)*width*height);
751 printf("failed to alloc array\n");
754 flow_map_y = (int *)malloc(sizeof(int)*width*height);
756 printf("failed to alloc array\n");
760 for (count = 0; count < k-1; count++) {
761 if (flow_map_x && flow_map_y)
762 create_flow_maps(NULL, img_buffer_all + width*height*3*(count+1), img_buffer_all + width*height*3*count, width, height, flow_steps/scale, flow_win/scale, flow_max/scale, NULL, NULL, flow_map_x, flow_map_y, NULL);
763 ptr = darrayGetPr(dx) + width*height*count;
765 for (j = 0; j < height; j++) {
766 for (i = 0; i < width; i++)
767 ptr[i + width * j] = flow_map_x[width*j + i];
770 ptr = darrayGetPr(dy) + width*height*count;
772 for (j = 0; j < height; j++) {
773 for (i = 0; i < width; i++)
774 ptr[i + width * j] = flow_map_y[width*j + i];
777 if (flow_map_x && flow_map_y)
778 create_flow_maps(img_buffer_all + width*height*3*count, NULL, img_buffer_all + width*height*3*(count+1), width, height, flow_steps/scale, flow_win/scale, flow_max/scale, flow_map_x, flow_map_y, NULL, NULL, NULL);
779 ptr = darrayGetPr(idx) + width*height*count;
781 for (j = 0; j < height; j++) {
782 for (i = 0; i < width; i++)
783 ptr[i + width * j] = flow_map_x[width*j + i];
786 ptr = darrayGetPr(idy) + width*height*count;
788 for (j = 0; j < height; j++) {
789 for (i = 0; i < width; i++)
790 ptr[i + width * j] = flow_map_y[width*j + i];
795 free(img_buffer_all);
796 img_buffer_all = NULL;
803 if (test != FLOW_NEXT && test != FLOW_PREV && test != MARKED && test != MASK && test != MASK_COLOR && test != BC_ONLY && test != BC_IMAGE) {
804 printf("Colorizing %d frames, please wait...\n", k);
805 resultIm = colorize(ntscIm, markIm, dx, dy, idx, idy, in_itr_num, out_itr_num, scalexyz);
808 printf("No memory! Use smaller frames or less frames between key frames or add more memory.");
810 printf("No memory! Use smaller image or add more memory.");
814 resultIm = darrayClone(ntscIm);
816 /* if we have a change, we apply brightness+contrast from bcIm */
818 for (count = 0; count < k; count++) {
819 ptr = darrayGetPr(ntscIm) + width*height*(features+1)*count;
820 ptr2 = darrayGetPr(resultIm) + width*height*(features+1)*count;
821 for (i = 0; i < height; i++) {
822 for (j = 0; j < width; j++) {
824 ptr2[width * i + j] = (ptr2[width * i + j] - 0.5) * ptr[width * height * 4 + width * i + j] * 10.0 + 0.5;
825 /* apply brightness */
826 ptr2[width * i + j] += ptr[width * height * 3 + width * i + j] * 10.0;
827 if (ptr2[width * i + j] < 0)
828 ptr2[width * i + j] = 0;
829 if (ptr2[width * i + j] > 1)
830 ptr2[width * i + j] = 1;
832 #warning TEST: show brightness and contrast change as uv vectors on a grey array */
833 ptr2[width * i + j] = 0.5;
834 ptr2[width * height + width * i + j] = ptr[width * height + width * i + j] * 10;
835 ptr2[width * height * 2 + width * i + j] = ptr[width * height * 2 + width * i + j] * 10 - 1;
842 darrayDestroy(ntscIm);
846 if (test == FLOW_NEXT || test == FLOW_PREV) {
847 /* apply flow planes to result image as u and y vector */
848 for (count = 0; count < k; count++) {
849 ptr = darrayGetPr(resultIm) + width*height*(features+1)*count;
850 if (test == FLOW_NEXT) {
851 ptr2 = darrayGetPr(dx) + width*height*count;
852 ptr3 = darrayGetPr(dy) + width*height*count;
854 ptr2 = darrayGetPr(idx) + width*height*count;
855 ptr3 = darrayGetPr(idy) + width*height*count;
857 for (i = 0; i < height; i++) {
858 for (j = 0; j < width; j++) {
859 ptr[width * i + j] = 0.5;
861 ptr[width * i + j + width*height] = ptr2[width * i + j] / flow_max;
862 ptr[width * i + j + width*height*2] = ptr3[width * i + j] / flow_max;
864 ptr[width * i + j + width*height] = 0;
865 ptr[width * i + j + width*height*2] = 0;
874 /* apply maked mask as image */
875 for (count = 0; count < k; count++) {
876 ptr = darrayGetPr(resultIm) + width*height*(features+1)*count;
877 ptr2 = darrayGetPr(markIm) + width*height*count;
878 for (i = 0; i < height; i++) {
879 for (j = 0; j < width; j++) {
880 ptr[width * i + j] = ptr2[width * i + j];
881 ptr[width * i + j + width*height] = ptr2[width * i + j];
882 ptr[width * i + j + width*height*2] = ptr2[width * i + j];
888 if (test == MASK_COLOR) {
889 /* apply maked mask on grey image */
890 for (count = 0; count < k; count++) {
891 ptr = darrayGetPr(resultIm) + width*height*(features+1)*count;
892 ptr2 = darrayGetPr(markIm) + width*height*count;
893 for (i = 0; i < height; i++) {
894 for (j = 0; j < width; j++) {
895 /* darken unmarked areas, make maked areas with uniformed brightness */
896 if (ptr2[width * i + j] < 0.5F)
897 ptr[width * i + j] = ptr[width * i + j] / 4;
899 ptr[width * i + j] = 0.5F;
905 if (test == BC_IMAGE) {
906 /* apply bc image as result image */
907 for (count = 0; count < k; count++) {
908 ptr = darrayGetPr(resultIm) + width*height*(features+1)*count;
909 ptr2 = darrayGetPr(resultIm) + width*height*(features+1)*count;
910 /* use uniformed brightness as y component */
911 for (i = 0; i < height; i++) {
912 for (j = 0; j < width; j++) {
913 ptr[width * i + j] = 0.5F;
917 ptr2 = darrayGetPr(resultIm) + width*height*(features+1)*count;
918 memcpy(ptr+width*height, ptr2+width*height*3, width * height * sizeof(double));
919 memcpy(ptr+width*height*2, ptr2+width*height*4, width * height * sizeof(double));
921 memset(ptr+width*height, 0, width * height * sizeof(double));
922 memset(ptr+width*height*2, 0, width * height * sizeof(double));
927 // save result YUV array to image with RGB components
928 img_buffer = (unsigned char *)malloc(width * height * 3);
930 fprintf(stderr, "Failed to allocate image buffer\n");
933 for (count = 0; count < k; count++) {
934 ptr = darrayGetPr(resultIm) + width*height*(features+1)*count;
935 yuv2rgb(ptr, ptr, width, height);
936 array2img(ptr, width, height, img_buffer, width, height);
938 static char name[256], *p, *q;
939 p = sequence[count].filename;
940 while((q = strchr(p, DIR_SEPERATOR)))
942 strcpy(name, sequence[count].filename);
943 name[p - sequence[count].filename] = '\0';
944 strcat(name, "colorized_");
949 save_img(img_buffer, width, height, filename, index + count);
954 printf("Elapsed time: %d minutes, %d seconds\n", (int)(end-start)/60, (int)(end-start)%60);
957 darrayDestroy(resultIm);
973 darrayDestroy(markIm);
985 /* if end frame is not given or if not reached */
986 if (argc <= 3 || atoi(argv[3]) > seq_offset + k) {
987 seq_offset = seq_offset + k - 1;