diff --git a/Makefile b/Makefile index a1e4604f..63e15e65 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ EXEC=darknet OBJDIR=./obj/ CC=gcc +CPP=g++ NVCC=nvcc AR=ar ARFLAGS=rcs @@ -41,7 +42,7 @@ CFLAGS+=$(OPTS) ifeq ($(OPENCV), 1) COMMON+= -DOPENCV CFLAGS+= -DOPENCV -LDFLAGS+= `pkg-config --libs opencv` +LDFLAGS+= `pkg-config --libs opencv` -lstdc++ COMMON+= `pkg-config --cflags opencv` endif @@ -57,7 +58,7 @@ CFLAGS+= -DCUDNN LDFLAGS+= -lcudnn 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 detection_layer.o route_layer.o upsample_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o logistic_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o l2norm_layer.o yolo_layer.o iseg_layer.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 detection_layer.o route_layer.o upsample_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o logistic_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o lstm_layer.o l2norm_layer.o yolo_layer.o iseg_layer.o image_opencv.o EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o instance-segmenter.o darknet.o ifeq ($(GPU), 1) LDFLAGS+= -lstdc++ @@ -81,6 +82,9 @@ $(ALIB): $(OBJS) $(SLIB): $(OBJS) $(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS) +$(OBJDIR)%.o: %.cpp $(DEPS) + $(CPP) $(COMMON) $(CFLAGS) -c $< -o $@ + $(OBJDIR)%.o: %.c $(DEPS) $(CC) $(COMMON) $(CFLAGS) -c $< -o $@ diff --git a/examples/art.c b/examples/art.c index ce885540..932688e7 100644 --- a/examples/art.c +++ b/examples/art.c @@ -9,14 +9,11 @@ void demo_art(char *cfgfile, char *weightfile, int cam_index) set_batch_network(net, 1); srand(2222222); - CvCapture * cap; - cap = cvCaptureFromCAM(cam_index); + void * cap = open_video_stream(0, cam_index, 0,0,0); char *window = "ArtJudgementBot9000!!!"; if(!cap) error("Couldn't connect to webcam.\n"); - cvNamedWindow(window, CV_WINDOW_NORMAL); - cvResizeWindow(window, 512, 512); int i; int idx[] = {37, 401, 434}; int n = sizeof(idx)/sizeof(idx[0]); diff --git a/examples/cifar.c b/examples/cifar.c index d57d7fdc..a5f5f240 100644 --- a/examples/cifar.c +++ b/examples/cifar.c @@ -157,14 +157,14 @@ char *labels[] = {"airplane","automobile","bird","cat","deer","dog","frog","hors int class = max_index(train.y.vals[i], 10); char buff[256]; sprintf(buff, "data/cifar/train/%d_%s",i,labels[class]); - save_image_png(im, buff); + save_image_options(im, buff, PNG, 0); } for(i = 0; i < test.X.rows; ++i){ image im = float_to_image(32, 32, 3, test.X.vals[i]); int class = max_index(test.y.vals[i], 10); char buff[256]; sprintf(buff, "data/cifar/test/%d_%s",i,labels[class]); - save_image_png(im, buff); + save_image_options(im, buff, PNG, 0); } } diff --git a/examples/classifier.c b/examples/classifier.c index 90cd3abc..df91a084 100644 --- a/examples/classifier.c +++ b/examples/classifier.c @@ -806,13 +806,7 @@ void threat_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_i list *options = read_data_cfg(datacfg); srand(2222222); - CvCapture * cap; - - if(filename){ - cap = cvCaptureFromFile(filename); - }else{ - cap = cvCaptureFromCAM(cam_index); - } + void * cap = open_video_stream(filename, cam_index, 0,0,0); int top = option_find_int(options, "top", 1); @@ -934,13 +928,7 @@ void gun_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_inde list *options = read_data_cfg(datacfg); srand(2222222); - CvCapture * cap; - - if(filename){ - cap = cvCaptureFromFile(filename); - }else{ - cap = cvCaptureFromCAM(cam_index); - } + void * cap = open_video_stream(filename, cam_index, 0,0,0); int top = option_find_int(options, "top", 1); @@ -950,8 +938,6 @@ void gun_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_inde int *indexes = calloc(top, sizeof(int)); if(!cap) error("Couldn't connect to webcam.\n"); - cvNamedWindow("Threat Detection", CV_WINDOW_NORMAL); - cvResizeWindow("Threat Detection", 512, 512); float fps = 0; int i; @@ -1008,23 +994,10 @@ void demo_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_ind list *options = read_data_cfg(datacfg); srand(2222222); - CvCapture * cap; int w = 1280; int h = 720; - - if(filename){ - cap = cvCaptureFromFile(filename); - }else{ - cap = cvCaptureFromCAM(cam_index); - } - - if(w){ - cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w); - } - if(h){ - cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h); - } + void * cap = open_video_stream(filename, cam_index, w, h, 0); int top = option_find_int(options, "top", 1); @@ -1035,8 +1008,6 @@ void demo_classifier(char *datacfg, char *cfgfile, char *weightfile, int cam_ind int *indexes = calloc(top, sizeof(int)); if(!cap) error("Couldn't connect to webcam.\n"); - cvNamedWindow(base, CV_WINDOW_NORMAL); - cvResizeWindow(base, 512, 512); float fps = 0; int i; diff --git a/examples/darknet.c b/examples/darknet.c index 99b0d64f..d5383592 100644 --- a/examples/darknet.c +++ b/examples/darknet.c @@ -9,7 +9,6 @@ extern void test_detector(char *datacfg, char *cfgfile, char *weightfile, char * extern void run_yolo(int argc, char **argv); extern void run_detector(int argc, char **argv); extern void run_coco(int argc, char **argv); -extern void run_captcha(int argc, char **argv); extern void run_nightmare(int argc, char **argv); extern void run_classifier(int argc, char **argv); extern void run_regressor(int argc, char **argv); @@ -396,9 +395,6 @@ void visualize(char *cfgfile, char *weightfile) { network *net = load_network(cfgfile, weightfile, 0); visualize_network(net); -#ifdef OPENCV - cvWaitKey(0); -#endif } int main(int argc, char **argv) @@ -465,8 +461,6 @@ int main(int argc, char **argv) composite_3d(argv[2], argv[3], argv[4], (argc > 5) ? atof(argv[5]) : 0); } else if (0 == strcmp(argv[1], "test")){ test_resize(argv[2]); - } else if (0 == strcmp(argv[1], "captcha")){ - run_captcha(argc, argv); } else if (0 == strcmp(argv[1], "nightmare")){ run_nightmare(argc, argv); } else if (0 == strcmp(argv[1], "rgbgr")){ diff --git a/examples/detector.c b/examples/detector.c index b503fc60..318f7fbb 100644 --- a/examples/detector.c +++ b/examples/detector.c @@ -609,10 +609,7 @@ void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filenam else{ save_image(im, "predictions"); #ifdef OPENCV - cvNamedWindow("predictions", CV_WINDOW_NORMAL); - if(fullscreen){ - cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); - } + make_window("predictions", 512, 512, 0); show_image(im, "predictions", 0); #endif } diff --git a/examples/instance-segmenter.c b/examples/instance-segmenter.c index 17fd4e1a..664e7142 100644 --- a/examples/instance-segmenter.c +++ b/examples/instance-segmenter.c @@ -187,17 +187,9 @@ void demo_isegmenter(char *datacfg, char *cfg, char *weights, int cam_index, con set_batch_network(net, 1); srand(2222222); - CvCapture * cap; - - if(filename){ - cap = cvCaptureFromFile(filename); - }else{ - cap = cvCaptureFromCAM(cam_index); - } + void * cap = open_video_stream(filename, cam_index, 0,0,0); if(!cap) error("Couldn't connect to webcam.\n"); - cvNamedWindow("Segmenter", CV_WINDOW_NORMAL); - cvResizeWindow("Segmenter", 512, 512); float fps = 0; while(1){ diff --git a/examples/regressor.c b/examples/regressor.c index 0bd7aba0..20cec0fa 100644 --- a/examples/regressor.c +++ b/examples/regressor.c @@ -155,21 +155,13 @@ void demo_regressor(char *datacfg, char *cfgfile, char *weightfile, int cam_inde set_batch_network(net, 1); srand(2222222); - CvCapture * cap; - - if(filename){ - cap = cvCaptureFromFile(filename); - }else{ - cap = cvCaptureFromCAM(cam_index); - } list *options = read_data_cfg(datacfg); int classes = option_find_int(options, "classes", 1); char *name_list = option_find_str(options, "names", 0); char **names = get_labels(name_list); + void * cap = open_video_stream(filename, cam_index, 0,0,0); if(!cap) error("Couldn't connect to webcam.\n"); - cvNamedWindow("Regressor", CV_WINDOW_NORMAL); - cvResizeWindow("Regressor", 512, 512); float fps = 0; while(1){ diff --git a/examples/segmenter.c b/examples/segmenter.c index eadfd69a..2e7cea0b 100644 --- a/examples/segmenter.c +++ b/examples/segmenter.c @@ -175,17 +175,9 @@ void demo_segmenter(char *datacfg, char *cfg, char *weights, int cam_index, cons set_batch_network(net, 1); srand(2222222); - CvCapture * cap; - - if(filename){ - cap = cvCaptureFromFile(filename); - }else{ - cap = cvCaptureFromCAM(cam_index); - } + void * cap = open_video_stream(filename, cam_index, 0,0,0); if(!cap) error("Couldn't connect to webcam.\n"); - cvNamedWindow("Segmenter", CV_WINDOW_NORMAL); - cvResizeWindow("Segmenter", 512, 512); float fps = 0; while(1){ diff --git a/include/darknet.h b/include/darknet.h index b0a65e99..4390c619 100644 --- a/include/darknet.h +++ b/include/darknet.h @@ -5,9 +5,6 @@ #include #include -#define SECRET_NUM -1234 -extern int gpu_index; - #ifdef GPU #define BLOCK 512 @@ -20,18 +17,13 @@ extern int gpu_index; #endif #endif -#ifndef __cplusplus - #ifdef OPENCV - #include "opencv2/highgui/highgui_c.h" - #include "opencv2/imgproc/imgproc_c.h" - #include "opencv2/core/version.hpp" - #if CV_MAJOR_VERSION == 3 - #include "opencv2/videoio/videoio_c.h" - #include "opencv2/imgcodecs/imgcodecs_c.h" - #endif - #endif +#ifdef __cplusplus +extern "C" { #endif +#define SECRET_NUM -1234 +extern int gpu_index; + typedef struct{ int classes; char **names; @@ -57,6 +49,10 @@ typedef enum{ LOGISTIC, RELU, RELIE, LINEAR, RAMP, TANH, PLSE, LEAKY, ELU, LOGGY, STAIR, HARDTAN, LHTAN, SELU } ACTIVATION; +typedef enum{ + PNG, BMP, TGA, JPG +} IMTYPE; + typedef enum{ MULT, ADD, SUB, DIV } BINARY_ACTIVATION; @@ -650,7 +646,8 @@ void harmless_update_network_gpu(network *net); #endif image get_label(image **characters, char *string, int size); void draw_label(image a, int r, int c, image label, const float *rgb); -void save_image_png(image im, const char *name); +void save_image(image im, const char *name); +void save_image_options(image im, const char *name, IMTYPE f, int quality); void get_next_batch(data d, int n, int offset, float *X, float *y); void grayscale_image_3c(image im); void normalize_image(image p); @@ -709,7 +706,6 @@ image mask_to_rgb(image mask); int resize_network(network *net, int w, int h); void free_matrix(matrix m); void test_resize(char *filename); -void save_image(image p, const char *name); int show_image(image p, const char *name, int ms); image copy_image(image p); void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b); @@ -758,11 +754,12 @@ void do_nms_sort(detection *dets, int total, int classes, float thresh); matrix make_matrix(int rows, int cols); -#ifndef __cplusplus #ifdef OPENCV -image get_image_from_stream(CvCapture *cap); -#endif +void *open_video_stream(const char *f, int c, int w, int h, int fps); +image get_image_from_stream(void *p); +void make_window(char *name, int w, int h, int fullscreen); #endif + void free_image(image m); float train_network(network *net, data d); pthread_t load_data_in_thread(load_args args); @@ -802,4 +799,7 @@ size_t rand_size_t(); float rand_normal(); float rand_uniform(float min, float max); +#ifdef __cplusplus +} +#endif #endif diff --git a/src/demo.c b/src/demo.c index 492c360d..b89efb8d 100644 --- a/src/demo.c +++ b/src/demo.c @@ -21,8 +21,7 @@ static network *net; static image buff [3]; static image buff_letter[3]; static int buff_index = 0; -static CvCapture * cap; -static IplImage * ipl; +static void * cap; static float fps = 0; static float demo_thresh = 0; static float demo_hier = .5; @@ -140,16 +139,19 @@ void *detect_in_thread(void *ptr) void *fetch_in_thread(void *ptr) { - int status = fill_image_from_stream(cap, buff[buff_index]); + free_image(buff[buff_index]); + buff[buff_index] = get_image_from_stream(cap); + if(buff[buff_index].data == 0) { + demo_done = 1; + return 0; + } letterbox_image_into(buff[buff_index], net->w, net->h, buff_letter[buff_index]); - if(status == 0) demo_done = 1; return 0; } void *display_in_thread(void *ptr) { - show_image_cv(buff[(buff_index + 1)%3], "Demo", ipl); - int c = cvWaitKey(1); + int c = show_image(buff[(buff_index + 1)%3], "Demo", 1); if (c != -1) c = c%256; if (c == 27) { demo_done = 1; @@ -209,19 +211,9 @@ void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const ch if(filename){ printf("video file: %s\n", filename); - cap = cvCaptureFromFile(filename); + cap = open_video_stream(filename, 0, 0, 0, 0); }else{ - cap = cvCaptureFromCAM(cam_index); - - if(w){ - cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w); - } - if(h){ - cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h); - } - if(frames){ - cvSetCaptureProperty(cap, CV_CAP_PROP_FPS, frames); - } + cap = open_video_stream(0, cam_index, w, h, frames); } if(!cap) error("Couldn't connect to webcam.\n"); @@ -232,17 +224,10 @@ void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const ch buff_letter[0] = letterbox_image(buff[0], net->w, net->h); buff_letter[1] = letterbox_image(buff[0], net->w, net->h); buff_letter[2] = letterbox_image(buff[0], net->w, net->h); - ipl = cvCreateImage(cvSize(buff[0].w,buff[0].h), IPL_DEPTH_8U, buff[0].c); int count = 0; if(!prefix){ - cvNamedWindow("Demo", CV_WINDOW_NORMAL); - if(fullscreen){ - cvSetWindowProperty("Demo", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); - } else { - cvMoveWindow("Demo", 0, 0); - cvResizeWindow("Demo", 1352, 1013); - } + make_window("Demo", 1352, 1013, fullscreen); } demo_time = what_time_is_it_now(); diff --git a/src/image.c b/src/image.c index c112dd81..4a2c6baf 100644 --- a/src/image.c +++ b/src/image.c @@ -534,174 +534,27 @@ void rgbgr_image(image im) } } -#ifdef OPENCV -void show_image_cv(image p, const char *name, IplImage *disp) -{ - int x,y,k; - if(p.c == 3) rgbgr_image(p); - //normalize_image(copy); - - char buff[256]; - //sprintf(buff, "%s (%d)", name, windows); - sprintf(buff, "%s", name); - - int step = disp->widthStep; - cvNamedWindow(buff, CV_WINDOW_NORMAL); - //cvMoveWindow(buff, 100*(windows%10) + 200*(windows/10), 100*(windows%10)); - ++windows; - 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(p,x,y,k)*255); - } - } - } - if(0){ - int w = 448; - int h = w*p.h/p.w; - if(h > 1000){ - h = 1000; - w = h*p.w/p.h; - } - IplImage *buffer = disp; - disp = cvCreateImage(cvSize(w, h), buffer->depth, buffer->nChannels); - cvResize(buffer, disp, CV_INTER_LINEAR); - cvReleaseImage(&buffer); - } - cvShowImage(buff, disp); -} -#endif - int show_image(image p, const char *name, int ms) { #ifdef OPENCV - IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c); - image copy = copy_image(p); - constrain_image(copy); - show_image_cv(copy, name, disp); - free_image(copy); - cvReleaseImage(&disp); - int c = cvWaitKey(ms); - if (c != -1) c = c%256; + int c = show_image_cv(p, name, ms); return c; #else fprintf(stderr, "Not compiled with OpenCV, saving to %s.png instead\n", name); save_image(p, name); - return 0; + return -1; #endif } -#ifdef OPENCV - -void ipl_into_image(IplImage* src, image im) -{ - unsigned char *data = (unsigned char *)src->imageData; - int h = src->height; - int w = src->width; - int c = src->nChannels; - int step = src->widthStep; - int i, j, k; - - for(i = 0; i < h; ++i){ - for(k= 0; k < c; ++k){ - for(j = 0; j < w; ++j){ - im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.; - } - } - } -} - -image ipl_to_image(IplImage* src) -{ - int h = src->height; - int w = src->width; - int c = src->nChannels; - image out = make_image(w, h, c); - ipl_into_image(src, 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 ) - { - fprintf(stderr, "Cannot load image \"%s\"\n", filename); - char buff[256]; - sprintf(buff, "echo %s >> bad.list", filename); - system(buff); - return make_image(10,10,3); - //exit(0); - } - image out = ipl_to_image(src); - cvReleaseImage(&src); - rgbgr_image(out); - return out; -} - -void flush_stream_buffer(CvCapture *cap, int n) -{ - int i; - for(i = 0; i < n; ++i) { - cvQueryFrame(cap); - } -} - -image get_image_from_stream(CvCapture *cap) -{ - IplImage* src = cvQueryFrame(cap); - if (!src) return make_empty_image(0,0,0); - image im = ipl_to_image(src); - rgbgr_image(im); - return im; -} - -int fill_image_from_stream(CvCapture *cap, image im) -{ - IplImage* src = cvQueryFrame(cap); - if (!src) return 0; - ipl_into_image(src, im); - rgbgr_image(im); - return 1; -} - -void save_image_jpg(image p, const char *name) -{ - image copy = copy_image(p); - if(p.c == 3) rgbgr_image(copy); - int x,y,k; - - char buff[256]; - sprintf(buff, "%s.jpg", name); - - 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); - } - } - } - cvSaveImage(buff, disp,0); - cvReleaseImage(&disp); - free_image(copy); -} -#endif - -void save_image_png(image im, const char *name) +void save_image_options(image im, const char *name, IMTYPE f, int quality) { char buff[256]; //sprintf(buff, "%s (%d)", name, windows); - sprintf(buff, "%s.png", name); + if(f == PNG) sprintf(buff, "%s.png", name); + else if (f == BMP) sprintf(buff, "%s.bmp", name); + else if (f == TGA) sprintf(buff, "%s.tga", name); + else if (f == JPG) sprintf(buff, "%s.jpg", name); + else 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){ @@ -709,21 +562,20 @@ void save_image_png(image im, const char *name) 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); + int success = 0; + if(f == PNG) success = stbi_write_png(buff, im.w, im.h, im.c, data, im.w*im.c); + else if (f == BMP) success = stbi_write_bmp(buff, im.w, im.h, im.c, data); + else if (f == TGA) success = stbi_write_tga(buff, im.w, im.h, im.c, data); + else if (f == JPG) success = stbi_write_jpg(buff, im.w, im.h, im.c, data, quality); free(data); if(!success) fprintf(stderr, "Failed to write image %s\n", buff); } void save_image(image im, const char *name) { -#ifdef OPENCV - save_image_jpg(im, name); -#else - save_image_png(im, name); -#endif + save_image_options(im, name, JPG, 80); } - void show_image_layers(image p, char *name) { int i; @@ -938,11 +790,7 @@ void composite_3d(char *f1, char *f2, char *out, int delta) for(i = 0; i < c.w*c.h; ++i){ c.data[i] = a.data[i]; } -#ifdef OPENCV - save_image_jpg(c, out); -#else save_image(c, out); -#endif } void letterbox_image_into(image im, int w, int h, image boxed) @@ -1437,7 +1285,6 @@ void test_resize(char *filename) show_image(c, "rand", 1); printf("%f %f %f\n", dhue, dsat, dexp); free_image(c); - cvWaitKey(0); } #endif } diff --git a/src/image.h b/src/image.h index 789cf18d..3392bb97 100644 --- a/src/image.h +++ b/src/image.h @@ -9,14 +9,15 @@ #include "box.h" #include "darknet.h" -#ifndef __cplusplus -#ifdef OPENCV -int fill_image_from_stream(CvCapture *cap, image im); -image ipl_to_image(IplImage* src); -void ipl_into_image(IplImage* src, image im); -void flush_stream_buffer(CvCapture *cap, int n); -void show_image_cv(image p, const char *name, IplImage *disp); +#ifdef __cplusplus +extern "C" { #endif + +#ifdef OPENCV +void *open_video_stream(const char *f, int c, int w, int h, int fps); +image get_image_from_stream(void *p); +image load_image_cv(char *filename, int channels); +int show_image_cv(image im, const char* name, int ms); #endif float get_color(int c, int x, int max); @@ -60,5 +61,9 @@ void copy_image_into(image src, image dest); image get_image_layer(image m, int l); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/image_opencv.cpp b/src/image_opencv.cpp new file mode 100644 index 00000000..7511280b --- /dev/null +++ b/src/image_opencv.cpp @@ -0,0 +1,135 @@ +#ifdef OPENCV + +#include "stdio.h" +#include "stdlib.h" +#include "opencv2/opencv.hpp" +#include "image.h" + +using namespace cv; + +extern "C" { + +IplImage *image_to_ipl(image im) +{ + int x,y,c; + IplImage *disp = cvCreateImage(cvSize(im.w,im.h), IPL_DEPTH_8U, im.c); + int step = disp->widthStep; + for(y = 0; y < im.h; ++y){ + for(x = 0; x < im.w; ++x){ + for(c= 0; c < im.c; ++c){ + float val = im.data[c*im.h*im.w + y*im.w + x]; + disp->imageData[y*step + x*im.c + c] = (unsigned char)(val*255); + } + } + } + return disp; +} + +image ipl_to_image(IplImage* src) +{ + int h = src->height; + int w = src->width; + int c = src->nChannels; + image im = make_image(w, h, c); + unsigned char *data = (unsigned char *)src->imageData; + int step = src->widthStep; + int i, j, k; + + for(i = 0; i < h; ++i){ + for(k= 0; k < c; ++k){ + for(j = 0; j < w; ++j){ + im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.; + } + } + } + return im; +} + +Mat image_to_mat(image im) +{ + image copy = copy_image(im); + constrain_image(copy); + if(im.c == 3) rgbgr_image(copy); + + IplImage *ipl = image_to_ipl(copy); + Mat m = cvarrToMat(ipl, true); + cvReleaseImage(&ipl); + free_image(copy); + return m; +} + +image mat_to_image(Mat m) +{ + IplImage ipl = m; + image im = ipl_to_image(&ipl); + rgbgr_image(im); + return im; +} + +void *open_video_stream(const char *f, int c, int w, int h, int fps) +{ + VideoCapture *cap; + if(f) cap = new VideoCapture(f); + else cap = new VideoCapture(c); + if(!cap->isOpened()) return 0; + if(w) cap->set(CV_CAP_PROP_FRAME_WIDTH, w); + if(h) cap->set(CV_CAP_PROP_FRAME_HEIGHT, w); + if(fps) cap->set(CV_CAP_PROP_FPS, w); + return (void *) cap; +} + +image get_image_from_stream(void *p) +{ + VideoCapture *cap = (VideoCapture *)p; + Mat m; + *cap >> m; + if(m.empty()) return make_empty_image(0,0,0); + return mat_to_image(m); +} + +image load_image_cv(char *filename, int channels) +{ + 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); + } + Mat m; + m = imread(filename, flag); + if(!m.data){ + fprintf(stderr, "Cannot load image \"%s\"\n", filename); + char buff[256]; + sprintf(buff, "echo %s >> bad.list", filename); + system(buff); + return make_image(10,10,3); + //exit(0); + } + image im = mat_to_image(m); + return im; +} + +int show_image_cv(image im, const char* name, int ms) +{ + Mat m = image_to_mat(im); + imshow(name, m); + int c = waitKey(ms); + if (c != -1) c = c%256; + return c; +} + +void make_window(char *name, int w, int h, int fullscreen) +{ + namedWindow(name, WINDOW_NORMAL); + if (fullscreen) { + setWindowProperty(name, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); + } else { + resizeWindow(name, w, h); + if(strcmp(name, "Demo") == 0) moveWindow(name, 0, 0); + } +} + +} + +#endif