From 9d42f49a240136a8cd643cdc1f98230d4f22b05e Mon Sep 17 00:00:00 2001
From: Joseph Redmon <pjreddie@gmail.com>
Date: Tue, 25 Aug 2015 01:27:42 +0000
Subject: [PATCH] changing data loading
---
src/network.c | 19
src/yolo.c | 34
src/region_layer.h | 18
src/box.h | 2
Makefile | 9
src/network_kernels.cu | 5
src/data.c | 308 +++----
src/box.c | 19
src/region_layer.c | 161 ++++
src/data.h | 33
src/detection_layer.c | 8
/dev/null | 305 -------
src/image.c | 1145 ++++++++++++++--------------
src/coco.c | 91 +-
src/imagenet.c | 35
src/parser.c | 18
src/captcha.c | 117 --
cfg/darknet.cfg | 2
src/darknet.c | 3
src/image.h | 2
src/layer.h | 1
21 files changed, 1,104 insertions(+), 1,231 deletions(-)
diff --git a/Makefile b/Makefile
index 556f2a4..8ce6888 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,9 @@
-GPU=0
-OPENCV=0
+GPU=1
+OPENCV=1
DEBUG=0
ARCH= --gpu-architecture=compute_20 --gpu-code=compute_20
+ARCH= -arch sm_52
VPATH=./src/
EXEC=darknet
@@ -10,7 +11,7 @@
CC=gcc
NVCC=nvcc
-OPTS=-Ofast
+OPTS=-O2
LDFLAGS= -lm -pthread -lstdc++
COMMON= -I/usr/local/cuda/include/
CFLAGS=-Wall -Wfatal-errors
@@ -34,7 +35,7 @@
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
-OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o imagenet.o captcha.o detection.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o
+OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o imagenet.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o region_layer.o
ifeq ($(GPU), 1)
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o softmax_layer_kernels.o network_kernels.o avgpool_layer_kernels.o
endif
diff --git a/cfg/darknet.cfg b/cfg/darknet.cfg
index 2a99279..2e0a624 100644
--- a/cfg/darknet.cfg
+++ b/cfg/darknet.cfg
@@ -1,6 +1,6 @@
[net]
batch=128
-subdivisions=1
+subdivisions=32
height=256
width=256
channels=3
diff --git a/src/box.c b/src/box.c
index 0518c05..d49be41 100644
--- a/src/box.c
+++ b/src/box.c
@@ -231,3 +231,22 @@
}
}
+box encode_box(box b, box anchor)
+{
+ box encode;
+ encode.x = (b.x - anchor.x) / anchor.w;
+ encode.y = (b.y - anchor.y) / anchor.h;
+ encode.w = log2(b.w / anchor.w);
+ encode.h = log2(b.h / anchor.h);
+ return encode;
+}
+
+box decode_box(box b, box anchor)
+{
+ box decode;
+ decode.x = b.x * anchor.w + anchor.x;
+ decode.y = b.y * anchor.h + anchor.y;
+ decode.w = pow(2., b.w) * anchor.w;
+ decode.h = pow(2., b.h) * anchor.h;
+ return decode;
+}
diff --git a/src/box.h b/src/box.h
index 998f58a..e45dd89 100644
--- a/src/box.h
+++ b/src/box.h
@@ -12,5 +12,7 @@
float box_iou(box a, box b);
dbox diou(box a, box b);
void do_nms(box *boxes, float **probs, int num_boxes, int classes, float thresh);
+box decode_box(box b, box anchor);
+box encode_box(box b, box anchor);
#endif
diff --git a/src/captcha.c b/src/captcha.c
index 772f9d7..68d8915 100644
--- a/src/captcha.c
+++ b/src/captcha.c
@@ -26,7 +26,7 @@
}
}
-void train_captcha2(char *cfgfile, char *weightfile)
+void train_captcha(char *cfgfile, char *weightfile)
{
data_seed = time(0);
srand(time(0));
@@ -55,7 +55,19 @@
pthread_t load_thread;
data train;
data buffer;
- load_thread = load_data_thread(paths, imgs, plist->size, labels, 26, net.w, net.h, &buffer);
+
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.paths = paths;
+ args.classes = 26;
+ args.n = imgs;
+ args.m = plist->size;
+ args.labels = labels;
+ args.d = &buffer;
+ args.type = CLASSIFICATION_DATA;
+
+ load_thread = load_data_in_thread(args);
while(1){
++i;
time=clock();
@@ -69,7 +81,7 @@
cvWaitKey(0);
*/
- load_thread = load_data_thread(paths, imgs, plist->size, labels, 26, net.w, net.h, &buffer);
+ load_thread = load_data_in_thread(args);
printf("Loaded: %lf seconds\n", sec(clock()-time));
time=clock();
float loss = train_network(net, train);
@@ -86,7 +98,7 @@
}
}
-void test_captcha2(char *cfgfile, char *weightfile, char *filename)
+void test_captcha(char *cfgfile, char *weightfile, char *filename)
{
network net = parse_network_cfg(cfgfile);
if(weightfile){
@@ -165,99 +177,6 @@
}
}
-void train_captcha(char *cfgfile, char *weightfile)
-{
- data_seed = time(0);
- srand(time(0));
- float avg_loss = -1;
- char *base = basecfg(cfgfile);
- printf("%s\n", base);
- network net = parse_network_cfg(cfgfile);
- if(weightfile){
- load_weights(&net, weightfile);
- }
- printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay);
- //net.seen=0;
- int imgs = 1024;
- int i = net.seen/imgs;
- char **labels = get_labels("/data/captcha/reimgs.labels.list");
- list *plist = get_paths("/data/captcha/reimgs.train.list");
- char **paths = (char **)list_to_array(plist);
- printf("%d\n", plist->size);
- clock_t time;
- pthread_t load_thread;
- data train;
- data buffer;
- load_thread = load_data_thread(paths, imgs, plist->size, labels, 13, net.w, net.h, &buffer);
- while(1){
- ++i;
- time=clock();
- pthread_join(load_thread, 0);
- train = buffer;
-
- /*
- image im = float_to_image(256, 256, 3, train.X.vals[114]);
- show_image(im, "training");
- cvWaitKey(0);
- */
-
- load_thread = load_data_thread(paths, imgs, plist->size, labels, 13, net.w, net.h, &buffer);
- printf("Loaded: %lf seconds\n", sec(clock()-time));
- time=clock();
- float loss = train_network(net, train);
- net.seen += imgs;
- if(avg_loss == -1) avg_loss = loss;
- avg_loss = avg_loss*.9 + loss*.1;
- printf("%d: %f, %f avg, %lf seconds, %d images\n", i, loss, avg_loss, sec(clock()-time), net.seen);
- free_data(train);
- if(i%100==0){
- char buff[256];
- sprintf(buff, "/home/pjreddie/imagenet_backup/%s_%d.weights",base, i);
- save_weights(net, buff);
- }
- }
-}
-
-void test_captcha(char *cfgfile, char *weightfile, char *filename)
-{
- network net = parse_network_cfg(cfgfile);
- if(weightfile){
- load_weights(&net, weightfile);
- }
- set_batch_network(&net, 1);
- srand(2222222);
- int i = 0;
- char **names = get_labels("/data/captcha/reimgs.labels.list");
- char input[256];
- int indexes[13];
- while(1){
- if(filename){
- strncpy(input, filename, 256);
- }else{
- //printf("Enter Image Path: ");
- //fflush(stdout);
- fgets(input, 256, stdin);
- strtok(input, "\n");
- }
- image im = load_image_color(input, net.w, net.h);
- float *X = im.data;
- float *predictions = network_predict(net, X);
- top_predictions(net, 13, indexes);
- //printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));
- for(i = 0; i < 13; ++i){
- int index = indexes[i];
- if(i != 0) printf(", ");
- printf("%s %f", names[index], predictions[index]);
- }
- printf("\n");
- fflush(stdout);
- free_image(im);
- if (filename) break;
- }
-}
-
-
-
/*
void train_captcha(char *cfgfile, char *weightfile)
{
@@ -435,8 +354,8 @@
char *cfg = argv[3];
char *weights = (argc > 4) ? argv[4] : 0;
char *filename = (argc > 5) ? argv[5]: 0;
- if(0==strcmp(argv[2], "train")) train_captcha2(cfg, weights);
- else if(0==strcmp(argv[2], "test")) test_captcha2(cfg, weights, filename);
+ if(0==strcmp(argv[2], "train")) train_captcha(cfg, weights);
+ else if(0==strcmp(argv[2], "test")) test_captcha(cfg, weights, filename);
else if(0==strcmp(argv[2], "valid")) valid_captcha(cfg, weights, filename);
//if(0==strcmp(argv[2], "test")) test_captcha(cfg, weights);
//else if(0==strcmp(argv[2], "encode")) encode_captcha(cfg, weights);
diff --git a/src/coco.c b/src/coco.c
index 66fddf5..d2a108a 100644
--- a/src/coco.c
+++ b/src/coco.c
@@ -15,41 +15,32 @@
int coco_ids[] = {1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,90};
-void draw_coco(image im, float *box, int side, int objectness, char *label)
+void draw_coco(image im, float *pred, int side, char *label)
{
- int classes = 80;
- int elems = 4+classes+objectness;
+ int classes = 81;
+ int elems = 4+classes;
int j;
int r, c;
for(r = 0; r < side; ++r){
for(c = 0; c < side; ++c){
j = (r*side + c) * elems;
- float scale = 1;
- if(objectness) scale = 1 - box[j++];
- int class = max_index(box+j, classes);
- if(scale * box[j+class] > 0.2){
- int width = box[j+class]*5 + 1;
- printf("%f %s\n", scale * box[j+class], coco_classes[class]);
+ int class = max_index(pred+j, classes);
+ if (class == 0) continue;
+ if (pred[j+class] > 0.2){
+ int width = pred[j+class]*5 + 1;
+ printf("%f %s\n", pred[j+class], coco_classes[class-1]);
float red = get_color(0,class,classes);
float green = get_color(1,class,classes);
float blue = get_color(2,class,classes);
j += classes;
- float x = box[j+0];
- float y = box[j+1];
- x = (x+c)/side;
- y = (y+r)/side;
- float w = box[j+2]; //*maxwidth;
- float h = box[j+3]; //*maxheight;
- h = h*h;
- w = w*w;
- int left = (x-w/2)*im.w;
- int right = (x+w/2)*im.w;
- int top = (y-h/2)*im.h;
- int bot = (y+h/2)*im.h;
- draw_box_width(im, left, top, right, bot, width, red, green, blue);
+ box predict = {pred[j+0], pred[j+1], pred[j+2], pred[j+3]};
+ box anchor = {(c+.5)/side, (r+.5)/side, .5, .5};
+ box decode = decode_box(predict, anchor);
+
+ draw_bbox(im, decode, width, red, green, blue);
}
}
}
@@ -69,39 +60,47 @@
if(weightfile){
load_weights(&net, weightfile);
}
- detection_layer layer = get_network_detection_layer(net);
printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay);
int imgs = 128;
int i = net.seen/imgs;
data train, buffer;
- int classes = layer.classes;
- int background = layer.objectness;
- int side = sqrt(get_detection_layer_locations(layer));
+ int classes = 81;
+ int side = 7;
- char **paths;
list *plist = get_paths(train_images);
int N = plist->size;
+ char **paths = (char **)list_to_array(plist);
- paths = (char **)list_to_array(plist);
- pthread_t load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.paths = paths;
+ args.n = imgs;
+ args.m = plist->size;
+ args.classes = classes;
+ args.num_boxes = side;
+ args.d = &buffer;
+ args.type = REGION_DATA;
+
+ pthread_t load_thread = load_data_in_thread(args);
clock_t time;
while(i*imgs < N*120){
i += 1;
time=clock();
pthread_join(load_thread, 0);
train = buffer;
- load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
+ load_thread = load_data_in_thread(args);
printf("Loaded: %lf seconds\n", sec(clock()-time));
- /*
- image im = float_to_image(net.w, net.h, 3, train.X.vals[114]);
- image copy = copy_image(im);
- draw_coco(copy, train.y.vals[114], 7, layer.objectness, "truth");
- cvWaitKey(0);
- free_image(copy);
- */
+/*
+ image im = float_to_image(net.w, net.h, 3, train.X.vals[114]);
+ image copy = copy_image(im);
+ draw_coco(copy, train.y.vals[114], 7, "truth");
+ cvWaitKey(0);
+ free_image(copy);
+ */
time=clock();
float loss = train_network(net, train);
@@ -220,6 +219,11 @@
int nms = 1;
float iou_thresh = .5;
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.type = IMAGE_DATA;
+
int nthreads = 8;
image *val = calloc(nthreads, sizeof(image));
image *val_resized = calloc(nthreads, sizeof(image));
@@ -227,7 +231,10 @@
image *buf_resized = calloc(nthreads, sizeof(image));
pthread_t *thr = calloc(nthreads, sizeof(pthread_t));
for(t = 0; t < nthreads; ++t){
- thr[t] = load_image_thread(paths[i+t], &buf[t], &buf_resized[t], net.w, net.h);
+ args.path = paths[i+t];
+ args.im = &buf[t];
+ args.resized = &buf_resized[t];
+ thr[t] = load_data_in_thread(args);
}
time_t start = time(0);
for(i = nthreads; i < m+nthreads; i += nthreads){
@@ -238,7 +245,10 @@
val_resized[t] = buf_resized[t];
}
for(t = 0; t < nthreads && i+t < m; ++t){
- thr[t] = load_image_thread(paths[i+t], &buf[t], &buf_resized[t], net.w, net.h);
+ args.path = paths[i+t];
+ args.im = &buf[t];
+ args.resized = &buf_resized[t];
+ thr[t] = load_data_in_thread(args);
}
for(t = 0; t < nthreads && i+t-nthreads < m; ++t){
char *path = paths[i+t-nthreads];
@@ -267,7 +277,6 @@
if(weightfile){
load_weights(&net, weightfile);
}
- detection_layer layer = get_network_detection_layer(net);
set_batch_network(&net, 1);
srand(2222222);
clock_t time;
@@ -287,7 +296,7 @@
time=clock();
float *predictions = network_predict(net, X);
printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));
- draw_coco(im, predictions, 7, layer.objectness, "predictions");
+ draw_coco(im, predictions, 7, "predictions");
free_image(im);
free_image(sized);
#ifdef OPENCV
diff --git a/src/darknet.c b/src/darknet.c
index 9b6eadb..0928f28 100644
--- a/src/darknet.c
+++ b/src/darknet.c
@@ -12,7 +12,6 @@
#endif
extern void run_imagenet(int argc, char **argv);
-extern void run_detection(int argc, char **argv);
extern void run_yolo(int argc, char **argv);
extern void run_coco(int argc, char **argv);
extern void run_writing(int argc, char **argv);
@@ -164,8 +163,6 @@
run_imagenet(argc, argv);
} else if (0 == strcmp(argv[1], "average")){
average(argc, argv);
- } else if (0 == strcmp(argv[1], "detection")){
- run_detection(argc, argv);
} else if (0 == strcmp(argv[1], "yolo")){
run_yolo(argc, argv);
} else if (0 == strcmp(argv[1], "coco")){
diff --git a/src/data.c b/src/data.c
index 6a41d13..a335e07 100644
--- a/src/data.c
+++ b/src/data.c
@@ -8,25 +8,6 @@
unsigned int data_seed;
-typedef struct load_args{
- char **paths;
- int n;
- int m;
- char **labels;
- int k;
- int h;
- int w;
- int nh;
- int nw;
- int num_boxes;
- int classes;
- int background;
- data *d;
- char *path;
- image *im;
- image *resized;
-} load_args;
-
list *get_paths(char *filename)
{
char *path;
@@ -138,6 +119,89 @@
}
}
+void correct_boxes(box_label *boxes, int n, float dx, float dy, float sx, float sy, int flip)
+{
+ int i;
+ for(i = 0; i < n; ++i){
+ boxes[i].left = boxes[i].left * sx - dx;
+ boxes[i].right = boxes[i].right * sx - dx;
+ boxes[i].top = boxes[i].top * sy - dy;
+ boxes[i].bottom = boxes[i].bottom* sy - dy;
+
+ if(flip){
+ float swap = boxes[i].left;
+ boxes[i].left = 1. - boxes[i].right;
+ boxes[i].right = 1. - swap;
+ }
+
+ boxes[i].left = constrain(0, 1, boxes[i].left);
+ boxes[i].right = constrain(0, 1, boxes[i].right);
+ boxes[i].top = constrain(0, 1, boxes[i].top);
+ boxes[i].bottom = constrain(0, 1, boxes[i].bottom);
+
+ boxes[i].x = (boxes[i].left+boxes[i].right)/2;
+ boxes[i].y = (boxes[i].top+boxes[i].bottom)/2;
+ boxes[i].w = (boxes[i].right - boxes[i].left);
+ boxes[i].h = (boxes[i].bottom - boxes[i].top);
+
+ boxes[i].w = constrain(0, 1, boxes[i].w);
+ boxes[i].h = constrain(0, 1, boxes[i].h);
+ }
+}
+
+void fill_truth_region(char *path, float *truth, int classes, int num_boxes, int flip, float dx, float dy, float sx, float sy)
+{
+ char *labelpath = find_replace(path, "images", "labels");
+ labelpath = find_replace(labelpath, ".jpg", ".txt");
+ labelpath = find_replace(labelpath, ".JPEG", ".txt");
+ int count = 0;
+ box_label *boxes = read_boxes(labelpath, &count);
+ randomize_boxes(boxes, count);
+ correct_boxes(boxes, count, dx, dy, sx, sy, flip);
+ float x,y,w,h;
+ int id;
+ int i;
+
+ for(i = 0; i < num_boxes*num_boxes*(4+classes); i += 4+classes){
+ truth[i] = 1;
+ }
+
+ for(i = 0; i < count; ++i){
+ x = boxes[i].x;
+ y = boxes[i].y;
+ w = boxes[i].w;
+ h = boxes[i].h;
+ id = boxes[i].id;
+
+ if (x <= 0 || x >= 1 || y <= 0 || y >= 1) continue;
+ if (w < .01 || h < .01) continue;
+
+ int col = (int)(x*num_boxes);
+ int row = (int)(y*num_boxes);
+
+ float xa = (col+.5)/num_boxes;
+ float ya = (row+.5)/num_boxes;
+ float wa = .5;
+ float ha = .5;
+
+ float tx = (x - xa) / wa;
+ float ty = (y - ya) / ha;
+ float tw = log2(w/wa);
+ float th = log2(h/ha);
+
+ int index = (col+row*num_boxes)*(4+classes);
+ if(!truth[index]) continue;
+ truth[index] = 0;
+ truth[index+id+1] = 1;
+ index += classes;
+ truth[index++] = tx;
+ truth[index++] = ty;
+ truth[index++] = tw;
+ truth[index++] = th;
+ }
+ free(boxes);
+}
+
void fill_truth_detection(char *path, float *truth, int classes, int num_boxes, int flip, int background, float dx, float dy, float sx, float sy)
{
char *labelpath = find_replace(path, "JPEGImages", "labels");
@@ -178,20 +242,20 @@
w = (right - left);
h = (bot - top);
- if (x <= 0 || x >= 1 || y <= 0 || y >= 1) continue;
+ if (x <= 0 || x >= 1 || y <= 0 || y >= 1) continue;
- int i = (int)(x*num_boxes);
- int j = (int)(y*num_boxes);
+ int col = (int)(x*num_boxes);
+ int row = (int)(y*num_boxes);
- x = x*num_boxes - i;
- y = y*num_boxes - j;
+ x = x*num_boxes - col;
+ y = y*num_boxes - row;
/*
- float maxwidth = distance_from_edge(i, num_boxes);
- float maxheight = distance_from_edge(j, num_boxes);
- w = w/maxwidth;
- h = h/maxheight;
- */
+ float maxwidth = distance_from_edge(i, num_boxes);
+ float maxheight = distance_from_edge(j, num_boxes);
+ w = w/maxwidth;
+ h = h/maxheight;
+ */
w = constrain(0, 1, w);
h = constrain(0, 1, h);
@@ -201,7 +265,7 @@
h = pow(h, 1./2.);
}
- int index = (i+j*num_boxes)*(4+classes+background);
+ int index = (col+row*num_boxes)*(4+classes+background);
if(truth[index+classes+background+2]) continue;
if(background) truth[index++] = 0;
truth[index+id] = 1;
@@ -214,57 +278,6 @@
free(boxes);
}
-void fill_truth_localization(char *path, float *truth, int classes, int flip, float dx, float dy, float sx, float sy)
-{
- char *labelpath = find_replace(path, "objects", "object_labels");
- labelpath = find_replace(labelpath, ".jpg", ".txt");
- labelpath = find_replace(labelpath, ".JPEG", ".txt");
- int count;
- box_label *boxes = read_boxes(labelpath, &count);
- box_label box = boxes[0];
- free(boxes);
- float x,y,w,h;
- float left, top, right, bot;
- int id;
- int i;
- for(i = 0; i < count; ++i){
- left = box.left * sx - dx;
- right = box.right * sx - dx;
- top = box.top * sy - dy;
- bot = box.bottom* sy - dy;
- id = box.id;
-
- if(flip){
- float swap = left;
- left = 1. - right;
- right = 1. - swap;
- }
-
- left = constrain(0, 1, left);
- right = constrain(0, 1, right);
- top = constrain(0, 1, top);
- bot = constrain(0, 1, bot);
-
- x = (left+right)/2;
- y = (top+bot)/2;
- w = (right - left);
- h = (bot - top);
-
- if (x <= 0 || x >= 1 || y <= 0 || y >= 1) continue;
-
- w = constrain(0, 1, w);
- h = constrain(0, 1, h);
- if (w == 0 || h == 0) continue;
-
- int index = id*4;
- truth[index++] = x;
- truth[index++] = y;
- truth[index++] = w;
- truth[index++] = h;
- }
-}
-
-
#define NUMCHARS 37
void print_letters(float *pred, int n)
@@ -362,7 +375,7 @@
}
}
-data load_data_localization(int n, char **paths, int m, int classes, int w, int h)
+data load_data_region(int n, char **paths, int m, int classes, int w, int h, int num_boxes)
{
char **random_paths = get_random_paths(paths, n, m);
int i;
@@ -373,7 +386,7 @@
d.X.vals = calloc(d.X.rows, sizeof(float*));
d.X.cols = h*w*3;
- int k = (4*classes);
+ int k = num_boxes*num_boxes*(4+classes);
d.y = make_matrix(n, k);
for(i = 0; i < n; ++i){
image orig = load_image_color(random_paths[i], 0, 0);
@@ -381,13 +394,13 @@
int oh = orig.h;
int ow = orig.w;
- int dw = 32;
- int dh = 32;
+ int dw = ow/10;
+ int dh = oh/10;
- int pleft = (rand_uniform() * dw);
- int pright = (rand_uniform() * dw);
- int ptop = (rand_uniform() * dh);
- int pbot = (rand_uniform() * dh);
+ int pleft = (rand_uniform() * 2*dw - dw);
+ int pright = (rand_uniform() * 2*dw - dw);
+ int ptop = (rand_uniform() * 2*dh - dh);
+ int pbot = (rand_uniform() * 2*dh - dh);
int swidth = ow - pleft - pright;
int sheight = oh - ptop - pbot;
@@ -397,22 +410,24 @@
int flip = rand_r(&data_seed)%2;
image cropped = crop_image(orig, pleft, ptop, swidth, sheight);
+
float dx = ((float)pleft/ow)/sx;
float dy = ((float)ptop /oh)/sy;
- free_image(orig);
image sized = resize_image(cropped, w, h);
- free_image(cropped);
if(flip) flip_image(sized);
d.X.vals[i] = sized.data;
- fill_truth_localization(random_paths[i], d.y.vals[i], classes, flip, dx, dy, 1./sx, 1./sy);
+ fill_truth_region(random_paths[i], d.y.vals[i], classes, num_boxes, flip, dx, dy, 1./sx, 1./sy);
+
+ free_image(orig);
+ free_image(cropped);
}
free(random_paths);
return d;
}
-data load_data_detection_jitter_random(int n, char **paths, int m, int classes, int w, int h, int num_boxes, int background)
+data load_data_detection(int n, char **paths, int m, int classes, int w, int h, int num_boxes, int background)
{
char **random_paths = get_random_paths(paths, n, m);
int i;
@@ -471,81 +486,30 @@
return d;
}
-void *load_image_in_thread(void *ptr)
-{
- load_args a = *(load_args*)ptr;
- free(ptr);
- *(a.im) = load_image_color(a.path, 0, 0);
- *(a.resized) = resize_image(*(a.im), a.w, a.h);
- return 0;
-}
-
-pthread_t load_image_thread(char *path, image *im, image *resized, int w, int h)
-{
- pthread_t thread;
- struct load_args *args = calloc(1, sizeof(struct load_args));
- args->path = path;
- args->w = w;
- args->h = h;
- args->im = im;
- args->resized = resized;
- if(pthread_create(&thread, 0, load_image_in_thread, args)) {
- error("Thread creation failed");
- }
- return thread;
-}
-
-void *load_localization_thread(void *ptr)
+void *load_thread(void *ptr)
{
printf("Loading data: %d\n", rand_r(&data_seed));
- struct load_args a = *(struct load_args*)ptr;
- *a.d = load_data_localization(a.n, a.paths, a.m, a.classes, a.w, a.h);
- free(ptr);
- return 0;
-}
-
-pthread_t load_data_localization_thread(int n, char **paths, int m, int classes, int w, int h, data *d)
-{
- pthread_t thread;
- struct load_args *args = calloc(1, sizeof(struct load_args));
- args->n = n;
- args->paths = paths;
- args->m = m;
- args->w = w;
- args->h = h;
- args->classes = classes;
- args->d = d;
- if(pthread_create(&thread, 0, load_localization_thread, args)) {
- error("Thread creation failed");
+ load_args a = *(struct load_args*)ptr;
+ if (a.type == CLASSIFICATION_DATA){
+ *a.d = load_data(a.paths, a.n, a.m, a.labels, a.classes, a.w, a.h);
+ } else if (a.type == DETECTION_DATA){
+ *a.d = load_data_detection(a.n, a.paths, a.m, a.classes, a.w, a.h, a.num_boxes, a.background);
+ } else if (a.type == REGION_DATA){
+ *a.d = load_data_region(a.n, a.paths, a.m, a.classes, a.w, a.h, a.num_boxes);
+ } else if (a.type == IMAGE_DATA){
+ *(a.im) = load_image_color(a.path, 0, 0);
+ *(a.resized) = resize_image(*(a.im), a.w, a.h);
}
- return thread;
-}
-
-void *load_detection_thread(void *ptr)
-{
- printf("Loading data: %d\n", rand_r(&data_seed));
- struct load_args a = *(struct load_args*)ptr;
- *a.d = load_data_detection_jitter_random(a.n, a.paths, a.m, a.classes, a.w, a.h, a.num_boxes, a.background);
free(ptr);
return 0;
}
-pthread_t load_data_detection_thread(int n, char **paths, int m, int classes, int w, int h, int nh, int nw, int background, data *d)
+pthread_t load_data_in_thread(load_args args)
{
pthread_t thread;
- struct load_args *args = calloc(1, sizeof(struct load_args));
- args->n = n;
- args->paths = paths;
- args->m = m;
- args->h = h;
- args->w = w;
- args->nh = nh;
- args->nw = nw;
- args->num_boxes = nw;
- args->classes = classes;
- args->background = background;
- args->d = d;
- if(pthread_create(&thread, 0, load_detection_thread, args)) {
+ struct load_args *ptr = calloc(1, sizeof(struct load_args));
+ *ptr = args;
+ if(pthread_create(&thread, 0, load_thread, ptr)) {
error("Thread creation failed");
}
return thread;
@@ -577,32 +541,6 @@
return d;
}
-void *load_in_thread(void *ptr)
-{
- struct load_args a = *(struct load_args*)ptr;
- *a.d = load_data(a.paths, a.n, a.m, a.labels, a.k, a.w, a.h);
- free(ptr);
- return 0;
-}
-
-pthread_t load_data_thread(char **paths, int n, int m, char **labels, int k, int w, int h, data *d)
-{
- pthread_t thread;
- struct load_args *args = calloc(1, sizeof(struct load_args));
- args->n = n;
- args->paths = paths;
- args->m = m;
- args->labels = labels;
- args->k = k;
- args->h = h;
- args->w = w;
- args->d = d;
- if(pthread_create(&thread, 0, load_in_thread, args)) {
- error("Thread creation failed");
- }
- return thread;
-}
-
matrix concat_matrix(matrix m1, matrix m2)
{
int i, count = 0;
diff --git a/src/data.h b/src/data.h
index 993a7a7..f71e04a 100644
--- a/src/data.h
+++ b/src/data.h
@@ -19,26 +19,45 @@
return dist;
}
-
typedef struct{
matrix X;
matrix y;
int shallow;
} data;
+typedef enum {
+ CLASSIFICATION_DATA, DETECTION_DATA, CAPTCHA_DATA, REGION_DATA, IMAGE_DATA
+} data_type;
+
+typedef struct load_args{
+ char **paths;
+ char *path;
+ int n;
+ int m;
+ char **labels;
+ int k;
+ int h;
+ int w;
+ int nh;
+ int nw;
+ int num_boxes;
+ int classes;
+ int background;
+ data *d;
+ image *im;
+ image *resized;
+ data_type type;
+} load_args;
void free_data(data d);
+pthread_t load_data_in_thread(load_args args);
+
void print_letters(float *pred, int n);
data load_data_captcha(char **paths, int n, int m, int k, int w, int h);
data load_data_captcha_encode(char **paths, int n, int m, int w, int h);
data load_data(char **paths, int n, int m, char **labels, int k, int w, int h);
-pthread_t load_data_thread(char **paths, int n, int m, char **labels, int k, int w, int h, data *d);
-pthread_t load_image_thread(char *path, image *im, image *resized, int w, int h);
-
-pthread_t load_data_detection_thread(int n, char **paths, int m, int classes, int w, int h, int nh, int nw, int background, data *d);
-data load_data_detection_jitter_random(int n, char **paths, int m, int classes, int w, int h, int num_boxes, int background);
-pthread_t load_data_localization_thread(int n, char **paths, int m, int classes, int w, int h, data *d);
+data load_data_detection(int n, char **paths, int m, int classes, int w, int h, int num_boxes, int background);
data load_cifar10_data(char *filename);
data load_all_cifar10();
diff --git a/src/detection.c b/src/detection.c
deleted file mode 100644
index c9dea3e..0000000
--- a/src/detection.c
+++ /dev/null
@@ -1,305 +0,0 @@
-#include "network.h"
-#include "detection_layer.h"
-#include "cost_layer.h"
-#include "utils.h"
-#include "parser.h"
-#include "box.h"
-
-#ifdef OPENCV
-#include "opencv2/highgui/highgui_c.h"
-#endif
-
-char *class_names[] = {"aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"};
-
-void draw_detection(image im, float *box, int side, int objectness, char *label)
-{
- int classes = 20;
- int elems = 4+classes+objectness;
- int j;
- int r, c;
-
- for(r = 0; r < side; ++r){
- for(c = 0; c < side; ++c){
- j = (r*side + c) * elems;
- float scale = 1;
- if(objectness) scale = 1 - box[j++];
- int class = max_index(box+j, classes);
- if(scale * box[j+class] > 0.2){
- int width = box[j+class]*5 + 1;
- printf("%f %s\n", scale * box[j+class], class_names[class]);
- float red = get_color(0,class,classes);
- float green = get_color(1,class,classes);
- float blue = get_color(2,class,classes);
-
- j += classes;
- float x = box[j+0];
- float y = box[j+1];
- x = (x+c)/side;
- y = (y+r)/side;
- float w = box[j+2]; //*maxwidth;
- float h = box[j+3]; //*maxheight;
- h = h*h;
- w = w*w;
-
- int left = (x-w/2)*im.w;
- int right = (x+w/2)*im.w;
- int top = (y-h/2)*im.h;
- int bot = (y+h/2)*im.h;
- draw_box_width(im, left, top, right, bot, width, red, green, blue);
- }
- }
- }
- show_image(im, label);
-}
-
-void train_detection(char *cfgfile, char *weightfile)
-{
- char *train_images = "/home/pjreddie/data/voc/test/train.txt";
- char *backup_directory = "/home/pjreddie/backup/";
- srand(time(0));
- data_seed = time(0);
- char *base = basecfg(cfgfile);
- printf("%s\n", base);
- float avg_loss = -1;
- network net = parse_network_cfg(cfgfile);
- if(weightfile){
- load_weights(&net, weightfile);
- }
- detection_layer layer = get_network_detection_layer(net);
- printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay);
- int imgs = 128;
- int i = net.seen/imgs;
- data train, buffer;
-
- int classes = layer.classes;
- int background = layer.objectness;
- int side = sqrt(get_detection_layer_locations(layer));
-
- char **paths;
- list *plist = get_paths(train_images);
- int N = plist->size;
-
- paths = (char **)list_to_array(plist);
- pthread_t load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
- clock_t time;
- while(i*imgs < N*130){
- i += 1;
- time=clock();
- pthread_join(load_thread, 0);
- train = buffer;
- load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
-
- printf("Loaded: %lf seconds\n", sec(clock()-time));
- time=clock();
- float loss = train_network(net, train);
- net.seen += imgs;
- if (avg_loss < 0) avg_loss = loss;
- avg_loss = avg_loss*.9 + loss*.1;
-
- printf("%d: %f, %f avg, %lf seconds, %d images\n", i, loss, avg_loss, sec(clock()-time), i*imgs);
- if((i-1)*imgs <= N && i*imgs > N){
- fprintf(stderr, "First stage done\n");
- net.learning_rate *= 10;
- char buff[256];
- sprintf(buff, "%s/%s_first_stage.weights", backup_directory, base);
- save_weights(net, buff);
- }
- if((i-1)*imgs <= 80*N && i*imgs > N*80){
- fprintf(stderr, "Second stage done.\n");
- net.learning_rate *= .1;
- char buff[256];
- sprintf(buff, "%s/%s_second_stage.weights", backup_directory, base);
- save_weights(net, buff);
- return;
- }
- if((i-1)*imgs <= 120*N && i*imgs > N*120){
- fprintf(stderr, "Third stage done.\n");
- char buff[256];
- sprintf(buff, "%s/%s_third_stage.weights", backup_directory, base);
- net.layers[net.n-1].rescore = 1;
- save_weights(net, buff);
- }
- if(i%1000==0){
- char buff[256];
- sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i);
- save_weights(net, buff);
- }
- free_data(train);
- }
- char buff[256];
- sprintf(buff, "%s/%s_final.weights", backup_directory, base);
- save_weights(net, buff);
-}
-
-void convert_detections(float *predictions, int classes, int objectness, int background, int num_boxes, int w, int h, float thresh, float **probs, box *boxes)
-{
- int i,j;
- int per_box = 4+classes+(background || objectness);
- for (i = 0; i < num_boxes*num_boxes; ++i){
- float scale = 1;
- if(objectness) scale = 1-predictions[i*per_box];
- int offset = i*per_box+(background||objectness);
- for(j = 0; j < classes; ++j){
- float prob = scale*predictions[offset+j];
- probs[i][j] = (prob > thresh) ? prob : 0;
- }
- int row = i / num_boxes;
- int col = i % num_boxes;
- offset += classes;
- boxes[i].x = (predictions[offset + 0] + col) / num_boxes * w;
- boxes[i].y = (predictions[offset + 1] + row) / num_boxes * h;
- boxes[i].w = pow(predictions[offset + 2], 2) * w;
- boxes[i].h = pow(predictions[offset + 3], 2) * h;
- }
-}
-
-void print_detections(FILE **fps, char *id, box *boxes, float **probs, int num_boxes, int classes, int w, int h)
-{
- int i, j;
- for(i = 0; i < num_boxes*num_boxes; ++i){
- float xmin = boxes[i].x - boxes[i].w/2.;
- float xmax = boxes[i].x + boxes[i].w/2.;
- float ymin = boxes[i].y - boxes[i].h/2.;
- float ymax = boxes[i].y + boxes[i].h/2.;
-
- if (xmin < 0) xmin = 0;
- if (ymin < 0) ymin = 0;
- if (xmax > w) xmax = w;
- if (ymax > h) ymax = h;
-
- for(j = 0; j < classes; ++j){
- if (probs[i][j]) fprintf(fps[j], "%s %f %f %f %f %f\n", id, probs[i][j],
- xmin, ymin, xmax, ymax);
- }
- }
-}
-
-void validate_detection(char *cfgfile, char *weightfile)
-{
- network net = parse_network_cfg(cfgfile);
- if(weightfile){
- load_weights(&net, weightfile);
- }
- set_batch_network(&net, 1);
- detection_layer layer = get_network_detection_layer(net);
- fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay);
- srand(time(0));
-
- char *base = "results/comp4_det_test_";
- list *plist = get_paths("/home/pjreddie/data/voc/test/2007_test.txt");
- char **paths = (char **)list_to_array(plist);
-
- int classes = layer.classes;
- int objectness = layer.objectness;
- int background = layer.background;
- int num_boxes = sqrt(get_detection_layer_locations(layer));
-
- int j;
- FILE **fps = calloc(classes, sizeof(FILE *));
- for(j = 0; j < classes; ++j){
- char buff[1024];
- snprintf(buff, 1024, "%s%s.txt", base, class_names[j]);
- fps[j] = fopen(buff, "w");
- }
- box *boxes = calloc(num_boxes*num_boxes, sizeof(box));
- float **probs = calloc(num_boxes*num_boxes, sizeof(float *));
- for(j = 0; j < num_boxes*num_boxes; ++j) probs[j] = calloc(classes, sizeof(float *));
-
- int m = plist->size;
- int i=0;
- int t;
-
- float thresh = .001;
- int nms = 1;
- float iou_thresh = .5;
-
- int nthreads = 8;
- image *val = calloc(nthreads, sizeof(image));
- image *val_resized = calloc(nthreads, sizeof(image));
- image *buf = calloc(nthreads, sizeof(image));
- image *buf_resized = calloc(nthreads, sizeof(image));
- pthread_t *thr = calloc(nthreads, sizeof(pthread_t));
- for(t = 0; t < nthreads; ++t){
- thr[t] = load_image_thread(paths[i+t], &buf[t], &buf_resized[t], net.w, net.h);
- }
- time_t start = time(0);
- for(i = nthreads; i < m+nthreads; i += nthreads){
- fprintf(stderr, "%d\n", i);
- for(t = 0; t < nthreads && i+t-nthreads < m; ++t){
- pthread_join(thr[t], 0);
- val[t] = buf[t];
- val_resized[t] = buf_resized[t];
- }
- for(t = 0; t < nthreads && i+t < m; ++t){
- thr[t] = load_image_thread(paths[i+t], &buf[t], &buf_resized[t], net.w, net.h);
- }
- for(t = 0; t < nthreads && i+t-nthreads < m; ++t){
- char *path = paths[i+t-nthreads];
- char *id = basecfg(path);
- float *X = val_resized[t].data;
- float *predictions = network_predict(net, X);
- int w = val[t].w;
- int h = val[t].h;
- convert_detections(predictions, classes, objectness, background, num_boxes, w, h, thresh, probs, boxes);
- if (nms) do_nms(boxes, probs, num_boxes, classes, iou_thresh);
- print_detections(fps, id, boxes, probs, num_boxes, classes, w, h);
- free(id);
- free_image(val[t]);
- free_image(val_resized[t]);
- }
- }
- fprintf(stderr, "Total Detection Time: %f Seconds\n", (double)(time(0) - start));
-}
-
-void test_detection(char *cfgfile, char *weightfile, char *filename)
-{
-
- network net = parse_network_cfg(cfgfile);
- if(weightfile){
- load_weights(&net, weightfile);
- }
- detection_layer layer = get_network_detection_layer(net);
- set_batch_network(&net, 1);
- srand(2222222);
- clock_t time;
- char input[256];
- while(1){
- if(filename){
- strncpy(input, filename, 256);
- } else {
- printf("Enter Image Path: ");
- fflush(stdout);
- fgets(input, 256, stdin);
- strtok(input, "\n");
- }
- image im = load_image_color(input,0,0);
- image sized = resize_image(im, net.w, net.h);
- float *X = sized.data;
- time=clock();
- float *predictions = network_predict(net, X);
- printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));
- draw_detection(im, predictions, 7, layer.objectness, "predictions");
- free_image(im);
- free_image(sized);
-#ifdef OPENCV
- cvWaitKey(0);
- cvDestroyAllWindows();
-#endif
- if (filename) break;
- }
-}
-
-void run_detection(int argc, char **argv)
-{
- if(argc < 4){
- fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]);
- return;
- }
-
- char *cfg = argv[3];
- char *weights = (argc > 4) ? argv[4] : 0;
- char *filename = (argc > 5) ? argv[5]: 0;
- if(0==strcmp(argv[2], "test")) test_detection(cfg, weights, filename);
- else if(0==strcmp(argv[2], "train")) train_detection(cfg, weights);
- else if(0==strcmp(argv[2], "valid")) validate_detection(cfg, weights);
-}
diff --git a/src/detection_layer.c b/src/detection_layer.c
index e48b8b3..f83e2e4 100644
--- a/src/detection_layer.c
+++ b/src/detection_layer.c
@@ -97,6 +97,7 @@
truth.y = state.truth[j+1]/7;
truth.w = pow(state.truth[j+2], 2);
truth.h = pow(state.truth[j+3], 2);
+
box out;
out.x = l.output[j+0]/7;
out.y = l.output[j+1]/7;
@@ -107,13 +108,6 @@
float iou = box_iou(out, truth);
avg_iou += iou;
++count;
- dbox delta = diou(out, truth);
-
- l.delta[j+0] = 10 * delta.dx/7;
- l.delta[j+1] = 10 * delta.dy/7;
- l.delta[j+2] = 10 * delta.dw * 2 * sqrt(out.w);
- l.delta[j+3] = 10 * delta.dh * 2 * sqrt(out.h);
-
*(l.cost) += pow((1-iou), 2);
l.delta[j+0] = 4 * (state.truth[j+0] - l.output[j+0]);
diff --git a/src/image.c b/src/image.c
index d86f752..8669294 100644
--- a/src/image.c
+++ b/src/image.c
@@ -72,6 +72,19 @@
}
}
+void draw_bbox(image a, box bbox, int w, float r, float g, float b)
+{
+ int left = (bbox.x-bbox.w/2)*a.w;
+ int right = (bbox.x+bbox.w/2)*a.w;
+ int top = (bbox.y-bbox.h/2)*a.h;
+ int bot = (bbox.y+bbox.h/2)*a.h;
+
+ int i;
+ for(i = 0; i < w; ++i){
+ draw_box(a, left+i, top+i, right-i, bot-i, r, g, b);
+ }
+}
+
void flip_image(image a)
{
int i,j,k;
@@ -214,7 +227,7 @@
}
free_image(copy);
if(0){
- //if(disp->height < 448 || disp->width < 448 || disp->height > 1000){
+ //if(disp->height < 448 || disp->width < 448 || disp->height > 1000){
int w = 448;
int h = w*p.h/p.w;
if(h > 1000){
@@ -228,41 +241,41 @@
}
cvShowImage(buff, disp);
cvReleaseImage(&disp);
-}
+ }
#endif
-void show_image(image p, char *name)
-{
- #ifdef OPENCV
- show_image_cv(p, name);
- #else
- fprintf(stderr, "Not compiled with OpenCV, saving to %s.png instead\n", name);
- save_image(p, name);
- #endif
-}
-
-void save_image(image im, char *name)
-{
- char buff[256];
- //sprintf(buff, "%s (%d)", name, windows);
- sprintf(buff, "%s.png", name);
- unsigned char *data = calloc(im.w*im.h*im.c, sizeof(char));
- int i,k;
- for(k = 0; k < im.c; ++k){
- for(i = 0; i < im.w*im.h; ++i){
- data[i*im.c+k] = (unsigned char) (255*im.data[i + k*im.w*im.h]);
- }
+ void show_image(image p, char *name)
+ {
+#ifdef OPENCV
+ show_image_cv(p, name);
+#else
+ fprintf(stderr, "Not compiled with OpenCV, saving to %s.png instead\n", name);
+ save_image(p, name);
+#endif
}
- int success = stbi_write_png(buff, im.w, im.h, im.c, data, im.w*im.c);
- free(data);
- if(!success) fprintf(stderr, "Failed to write image %s\n", buff);
-}
-/*
-void save_image_cv(image p, char *name)
-{
- int x,y,k;
- image copy = copy_image(p);
+ void save_image(image im, char *name)
+ {
+ char buff[256];
+ //sprintf(buff, "%s (%d)", name, windows);
+ sprintf(buff, "%s.png", name);
+ unsigned char *data = calloc(im.w*im.h*im.c, sizeof(char));
+ int i,k;
+ for(k = 0; k < im.c; ++k){
+ for(i = 0; i < im.w*im.h; ++i){
+ data[i*im.c+k] = (unsigned char) (255*im.data[i + k*im.w*im.h]);
+ }
+ }
+ int success = stbi_write_png(buff, im.w, im.h, im.c, data, im.w*im.c);
+ free(data);
+ if(!success) fprintf(stderr, "Failed to write image %s\n", buff);
+ }
+
+ /*
+ void save_image_cv(image p, char *name)
+ {
+ int x,y,k;
+ image copy = copy_image(p);
//normalize_image(copy);
char buff[256];
@@ -272,603 +285,603 @@
IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c);
int step = disp->widthStep;
for(y = 0; y < p.h; ++y){
- for(x = 0; x < p.w; ++x){
- for(k= 0; k < p.c; ++k){
- disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(copy,x,y,k)*255);
- }
- }
+ for(x = 0; x < p.w; ++x){
+ for(k= 0; k < p.c; ++k){
+ disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(copy,x,y,k)*255);
+ }
+ }
}
free_image(copy);
cvSaveImage(buff, disp,0);
cvReleaseImage(&disp);
-}
-*/
-
-void show_image_layers(image p, char *name)
-{
- int i;
- char buff[256];
- for(i = 0; i < p.c; ++i){
- sprintf(buff, "%s - Layer %d", name, i);
- image layer = get_image_layer(p, i);
- show_image(layer, buff);
- free_image(layer);
}
-}
+ */
-void show_image_collapsed(image p, char *name)
-{
- image c = collapse_image_layers(p, 1);
- show_image(c, name);
- free_image(c);
-}
-
-image make_empty_image(int w, int h, int c)
-{
- image out;
- out.data = 0;
- out.h = h;
- out.w = w;
- out.c = c;
- return out;
-}
-
-image make_image(int w, int h, int c)
-{
- image out = make_empty_image(w,h,c);
- out.data = calloc(h*w*c, sizeof(float));
- return out;
-}
-
-image float_to_image(int w, int h, int c, float *data)
-{
- image out = make_empty_image(w,h,c);
- out.data = data;
- return out;
-}
-
-image rotate_image(image im, float rad)
-{
- int x, y, c;
- float cx = im.w/2.;
- float cy = im.h/2.;
- image rot = make_image(im.w, im.h, im.c);
- for(c = 0; c < im.c; ++c){
- for(y = 0; y < im.h; ++y){
- for(x = 0; x < im.w; ++x){
- float rx = cos(rad)*(x-cx) - sin(rad)*(y-cy) + cx;
- float ry = sin(rad)*(x-cx) + cos(rad)*(y-cy) + cy;
- float val = bilinear_interpolate(im, rx, ry, c);
- set_pixel(rot, x, y, c, val);
- }
+ void show_image_layers(image p, char *name)
+ {
+ int i;
+ char buff[256];
+ for(i = 0; i < p.c; ++i){
+ sprintf(buff, "%s - Layer %d", name, i);
+ image layer = get_image_layer(p, i);
+ show_image(layer, buff);
+ free_image(layer);
}
}
- return rot;
-}
-void translate_image(image m, float s)
-{
- int i;
- for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] += s;
-}
-
-void scale_image(image m, float s)
-{
- int i;
- for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] *= s;
-}
-
-image crop_image(image im, int dx, int dy, int w, int h)
-{
- image cropped = make_image(w, h, im.c);
- int i, j, k;
- for(k = 0; k < im.c; ++k){
- for(j = 0; j < h; ++j){
- for(i = 0; i < w; ++i){
- int r = j + dy;
- int c = i + dx;
- float val = 0;
- if (r >= 0 && r < im.h && c >= 0 && c < im.w) {
- val = get_pixel(im, c, r, k);
- }
- set_pixel(cropped, i, j, k, val);
- }
- }
+ void show_image_collapsed(image p, char *name)
+ {
+ image c = collapse_image_layers(p, 1);
+ show_image(c, name);
+ free_image(c);
}
- return cropped;
-}
-float three_way_max(float a, float b, float c)
-{
- return (a > b) ? ( (a > c) ? a : c) : ( (b > c) ? b : c) ;
-}
-
-float three_way_min(float a, float b, float c)
-{
- return (a < b) ? ( (a < c) ? a : c) : ( (b < c) ? b : c) ;
-}
-
-// http://www.cs.rit.edu/~ncs/color/t_convert.html
-void rgb_to_hsv(image im)
-{
- assert(im.c == 3);
- int i, j;
- float r, g, b;
- float h, s, v;
- for(j = 0; j < im.h; ++j){
- for(i = 0; i < im.w; ++i){
- r = get_pixel(im, i , j, 0);
- g = get_pixel(im, i , j, 1);
- b = get_pixel(im, i , j, 2);
- float max = three_way_max(r,g,b);
- float min = three_way_min(r,g,b);
- float delta = max - min;
- v = max;
- if(max == 0){
- s = 0;
- h = -1;
- }else{
- s = delta/max;
- if(r == max){
- h = (g - b) / delta;
- } else if (g == max) {
- h = 2 + (b - r) / delta;
- } else {
- h = 4 + (r - g) / delta;
- }
- if (h < 0) h += 6;
- }
- set_pixel(im, i, j, 0, h);
- set_pixel(im, i, j, 1, s);
- set_pixel(im, i, j, 2, v);
- }
+ image make_empty_image(int w, int h, int c)
+ {
+ image out;
+ out.data = 0;
+ out.h = h;
+ out.w = w;
+ out.c = c;
+ return out;
}
-}
-void hsv_to_rgb(image im)
-{
- assert(im.c == 3);
- int i, j;
- float r, g, b;
- float h, s, v;
- float f, p, q, t;
- for(j = 0; j < im.h; ++j){
- for(i = 0; i < im.w; ++i){
- h = get_pixel(im, i , j, 0);
- s = get_pixel(im, i , j, 1);
- v = get_pixel(im, i , j, 2);
- if (s == 0) {
- r = g = b = v;
- } else {
- int index = floor(h);
- f = h - index;
- p = v*(1-s);
- q = v*(1-s*f);
- t = v*(1-s*(1-f));
- if(index == 0){
- r = v; g = t; b = p;
- } else if(index == 1){
- r = q; g = v; b = p;
- } else if(index == 2){
- r = p; g = v; b = t;
- } else if(index == 3){
- r = p; g = q; b = v;
- } else if(index == 4){
- r = t; g = p; b = v;
- } else {
- r = v; g = p; b = q;
+ image make_image(int w, int h, int c)
+ {
+ image out = make_empty_image(w,h,c);
+ out.data = calloc(h*w*c, sizeof(float));
+ return out;
+ }
+
+ image float_to_image(int w, int h, int c, float *data)
+ {
+ image out = make_empty_image(w,h,c);
+ out.data = data;
+ return out;
+ }
+
+ image rotate_image(image im, float rad)
+ {
+ int x, y, c;
+ float cx = im.w/2.;
+ float cy = im.h/2.;
+ image rot = make_image(im.w, im.h, im.c);
+ for(c = 0; c < im.c; ++c){
+ for(y = 0; y < im.h; ++y){
+ for(x = 0; x < im.w; ++x){
+ float rx = cos(rad)*(x-cx) - sin(rad)*(y-cy) + cx;
+ float ry = sin(rad)*(x-cx) + cos(rad)*(y-cy) + cy;
+ float val = bilinear_interpolate(im, rx, ry, c);
+ set_pixel(rot, x, y, c, val);
}
}
- set_pixel(im, i, j, 0, r);
- set_pixel(im, i, j, 1, g);
- set_pixel(im, i, j, 2, b);
}
+ return rot;
}
-}
-image grayscale_image(image im)
-{
- assert(im.c == 3);
- int i, j, k;
- image gray = make_image(im.w, im.h, im.c);
- float scale[] = {0.587, 0.299, 0.114};
- for(k = 0; k < im.c; ++k){
+ void translate_image(image m, float s)
+ {
+ int i;
+ for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] += s;
+ }
+
+ void scale_image(image m, float s)
+ {
+ int i;
+ for(i = 0; i < m.h*m.w*m.c; ++i) m.data[i] *= s;
+ }
+
+ image crop_image(image im, int dx, int dy, int w, int h)
+ {
+ image cropped = make_image(w, h, im.c);
+ int i, j, k;
+ for(k = 0; k < im.c; ++k){
+ for(j = 0; j < h; ++j){
+ for(i = 0; i < w; ++i){
+ int r = j + dy;
+ int c = i + dx;
+ float val = 0;
+ if (r >= 0 && r < im.h && c >= 0 && c < im.w) {
+ val = get_pixel(im, c, r, k);
+ }
+ set_pixel(cropped, i, j, k, val);
+ }
+ }
+ }
+ return cropped;
+ }
+
+ float three_way_max(float a, float b, float c)
+ {
+ return (a > b) ? ( (a > c) ? a : c) : ( (b > c) ? b : c) ;
+ }
+
+ float three_way_min(float a, float b, float c)
+ {
+ return (a < b) ? ( (a < c) ? a : c) : ( (b < c) ? b : c) ;
+ }
+
+ // http://www.cs.rit.edu/~ncs/color/t_convert.html
+ void rgb_to_hsv(image im)
+ {
+ assert(im.c == 3);
+ int i, j;
+ float r, g, b;
+ float h, s, v;
for(j = 0; j < im.h; ++j){
for(i = 0; i < im.w; ++i){
- gray.data[i+im.w*j] += scale[k]*get_pixel(im, i, j, k);
- }
- }
- }
- memcpy(gray.data + im.w*im.h*1, gray.data, sizeof(float)*im.w*im.h);
- memcpy(gray.data + im.w*im.h*2, gray.data, sizeof(float)*im.w*im.h);
- return gray;
-}
-
-image blend_image(image fore, image back, float alpha)
-{
- assert(fore.w == back.w && fore.h == back.h && fore.c == back.c);
- image blend = make_image(fore.w, fore.h, fore.c);
- int i, j, k;
- for(k = 0; k < fore.c; ++k){
- for(j = 0; j < fore.h; ++j){
- for(i = 0; i < fore.w; ++i){
- float val = alpha * get_pixel(fore, i, j, k) +
- (1 - alpha)* get_pixel(back, i, j, k);
- set_pixel(blend, i, j, k, val);
- }
- }
- }
- return blend;
-}
-
-void scale_image_channel(image im, int c, float v)
-{
- int i, j;
- for(j = 0; j < im.h; ++j){
- for(i = 0; i < im.w; ++i){
- float pix = get_pixel(im, i, j, c);
- pix = pix*v;
- set_pixel(im, i, j, c, pix);
- }
- }
-}
-
-void saturate_image(image im, float sat)
-{
- rgb_to_hsv(im);
- scale_image_channel(im, 1, sat);
- hsv_to_rgb(im);
- constrain_image(im);
-}
-
-void exposure_image(image im, float sat)
-{
- rgb_to_hsv(im);
- scale_image_channel(im, 2, sat);
- hsv_to_rgb(im);
- constrain_image(im);
-}
-
-void saturate_exposure_image(image im, float sat, float exposure)
-{
- rgb_to_hsv(im);
- scale_image_channel(im, 1, sat);
- scale_image_channel(im, 2, exposure);
- hsv_to_rgb(im);
- constrain_image(im);
-}
-
-/*
- image saturate_image(image im, float sat)
- {
- image gray = grayscale_image(im);
- image blend = blend_image(im, gray, sat);
- free_image(gray);
- constrain_image(blend);
- return blend;
- }
-
- image brightness_image(image im, float b)
- {
- image bright = make_image(im.w, im.h, im.c);
- return bright;
- }
- */
-
-float bilinear_interpolate(image im, float x, float y, int c)
-{
- int ix = (int) floorf(x);
- int iy = (int) floorf(y);
-
- float dx = x - ix;
- float dy = y - iy;
-
- float val = (1-dy) * (1-dx) * get_pixel_extend(im, ix, iy, c) +
- dy * (1-dx) * get_pixel_extend(im, ix, iy+1, c) +
- (1-dy) * dx * get_pixel_extend(im, ix+1, iy, c) +
- dy * dx * get_pixel_extend(im, ix+1, iy+1, c);
- return val;
-}
-
-image resize_image(image im, int w, int h)
-{
- image resized = make_image(w, h, im.c);
- image part = make_image(w, im.h, im.c);
- int r, c, k;
- float w_scale = (float)(im.w - 1) / (w - 1);
- float h_scale = (float)(im.h - 1) / (h - 1);
- for(k = 0; k < im.c; ++k){
- for(r = 0; r < im.h; ++r){
- for(c = 0; c < w; ++c){
- float val = 0;
- if(c == w-1){
- val = get_pixel(im, im.w-1, r, k);
- } else {
- float sx = c*w_scale;
- int ix = (int) sx;
- float dx = sx - ix;
- val = (1 - dx) * get_pixel(im, ix, r, k) + dx * get_pixel(im, ix+1, r, k);
+ r = get_pixel(im, i , j, 0);
+ g = get_pixel(im, i , j, 1);
+ b = get_pixel(im, i , j, 2);
+ float max = three_way_max(r,g,b);
+ float min = three_way_min(r,g,b);
+ float delta = max - min;
+ v = max;
+ if(max == 0){
+ s = 0;
+ h = -1;
+ }else{
+ s = delta/max;
+ if(r == max){
+ h = (g - b) / delta;
+ } else if (g == max) {
+ h = 2 + (b - r) / delta;
+ } else {
+ h = 4 + (r - g) / delta;
+ }
+ if (h < 0) h += 6;
}
- set_pixel(part, c, r, k, val);
- }
- }
- }
- for(k = 0; k < im.c; ++k){
- for(r = 0; r < h; ++r){
- float sy = r*h_scale;
- int iy = (int) sy;
- float dy = sy - iy;
- for(c = 0; c < w; ++c){
- float val = (1-dy) * get_pixel(part, c, iy, k);
- set_pixel(resized, c, r, k, val);
- }
- if(r == h-1) continue;
- for(c = 0; c < w; ++c){
- float val = dy * get_pixel(part, c, iy+1, k);
- add_pixel(resized, c, r, k, val);
+ set_pixel(im, i, j, 0, h);
+ set_pixel(im, i, j, 1, s);
+ set_pixel(im, i, j, 2, v);
}
}
}
- free_image(part);
- return resized;
-}
+ void hsv_to_rgb(image im)
+ {
+ assert(im.c == 3);
+ int i, j;
+ float r, g, b;
+ float h, s, v;
+ float f, p, q, t;
+ for(j = 0; j < im.h; ++j){
+ for(i = 0; i < im.w; ++i){
+ h = get_pixel(im, i , j, 0);
+ s = get_pixel(im, i , j, 1);
+ v = get_pixel(im, i , j, 2);
+ if (s == 0) {
+ r = g = b = v;
+ } else {
+ int index = floor(h);
+ f = h - index;
+ p = v*(1-s);
+ q = v*(1-s*f);
+ t = v*(1-s*(1-f));
+ if(index == 0){
+ r = v; g = t; b = p;
+ } else if(index == 1){
+ r = q; g = v; b = p;
+ } else if(index == 2){
+ r = p; g = v; b = t;
+ } else if(index == 3){
+ r = p; g = q; b = v;
+ } else if(index == 4){
+ r = t; g = p; b = v;
+ } else {
+ r = v; g = p; b = q;
+ }
+ }
+ set_pixel(im, i, j, 0, r);
+ set_pixel(im, i, j, 1, g);
+ set_pixel(im, i, j, 2, b);
+ }
+ }
+ }
-void test_resize(char *filename)
-{
- image im = load_image(filename, 0,0, 3);
- image gray = grayscale_image(im);
+ image grayscale_image(image im)
+ {
+ assert(im.c == 3);
+ int i, j, k;
+ image gray = make_image(im.w, im.h, im.c);
+ float scale[] = {0.587, 0.299, 0.114};
+ for(k = 0; k < im.c; ++k){
+ for(j = 0; j < im.h; ++j){
+ for(i = 0; i < im.w; ++i){
+ gray.data[i+im.w*j] += scale[k]*get_pixel(im, i, j, k);
+ }
+ }
+ }
+ memcpy(gray.data + im.w*im.h*1, gray.data, sizeof(float)*im.w*im.h);
+ memcpy(gray.data + im.w*im.h*2, gray.data, sizeof(float)*im.w*im.h);
+ return gray;
+ }
- image sat2 = copy_image(im);
- saturate_image(sat2, 2);
+ image blend_image(image fore, image back, float alpha)
+ {
+ assert(fore.w == back.w && fore.h == back.h && fore.c == back.c);
+ image blend = make_image(fore.w, fore.h, fore.c);
+ int i, j, k;
+ for(k = 0; k < fore.c; ++k){
+ for(j = 0; j < fore.h; ++j){
+ for(i = 0; i < fore.w; ++i){
+ float val = alpha * get_pixel(fore, i, j, k) +
+ (1 - alpha)* get_pixel(back, i, j, k);
+ set_pixel(blend, i, j, k, val);
+ }
+ }
+ }
+ return blend;
+ }
- image sat5 = copy_image(im);
- saturate_image(sat5, .5);
+ void scale_image_channel(image im, int c, float v)
+ {
+ int i, j;
+ for(j = 0; j < im.h; ++j){
+ for(i = 0; i < im.w; ++i){
+ float pix = get_pixel(im, i, j, c);
+ pix = pix*v;
+ set_pixel(im, i, j, c, pix);
+ }
+ }
+ }
- image exp2 = copy_image(im);
- exposure_image(exp2, 2);
+ void saturate_image(image im, float sat)
+ {
+ rgb_to_hsv(im);
+ scale_image_channel(im, 1, sat);
+ hsv_to_rgb(im);
+ constrain_image(im);
+ }
- image exp5 = copy_image(im);
- exposure_image(exp5, .5);
+ void exposure_image(image im, float sat)
+ {
+ rgb_to_hsv(im);
+ scale_image_channel(im, 2, sat);
+ hsv_to_rgb(im);
+ constrain_image(im);
+ }
- show_image(im, "Original");
- show_image(gray, "Gray");
- show_image(sat2, "Saturation-2");
- show_image(sat5, "Saturation-.5");
- show_image(exp2, "Exposure-2");
- show_image(exp5, "Exposure-.5");
- #ifdef OPENCV
- cvWaitKey(0);
- #endif
-}
+ void saturate_exposure_image(image im, float sat, float exposure)
+ {
+ rgb_to_hsv(im);
+ scale_image_channel(im, 1, sat);
+ scale_image_channel(im, 2, exposure);
+ hsv_to_rgb(im);
+ constrain_image(im);
+ }
+
+ /*
+ image saturate_image(image im, float sat)
+ {
+ image gray = grayscale_image(im);
+ image blend = blend_image(im, gray, sat);
+ free_image(gray);
+ constrain_image(blend);
+ return blend;
+ }
+
+ image brightness_image(image im, float b)
+ {
+ image bright = make_image(im.w, im.h, im.c);
+ return bright;
+ }
+ */
+
+ float bilinear_interpolate(image im, float x, float y, int c)
+ {
+ int ix = (int) floorf(x);
+ int iy = (int) floorf(y);
+
+ float dx = x - ix;
+ float dy = y - iy;
+
+ float val = (1-dy) * (1-dx) * get_pixel_extend(im, ix, iy, c) +
+ dy * (1-dx) * get_pixel_extend(im, ix, iy+1, c) +
+ (1-dy) * dx * get_pixel_extend(im, ix+1, iy, c) +
+ dy * dx * get_pixel_extend(im, ix+1, iy+1, c);
+ return val;
+ }
+
+ image resize_image(image im, int w, int h)
+ {
+ image resized = make_image(w, h, im.c);
+ image part = make_image(w, im.h, im.c);
+ int r, c, k;
+ float w_scale = (float)(im.w - 1) / (w - 1);
+ float h_scale = (float)(im.h - 1) / (h - 1);
+ for(k = 0; k < im.c; ++k){
+ for(r = 0; r < im.h; ++r){
+ for(c = 0; c < w; ++c){
+ float val = 0;
+ if(c == w-1){
+ val = get_pixel(im, im.w-1, r, k);
+ } else {
+ float sx = c*w_scale;
+ int ix = (int) sx;
+ float dx = sx - ix;
+ val = (1 - dx) * get_pixel(im, ix, r, k) + dx * get_pixel(im, ix+1, r, k);
+ }
+ set_pixel(part, c, r, k, val);
+ }
+ }
+ }
+ for(k = 0; k < im.c; ++k){
+ for(r = 0; r < h; ++r){
+ float sy = r*h_scale;
+ int iy = (int) sy;
+ float dy = sy - iy;
+ for(c = 0; c < w; ++c){
+ float val = (1-dy) * get_pixel(part, c, iy, k);
+ set_pixel(resized, c, r, k, val);
+ }
+ if(r == h-1) continue;
+ for(c = 0; c < w; ++c){
+ float val = dy * get_pixel(part, c, iy+1, k);
+ add_pixel(resized, c, r, k, val);
+ }
+ }
+ }
+
+ free_image(part);
+ return resized;
+ }
+
+ void test_resize(char *filename)
+ {
+ image im = load_image(filename, 0,0, 3);
+ image gray = grayscale_image(im);
+
+ image sat2 = copy_image(im);
+ saturate_image(sat2, 2);
+
+ image sat5 = copy_image(im);
+ saturate_image(sat5, .5);
+
+ image exp2 = copy_image(im);
+ exposure_image(exp2, 2);
+
+ image exp5 = copy_image(im);
+ exposure_image(exp5, .5);
+
+ show_image(im, "Original");
+ show_image(gray, "Gray");
+ show_image(sat2, "Saturation-2");
+ show_image(sat5, "Saturation-.5");
+ show_image(exp2, "Exposure-2");
+ show_image(exp5, "Exposure-.5");
+#ifdef OPENCV
+ cvWaitKey(0);
+#endif
+ }
#ifdef OPENCV
-image ipl_to_image(IplImage* src)
-{
- unsigned char *data = (unsigned char *)src->imageData;
- int h = src->height;
- int w = src->width;
- int c = src->nChannels;
- int step = src->widthStep;
- image out = make_image(w, h, c);
- int i, j, k, count=0;;
+ image ipl_to_image(IplImage* src)
+ {
+ unsigned char *data = (unsigned char *)src->imageData;
+ int h = src->height;
+ int w = src->width;
+ int c = src->nChannels;
+ int step = src->widthStep;
+ image out = make_image(w, h, c);
+ int i, j, k, count=0;;
- for(k= 0; k < c; ++k){
- for(i = 0; i < h; ++i){
- for(j = 0; j < w; ++j){
- out.data[count++] = data[i*step + j*c + k]/255.;
+ for(k= 0; k < c; ++k){
+ for(i = 0; i < h; ++i){
+ for(j = 0; j < w; ++j){
+ out.data[count++] = data[i*step + j*c + k]/255.;
+ }
}
}
+ return out;
}
- return out;
-}
-image load_image_cv(char *filename, int channels)
-{
- IplImage* src = 0;
- int flag = -1;
- if (channels == 0) flag = -1;
- else if (channels == 1) flag = 0;
- else if (channels == 3) flag = 1;
- else {
- fprintf(stderr, "OpenCV can't force load with %d channels\n", channels);
- }
-
- if( (src = cvLoadImage(filename, flag)) == 0 )
+ image load_image_cv(char *filename, int channels)
{
- printf("Cannot load file image %s\n", filename);
- exit(0);
+ IplImage* src = 0;
+ int flag = -1;
+ if (channels == 0) flag = -1;
+ else if (channels == 1) flag = 0;
+ else if (channels == 3) flag = 1;
+ else {
+ fprintf(stderr, "OpenCV can't force load with %d channels\n", channels);
+ }
+
+ if( (src = cvLoadImage(filename, flag)) == 0 )
+ {
+ printf("Cannot load file image %s\n", filename);
+ exit(0);
+ }
+ image out = ipl_to_image(src);
+ cvReleaseImage(&src);
+ rgbgr_image(out);
+ return out;
}
- image out = ipl_to_image(src);
- cvReleaseImage(&src);
- rgbgr_image(out);
- return out;
-}
#endif
-image load_image_stb(char *filename, int channels)
-{
- int w, h, c;
- unsigned char *data = stbi_load(filename, &w, &h, &c, channels);
- if (!data) {
- fprintf(stderr, "Cannot load file image %s\nSTB Reason: %s\n", filename, stbi_failure_reason());
- exit(0);
- }
- if(channels) c = channels;
- int i,j,k;
- image im = make_image(w, h, c);
- for(k = 0; k < c; ++k){
- for(j = 0; j < h; ++j){
- for(i = 0; i < w; ++i){
- int dst_index = i + w*j + w*h*k;
- int src_index = k + c*i + c*w*j;
- im.data[dst_index] = (float)data[src_index]/255.;
+ image load_image_stb(char *filename, int channels)
+ {
+ int w, h, c;
+ unsigned char *data = stbi_load(filename, &w, &h, &c, channels);
+ if (!data) {
+ fprintf(stderr, "Cannot load file image %s\nSTB Reason: %s\n", filename, stbi_failure_reason());
+ exit(0);
+ }
+ if(channels) c = channels;
+ int i,j,k;
+ image im = make_image(w, h, c);
+ for(k = 0; k < c; ++k){
+ for(j = 0; j < h; ++j){
+ for(i = 0; i < w; ++i){
+ int dst_index = i + w*j + w*h*k;
+ int src_index = k + c*i + c*w*j;
+ im.data[dst_index] = (float)data[src_index]/255.;
+ }
}
}
+ free(data);
+ return im;
}
- free(data);
- return im;
-}
-image load_image(char *filename, int w, int h, int c)
-{
- #ifdef OPENCV
- image out = load_image_cv(filename, c);
- #else
- image out = load_image_stb(filename, c);
- #endif
+ image load_image(char *filename, int w, int h, int c)
+ {
+#ifdef OPENCV
+ image out = load_image_cv(filename, c);
+#else
+ image out = load_image_stb(filename, c);
+#endif
- if((h && w) && (h != out.h || w != out.w)){
- image resized = resize_image(out, w, h);
- free_image(out);
- out = resized;
+ if((h && w) && (h != out.h || w != out.w)){
+ image resized = resize_image(out, w, h);
+ free_image(out);
+ out = resized;
+ }
+ return out;
}
- return out;
-}
-image load_image_color(char *filename, int w, int h)
-{
- return load_image(filename, w, h, 3);
-}
-
-image get_image_layer(image m, int l)
-{
- image out = make_image(m.w, m.h, 1);
- int i;
- for(i = 0; i < m.h*m.w; ++i){
- out.data[i] = m.data[i+l*m.h*m.w];
+ image load_image_color(char *filename, int w, int h)
+ {
+ return load_image(filename, w, h, 3);
}
- return out;
-}
-float get_pixel(image m, int x, int y, int c)
-{
- assert(x < m.w && y < m.h && c < m.c);
- return m.data[c*m.h*m.w + y*m.w + x];
-}
-float get_pixel_extend(image m, int x, int y, int c)
-{
- if(x < 0 || x >= m.w || y < 0 || y >= m.h || c < 0 || c >= m.c) return 0;
- return get_pixel(m, x, y, c);
-}
-void set_pixel(image m, int x, int y, int c, float val)
-{
- assert(x < m.w && y < m.h && c < m.c);
- m.data[c*m.h*m.w + y*m.w + x] = val;
-}
-void add_pixel(image m, int x, int y, int c, float val)
-{
- assert(x < m.w && y < m.h && c < m.c);
- m.data[c*m.h*m.w + y*m.w + x] += val;
-}
+ image get_image_layer(image m, int l)
+ {
+ image out = make_image(m.w, m.h, 1);
+ int i;
+ for(i = 0; i < m.h*m.w; ++i){
+ out.data[i] = m.data[i+l*m.h*m.w];
+ }
+ return out;
+ }
-void print_image(image m)
-{
- int i, j, k;
- for(i =0 ; i < m.c; ++i){
- for(j =0 ; j < m.h; ++j){
- for(k = 0; k < m.w; ++k){
- printf("%.2lf, ", m.data[i*m.h*m.w + j*m.w + k]);
- if(k > 30) break;
+ float get_pixel(image m, int x, int y, int c)
+ {
+ assert(x < m.w && y < m.h && c < m.c);
+ return m.data[c*m.h*m.w + y*m.w + x];
+ }
+ float get_pixel_extend(image m, int x, int y, int c)
+ {
+ if(x < 0 || x >= m.w || y < 0 || y >= m.h || c < 0 || c >= m.c) return 0;
+ return get_pixel(m, x, y, c);
+ }
+ void set_pixel(image m, int x, int y, int c, float val)
+ {
+ assert(x < m.w && y < m.h && c < m.c);
+ m.data[c*m.h*m.w + y*m.w + x] = val;
+ }
+ void add_pixel(image m, int x, int y, int c, float val)
+ {
+ assert(x < m.w && y < m.h && c < m.c);
+ m.data[c*m.h*m.w + y*m.w + x] += val;
+ }
+
+ void print_image(image m)
+ {
+ int i, j, k;
+ for(i =0 ; i < m.c; ++i){
+ for(j =0 ; j < m.h; ++j){
+ for(k = 0; k < m.w; ++k){
+ printf("%.2lf, ", m.data[i*m.h*m.w + j*m.w + k]);
+ if(k > 30) break;
+ }
+ printf("\n");
+ if(j > 30) break;
}
printf("\n");
- if(j > 30) break;
}
printf("\n");
}
- printf("\n");
-}
-image collapse_images_vert(image *ims, int n)
-{
- int color = 1;
- int border = 1;
- int h,w,c;
- w = ims[0].w;
- h = (ims[0].h + border) * n - border;
- c = ims[0].c;
- if(c != 3 || !color){
- w = (w+border)*c - border;
- c = 1;
- }
-
- image filters = make_image(w, h, c);
- int i,j;
- for(i = 0; i < n; ++i){
- int h_offset = i*(ims[0].h+border);
- image copy = copy_image(ims[i]);
- //normalize_image(copy);
- if(c == 3 && color){
- embed_image(copy, filters, 0, h_offset);
+ image collapse_images_vert(image *ims, int n)
+ {
+ int color = 1;
+ int border = 1;
+ int h,w,c;
+ w = ims[0].w;
+ h = (ims[0].h + border) * n - border;
+ c = ims[0].c;
+ if(c != 3 || !color){
+ w = (w+border)*c - border;
+ c = 1;
}
- else{
- for(j = 0; j < copy.c; ++j){
- int w_offset = j*(ims[0].w+border);
- image layer = get_image_layer(copy, j);
- embed_image(layer, filters, w_offset, h_offset);
- free_image(layer);
+
+ image filters = make_image(w, h, c);
+ int i,j;
+ for(i = 0; i < n; ++i){
+ int h_offset = i*(ims[0].h+border);
+ image copy = copy_image(ims[i]);
+ //normalize_image(copy);
+ if(c == 3 && color){
+ embed_image(copy, filters, 0, h_offset);
}
- }
- free_image(copy);
- }
- return filters;
-}
-
-image collapse_images_horz(image *ims, int n)
-{
- int color = 1;
- int border = 1;
- int h,w,c;
- int size = ims[0].h;
- h = size;
- w = (ims[0].w + border) * n - border;
- c = ims[0].c;
- if(c != 3 || !color){
- h = (h+border)*c - border;
- c = 1;
- }
-
- image filters = make_image(w, h, c);
- int i,j;
- for(i = 0; i < n; ++i){
- int w_offset = i*(size+border);
- image copy = copy_image(ims[i]);
- //normalize_image(copy);
- if(c == 3 && color){
- embed_image(copy, filters, w_offset, 0);
- }
- else{
- for(j = 0; j < copy.c; ++j){
- int h_offset = j*(size+border);
- image layer = get_image_layer(copy, j);
- embed_image(layer, filters, w_offset, h_offset);
- free_image(layer);
+ else{
+ for(j = 0; j < copy.c; ++j){
+ int w_offset = j*(ims[0].w+border);
+ image layer = get_image_layer(copy, j);
+ embed_image(layer, filters, w_offset, h_offset);
+ free_image(layer);
+ }
}
+ free_image(copy);
}
- free_image(copy);
- }
- return filters;
-}
+ return filters;
+ }
-void show_images(image *ims, int n, char *window)
-{
- image m = collapse_images_vert(ims, n);
- int w = 448;
- int h = ((float)m.h/m.w) * 448;
- if(h > 896){
- h = 896;
- w = ((float)m.w/m.h) * 896;
- }
- image sized = resize_image(m, w, h);
- save_image(sized, window);
- show_image(sized, window);
- free_image(sized);
- free_image(m);
-}
+ image collapse_images_horz(image *ims, int n)
+ {
+ int color = 1;
+ int border = 1;
+ int h,w,c;
+ int size = ims[0].h;
+ h = size;
+ w = (ims[0].w + border) * n - border;
+ c = ims[0].c;
+ if(c != 3 || !color){
+ h = (h+border)*c - border;
+ c = 1;
+ }
-void free_image(image m)
-{
- free(m.data);
-}
+ image filters = make_image(w, h, c);
+ int i,j;
+ for(i = 0; i < n; ++i){
+ int w_offset = i*(size+border);
+ image copy = copy_image(ims[i]);
+ //normalize_image(copy);
+ if(c == 3 && color){
+ embed_image(copy, filters, w_offset, 0);
+ }
+ else{
+ for(j = 0; j < copy.c; ++j){
+ int h_offset = j*(size+border);
+ image layer = get_image_layer(copy, j);
+ embed_image(layer, filters, w_offset, h_offset);
+ free_image(layer);
+ }
+ }
+ free_image(copy);
+ }
+ return filters;
+ }
+
+ void show_images(image *ims, int n, char *window)
+ {
+ image m = collapse_images_vert(ims, n);
+ int w = 448;
+ int h = ((float)m.h/m.w) * 448;
+ if(h > 896){
+ h = 896;
+ w = ((float)m.w/m.h) * 896;
+ }
+ image sized = resize_image(m, w, h);
+ save_image(sized, window);
+ show_image(sized, window);
+ free_image(sized);
+ free_image(m);
+ }
+
+ void free_image(image m)
+ {
+ free(m.data);
+ }
diff --git a/src/image.h b/src/image.h
index b635ff1..f8577cd 100644
--- a/src/image.h
+++ b/src/image.h
@@ -6,6 +6,7 @@
#include <float.h>
#include <string.h>
#include <math.h>
+#include "box.h"
typedef struct {
int h;
@@ -18,6 +19,7 @@
void flip_image(image a);
void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b);
void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b);
+void draw_bbox(image a, box bbox, int w, float r, float g, float b);
image image_distance(image a, image b);
void scale_image(image m, float s);
image crop_image(image im, int dx, int dy, int w, int h);
diff --git a/src/imagenet.c b/src/imagenet.c
index aeb7e69..fb57307 100644
--- a/src/imagenet.c
+++ b/src/imagenet.c
@@ -30,7 +30,19 @@
pthread_t load_thread;
data train;
data buffer;
- load_thread = load_data_thread(paths, imgs, plist->size, labels, 1000, net.w, net.h, &buffer);
+
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.paths = paths;
+ args.classes = 1000;
+ args.n = imgs;
+ args.m = plist->size;
+ args.labels = labels;
+ args.d = &buffer;
+ args.type = CLASSIFICATION_DATA;
+
+ load_thread = load_data_in_thread(args);
while(1){
++i;
time=clock();
@@ -43,7 +55,7 @@
cvWaitKey(0);
*/
- load_thread = load_data_thread(paths, imgs, plist->size, labels, 1000, net.w, net.h, &buffer);
+ load_thread = load_data_in_thread(args);
printf("Loaded: %lf seconds\n", sec(clock()-time));
time=clock();
float loss = train_network(net, train);
@@ -84,7 +96,19 @@
int num = (i+1)*m/splits - i*m/splits;
data val, buffer;
- pthread_t load_thread = load_data_thread(paths, num, 0, labels, 1000, 256, 256, &buffer);
+
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.paths = paths;
+ args.classes = 1000;
+ args.n = num;
+ args.m = 0;
+ args.labels = labels;
+ args.d = &buffer;
+ args.type = CLASSIFICATION_DATA;
+
+ pthread_t load_thread = load_data_in_thread(args);
for(i = 1; i <= splits; ++i){
time=clock();
@@ -93,7 +117,10 @@
num = (i+1)*m/splits - i*m/splits;
char **part = paths+(i*m/splits);
- if(i != splits) load_thread = load_data_thread(part, num, 0, labels, 1000, 256, 256, &buffer);
+ if(i != splits){
+ args.paths = part;
+ load_thread = load_data_in_thread(args);
+ }
printf("Loaded: %d images in %lf seconds\n", val.X.rows, sec(clock()-time));
time=clock();
diff --git a/src/layer.h b/src/layer.h
index 29abec0..4cd9f28 100644
--- a/src/layer.h
+++ b/src/layer.h
@@ -15,6 +15,7 @@
ROUTE,
COST,
NORMALIZATION,
+ REGION,
AVGPOOL
} LAYER_TYPE;
diff --git a/src/network.c b/src/network.c
index ff5cd61..de3e569 100644
--- a/src/network.c
+++ b/src/network.c
@@ -11,6 +11,7 @@
#include "convolutional_layer.h"
#include "deconvolutional_layer.h"
#include "detection_layer.h"
+#include "region_layer.h"
#include "normalization_layer.h"
#include "maxpool_layer.h"
#include "avgpool_layer.h"
@@ -36,6 +37,8 @@
return "softmax";
case DETECTION:
return "detection";
+ case REGION:
+ return "region";
case DROPOUT:
return "dropout";
case CROP:
@@ -80,6 +83,8 @@
forward_normalization_layer(l, state);
} else if(l.type == DETECTION){
forward_detection_layer(l, state);
+ } else if(l.type == REGION){
+ forward_region_layer(l, state);
} else if(l.type == CONNECTED){
forward_connected_layer(l, state);
} else if(l.type == CROP){
@@ -130,12 +135,16 @@
float sum = 0;
int count = 0;
for(i = 0; i < net.n; ++i){
- if(net.layers[net.n-1].type == COST){
- sum += net.layers[net.n-1].output[0];
+ if(net.layers[i].type == COST){
+ sum += net.layers[i].output[0];
++count;
}
- if(net.layers[net.n-1].type == DETECTION){
- sum += net.layers[net.n-1].cost[0];
+ if(net.layers[i].type == DETECTION){
+ sum += net.layers[i].cost[0];
+ ++count;
+ }
+ if(net.layers[i].type == REGION){
+ sum += net.layers[i].cost[0];
++count;
}
}
@@ -178,6 +187,8 @@
backward_dropout_layer(l, state);
} else if(l.type == DETECTION){
backward_detection_layer(l, state);
+ } else if(l.type == REGION){
+ backward_region_layer(l, state);
} else if(l.type == SOFTMAX){
if(i != 0) backward_softmax_layer(l, state);
} else if(l.type == CONNECTED){
diff --git a/src/network_kernels.cu b/src/network_kernels.cu
index 3340afa..593de0a 100644
--- a/src/network_kernels.cu
+++ b/src/network_kernels.cu
@@ -12,6 +12,7 @@
#include "crop_layer.h"
#include "connected_layer.h"
#include "detection_layer.h"
+#include "region_layer.h"
#include "convolutional_layer.h"
#include "deconvolutional_layer.h"
#include "maxpool_layer.h"
@@ -42,6 +43,8 @@
forward_deconvolutional_layer_gpu(l, state);
} else if(l.type == DETECTION){
forward_detection_layer_gpu(l, state);
+ } else if(l.type == REGION){
+ forward_region_layer_gpu(l, state);
} else if(l.type == CONNECTED){
forward_connected_layer_gpu(l, state);
} else if(l.type == CROP){
@@ -92,6 +95,8 @@
backward_dropout_layer_gpu(l, state);
} else if(l.type == DETECTION){
backward_detection_layer_gpu(l, state);
+ } else if(l.type == REGION){
+ backward_region_layer_gpu(l, state);
} else if(l.type == NORMALIZATION){
backward_normalization_layer_gpu(l, state);
} else if(l.type == SOFTMAX){
diff --git a/src/parser.c b/src/parser.c
index b373c01..242a83c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -14,6 +14,7 @@
#include "softmax_layer.h"
#include "dropout_layer.h"
#include "detection_layer.h"
+#include "region_layer.h"
#include "avgpool_layer.h"
#include "route_layer.h"
#include "list.h"
@@ -37,6 +38,7 @@
int is_crop(section *s);
int is_cost(section *s);
int is_detection(section *s);
+int is_region(section *s);
int is_route(section *s);
list *read_cfg(char *filename);
@@ -172,6 +174,16 @@
return layer;
}
+region_layer parse_region(list *options, size_params params)
+{
+ int coords = option_find_int(options, "coords", 1);
+ int classes = option_find_int(options, "classes", 1);
+ int rescore = option_find_int(options, "rescore", 0);
+ int num = option_find_int(options, "num", 1);
+ region_layer layer = make_region_layer(params.batch, params.inputs, num, classes, coords, rescore);
+ return layer;
+}
+
cost_layer parse_cost(list *options, size_params params)
{
char *type_s = option_find_str(options, "type", "sse");
@@ -347,6 +359,8 @@
l = parse_cost(options, params);
}else if(is_detection(s)){
l = parse_detection(options, params);
+ }else if(is_region(s)){
+ l = parse_region(options, params);
}else if(is_softmax(s)){
l = parse_softmax(options, params);
}else if(is_normalization(s)){
@@ -399,6 +413,10 @@
{
return (strcmp(s->type, "[detection]")==0);
}
+int is_region(section *s)
+{
+ return (strcmp(s->type, "[region]")==0);
+}
int is_deconvolutional(section *s)
{
return (strcmp(s->type, "[deconv]")==0
diff --git a/src/region_layer.c b/src/region_layer.c
new file mode 100644
index 0000000..7c34b5c
--- /dev/null
+++ b/src/region_layer.c
@@ -0,0 +1,161 @@
+#include "region_layer.h"
+#include "activations.h"
+#include "softmax_layer.h"
+#include "blas.h"
+#include "box.h"
+#include "cuda.h"
+#include "utils.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int get_region_layer_locations(region_layer l)
+{
+ return l.inputs / (l.classes+l.coords);
+}
+
+region_layer make_region_layer(int batch, int inputs, int n, int classes, int coords, int rescore)
+{
+ region_layer l = {0};
+ l.type = REGION;
+
+ l.n = n;
+ l.batch = batch;
+ l.inputs = inputs;
+ l.classes = classes;
+ l.coords = coords;
+ l.rescore = rescore;
+ l.cost = calloc(1, sizeof(float));
+ int outputs = inputs;
+ l.outputs = outputs;
+ l.output = calloc(batch*outputs, sizeof(float));
+ l.delta = calloc(batch*outputs, sizeof(float));
+ #ifdef GPU
+ l.output_gpu = cuda_make_array(0, batch*outputs);
+ l.delta_gpu = cuda_make_array(0, batch*outputs);
+ #endif
+
+ fprintf(stderr, "Region Layer\n");
+ srand(0);
+
+ return l;
+}
+
+void forward_region_layer(const region_layer l, network_state state)
+{
+ int locations = get_region_layer_locations(l);
+ int i,j;
+ for(i = 0; i < l.batch*locations; ++i){
+ int index = i*(l.classes + l.coords);
+ int mask = (!state.truth || !state.truth[index]);
+
+ for(j = 0; j < l.classes; ++j){
+ l.output[index+j] = state.input[index+j];
+ }
+
+ softmax_array(l.output + index, l.classes, l.output + index);
+ index += l.classes;
+
+ for(j = 0; j < l.coords; ++j){
+ l.output[index+j] = mask*state.input[index+j];
+ }
+ }
+ if(state.train){
+ float avg_iou = 0;
+ int count = 0;
+ *(l.cost) = 0;
+ int size = l.outputs * l.batch;
+ memset(l.delta, 0, size * sizeof(float));
+ for (i = 0; i < l.batch*locations; ++i) {
+ int offset = i*(l.classes+l.coords);
+ int bg = state.truth[offset];
+ for (j = offset; j < offset+l.classes; ++j) {
+ //*(l.cost) += pow(state.truth[j] - l.output[j], 2);
+ //l.delta[j] = state.truth[j] - l.output[j];
+ }
+
+ box anchor = {0,0,.5,.5};
+ box truth_code = {state.truth[j+0], state.truth[j+1], state.truth[j+2], state.truth[j+3]};
+ box out_code = {l.output[j+0], l.output[j+1], l.output[j+2], l.output[j+3]};
+ box out = decode_box(out_code, anchor);
+ box truth = decode_box(truth_code, anchor);
+
+ if(bg) continue;
+ //printf("Box: %f %f %f %f\n", truth.x, truth.y, truth.w, truth.h);
+ //printf("Code: %f %f %f %f\n", truth_code.x, truth_code.y, truth_code.w, truth_code.h);
+ //printf("Pred : %f %f %f %f\n", out.x, out.y, out.w, out.h);
+ // printf("Pred Code: %f %f %f %f\n", out_code.x, out_code.y, out_code.w, out_code.h);
+ float iou = box_iou(out, truth);
+ avg_iou += iou;
+ ++count;
+
+ /*
+ *(l.cost) += pow((1-iou), 2);
+ l.delta[j+0] = (state.truth[j+0] - l.output[j+0]);
+ l.delta[j+1] = (state.truth[j+1] - l.output[j+1]);
+ l.delta[j+2] = (state.truth[j+2] - l.output[j+2]);
+ l.delta[j+3] = (state.truth[j+3] - l.output[j+3]);
+ */
+
+ for (j = offset+l.classes; j < offset+l.classes+l.coords; ++j) {
+ //*(l.cost) += pow(state.truth[j] - l.output[j], 2);
+ //l.delta[j] = state.truth[j] - l.output[j];
+ float diff = state.truth[j] - l.output[j];
+ if (fabs(diff) < 1){
+ l.delta[j] = diff;
+ *(l.cost) += .5*pow(state.truth[j] - l.output[j], 2);
+ } else {
+ l.delta[j] = (diff > 0) ? 1 : -1;
+ *(l.cost) += fabs(diff) - .5;
+ }
+ //l.delta[j] = state.truth[j] - l.output[j];
+ }
+
+ /*
+ if(l.rescore){
+ for (j = offset; j < offset+l.classes; ++j) {
+ if(state.truth[j]) state.truth[j] = iou;
+ l.delta[j] = state.truth[j] - l.output[j];
+ }
+ }
+ */
+ }
+ printf("Avg IOU: %f\n", avg_iou/count);
+ }
+}
+
+void backward_region_layer(const region_layer l, network_state state)
+{
+ axpy_cpu(l.batch*l.inputs, 1, l.delta_gpu, 1, state.delta, 1);
+ //copy_cpu(l.batch*l.inputs, l.delta_gpu, 1, state.delta, 1);
+}
+
+#ifdef GPU
+
+void forward_region_layer_gpu(const region_layer l, network_state state)
+{
+ float *in_cpu = calloc(l.batch*l.inputs, sizeof(float));
+ float *truth_cpu = 0;
+ if(state.truth){
+ truth_cpu = calloc(l.batch*l.outputs, sizeof(float));
+ cuda_pull_array(state.truth, truth_cpu, l.batch*l.outputs);
+ }
+ cuda_pull_array(state.input, in_cpu, l.batch*l.inputs);
+ network_state cpu_state;
+ cpu_state.train = state.train;
+ cpu_state.truth = truth_cpu;
+ cpu_state.input = in_cpu;
+ forward_region_layer(l, cpu_state);
+ cuda_push_array(l.output_gpu, l.output, l.batch*l.outputs);
+ cuda_push_array(l.delta_gpu, l.delta, l.batch*l.outputs);
+ free(cpu_state.input);
+ if(cpu_state.truth) free(cpu_state.truth);
+}
+
+void backward_region_layer_gpu(region_layer l, network_state state)
+{
+ axpy_ongpu(l.batch*l.inputs, 1, l.delta_gpu, 1, state.delta, 1);
+ //copy_ongpu(l.batch*l.inputs, l.delta_gpu, 1, state.delta, 1);
+}
+#endif
+
diff --git a/src/region_layer.h b/src/region_layer.h
new file mode 100644
index 0000000..00fbeba
--- /dev/null
+++ b/src/region_layer.h
@@ -0,0 +1,18 @@
+#ifndef REGION_LAYER_H
+#define REGION_LAYER_H
+
+#include "params.h"
+#include "layer.h"
+
+typedef layer region_layer;
+
+region_layer make_region_layer(int batch, int inputs, int n, int classes, int coords, int rescore);
+void forward_region_layer(const region_layer l, network_state state);
+void backward_region_layer(const region_layer l, network_state state);
+
+#ifdef GPU
+void forward_region_layer_gpu(const region_layer l, network_state state);
+void backward_region_layer_gpu(region_layer l, network_state state);
+#endif
+
+#endif
diff --git a/src/yolo.c b/src/yolo.c
index 5ad9534..13f0824 100644
--- a/src/yolo.c
+++ b/src/yolo.c
@@ -88,14 +88,26 @@
int background = layer.objectness;
int side = sqrt(get_detection_layer_locations(layer));
- pthread_t load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.paths = paths;
+ args.n = imgs;
+ args.m = plist->size;
+ args.classes = classes;
+ args.num_boxes = side;
+ args.background = background;
+ args.d = &buffer;
+ args.type = DETECTION_DATA;
+
+ pthread_t load_thread = load_data_in_thread(args);
clock_t time;
while(i*imgs < N*130){
i += 1;
time=clock();
pthread_join(load_thread, 0);
train = buffer;
- load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
+ load_thread = load_data_in_thread(args);
printf("Loaded: %lf seconds\n", sec(clock()-time));
time=clock();
@@ -126,7 +138,7 @@
pthread_join(load_thread, 0);
free_data(buffer);
- load_thread = load_data_detection_thread(imgs, paths, plist->size, classes, net.w, net.h, side, side, background, &buffer);
+ load_thread = load_data_in_thread(args);
}
if((i-1)*imgs <= 120*N && i*imgs > N*120){
@@ -237,8 +249,17 @@
image *buf = calloc(nthreads, sizeof(image));
image *buf_resized = calloc(nthreads, sizeof(image));
pthread_t *thr = calloc(nthreads, sizeof(pthread_t));
+
+ load_args args = {0};
+ args.w = net.w;
+ args.h = net.h;
+ args.type = IMAGE_DATA;
+
for(t = 0; t < nthreads; ++t){
- thr[t] = load_image_thread(paths[i+t], &buf[t], &buf_resized[t], net.w, net.h);
+ args.path = paths[i+t];
+ args.im = &buf[t];
+ args.resized = &buf_resized[t];
+ thr[t] = load_data_in_thread(args);
}
time_t start = time(0);
for(i = nthreads; i < m+nthreads; i += nthreads){
@@ -249,7 +270,10 @@
val_resized[t] = buf_resized[t];
}
for(t = 0; t < nthreads && i+t < m; ++t){
- thr[t] = load_image_thread(paths[i+t], &buf[t], &buf_resized[t], net.w, net.h);
+ args.path = paths[i+t];
+ args.im = &buf[t];
+ args.resized = &buf_resized[t];
+ thr[t] = load_data_in_thread(args);
}
for(t = 0; t < nthreads && i+t-nthreads < m; ++t){
char *path = paths[i+t-nthreads];
--
Gitblit v1.10.0