├── .gitignore ├── LICENSE ├── README.md ├── code ├── external │ ├── fast_rcnn_bbox_transform.m │ └── fast_rcnn_bbox_transform_inv.m ├── nms │ ├── nms.m │ ├── nms_gpu_mex.cu │ ├── nms_mex.cpp │ ├── nms_multiclass.m │ ├── nms_multiclass_mex.cpp │ └── nvmex.m ├── utils │ ├── RectLTRB2LTWH.m │ ├── RectLTWH2LTRB.m │ ├── append_roi_weight.m │ ├── assets │ │ ├── active_caffe_mex.m │ │ ├── auto_select_gpu.m │ │ ├── boxes_filter.m │ │ ├── boxes_filter_inline_normal.m │ │ ├── change_edgebox.m │ │ ├── check_im_num.m │ │ ├── compute_coco_mean.m │ │ ├── compute_recall_ilsvrc.m │ │ ├── convert_t7_to_caffe │ │ │ ├── net_def.py │ │ │ └── resnet200_trainval.prototxt │ │ ├── extract_14train_only.m │ │ ├── generate_multi_nms_setting.m │ │ ├── generate_multi_nms_setting_fcn.m │ │ ├── generate_train14_txt.m │ │ ├── jsonlab │ │ │ ├── AUTHORS.txt │ │ │ ├── ChangeLog.txt │ │ │ ├── LICENSE_BSD.txt │ │ │ ├── README.txt │ │ │ ├── examples │ │ │ │ ├── demo_jsonlab_basic.m │ │ │ │ ├── demo_ubjson_basic.m │ │ │ │ ├── example1.json │ │ │ │ ├── example2.json │ │ │ │ ├── example3.json │ │ │ │ ├── example4.json │ │ │ │ ├── jsonlab_selftest.m │ │ │ │ └── jsonlab_speedtest.m │ │ │ ├── jsonopt.m │ │ │ ├── loadjson.m │ │ │ ├── loadubjson.m │ │ │ ├── mergestruct.m │ │ │ ├── savejson.m │ │ │ ├── saveubjson.m │ │ │ ├── struct2jdata.m │ │ │ └── varargin2struct.m │ │ ├── load_proposal_detection_model.m │ │ ├── merge_roidb.m │ │ ├── new_parpool.m │ │ ├── prep_im_for_blob_size.m │ │ ├── print_model.py │ │ ├── proposal_prepare_anchors.m │ │ ├── show_box_simple.m │ │ ├── showboxes.m │ │ ├── split_json_file.py │ │ ├── stats_opt.m │ │ ├── subsample_images.m │ │ ├── subsample_images_per_class.m │ │ ├── symbolic_link.m │ │ ├── vis_label.m │ │ ├── xVOCap.m │ │ ├── xVOChash_init.m │ │ └── xVOChash_lookup.m │ ├── box_vote.m │ ├── boxes_filter.m │ ├── boxoverlap.m │ ├── collect_bbox_stats.m │ ├── collect_coco_gt.m │ ├── collect_db_info.m │ ├── compute_overlap.m │ ├── compute_rec_pre.m │ ├── convert_ilsvrc_rec.m │ ├── convert_pascal_rec.m │ ├── cprintf.m │ ├── find_nan_weight.m │ ├── get_coco_info.m │ ├── get_imagenet_3k_info.m │ ├── get_voc_info.m │ ├── im_list_to_blob.m │ ├── im_to_scale.m │ ├── init_weight_from_other_model.m │ ├── mkdir_if_missing.m │ ├── parse_rst.m │ ├── prep_im_for_blob.m │ ├── process_regression_result.m │ ├── procid.m │ ├── rolling_mean.m │ ├── scale_rois.m │ ├── seed_rand.m │ ├── tic_toc_print.m │ ├── update_recall_stats.m │ └── visual_anchor_test.m └── zoom_net │ ├── assets │ ├── AttractioNet_postprocess.m │ ├── evaluate.m │ ├── proposal_test_v0.m │ ├── rpn_compute_stats_TODO.m │ ├── rpn_compute_targets_v0.m │ └── update_rpn_boxes.m │ ├── minor │ ├── copy_weights_to_mirror_layer.m │ ├── default_config.m │ ├── draw_damn_image.m │ ├── dynamic_change_scale.m │ ├── fetch_required_info.m │ ├── init_zoom_net.m │ ├── proposal_calc_output_size.m │ ├── proposal_calc_output_size_certainScale.m │ ├── proposal_generate_anchors.m │ ├── proposal_generate_anchors_multi.m │ └── proposal_locate_anchors.m │ ├── process_test_output.m │ ├── proposal_get_minibatch.m │ ├── proposal_im_detect.m │ ├── rpn_fetch_data.m │ ├── zoom_sample_rois.m │ ├── zoom_test.m │ └── zoom_train.m ├── experiment ├── boost_main.m ├── compute_stats.m ├── deploy │ ├── E02_imagenet_3k_test.m │ ├── E02_imagenet_3k_train.m │ ├── F01_baseline_voc.m │ └── F03_voc_hg.m ├── evaluate.m ├── merge_split_json_file.m ├── merge_train_val_from_bj1_faster_rcnn.m ├── test │ └── F01_baseline_voc_test.m └── visualize_test.m ├── model ├── pretrain │ └── bn_vgg19 │ │ ├── deploy.prototxt │ │ ├── solver.txt │ │ └── train_val.txt └── zoom │ └── bn │ ├── base │ ├── deploy_check.prototxt │ └── solver_deploy_check.prototxt │ ├── baseline │ ├── deploy.prototxt │ ├── solver_deploy.prototxt │ ├── solver_train.prototxt │ ├── solver_train_auto.prototxt │ ├── train.prototxt │ └── train_bn_origin.prototxt │ ├── baseline_single │ ├── solver_train_auto.prototxt │ └── train.prototxt │ └── set_8_balance_3cls_voc │ ├── 10anchors_3level │ ├── deploy.prototxt │ ├── solver_deploy.prototxt │ ├── solver_train_auto.prototxt │ └── train.prototxt └── startup.m /.gitignore: -------------------------------------------------------------------------------- 1 | # user defined 2 | .idea/ 3 | data/ 4 | output/ 5 | !output/extract_prop/merge_train.m 6 | #*/caffe_log/* 7 | 8 | code/external/caffe 9 | *.swp 10 | *.jpg* 11 | *.mat* 12 | *.out* 13 | *.caffemodel* 14 | *.mex* 15 | *.m~ 16 | *.txt~ 17 | *.prototxt~ 18 | *.md~ 19 | 20 | # caffe 21 | code/external/caffe 22 | *.caffemodel 23 | *.solverstate 24 | *.binaryproto 25 | *leveldb 26 | *lmdb 27 | 28 | # build, distribute, and bins (+ python proto bindings) 29 | *.testbin 30 | *.bin 31 | 32 | # Byte-compiled / optimized / DLL files 33 | __pycache__/ 34 | *.py[cod] 35 | *$py.class 36 | 37 | # C extensions 38 | *.so 39 | 40 | 41 | # Byte-compiled / optimized / DLL files 42 | __pycache__/ 43 | *.py[cod] 44 | *$py.class 45 | 46 | # C extensions 47 | *.so 48 | 49 | # Distribution / packaging 50 | .Python 51 | env/ 52 | build/ 53 | develop-eggs/ 54 | dist/ 55 | downloads/ 56 | eggs/ 57 | .eggs/ 58 | lib/ 59 | lib64/ 60 | parts/ 61 | sdist/ 62 | var/ 63 | *.egg-info/ 64 | .installed.cfg 65 | *.egg 66 | 67 | # PyInstaller 68 | # Usually these files are written by a python script from a template 69 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 70 | *.manifest 71 | *.spec 72 | 73 | # Installer logs 74 | pip-log.txt 75 | pip-delete-this-directory.txt 76 | 77 | # Unit test / coverage reports 78 | htmlcov/ 79 | .tox/ 80 | .coverage 81 | .coverage.* 82 | .cache 83 | nosetests.xml 84 | coverage.xml 85 | *,cover 86 | .hypothesis/ 87 | 88 | # Translations 89 | *.mo 90 | *.pot 91 | 92 | # Django stuff: 93 | *.log 94 | local_settings.py 95 | 96 | # Flask stuff: 97 | instance/ 98 | .webassets-cache 99 | 100 | # Scrapy stuff: 101 | .scrapy 102 | 103 | # Sphinx documentation 104 | docs/_build/ 105 | 106 | # PyBuilder 107 | target/ 108 | 109 | # IPython Notebook 110 | .ipynb_checkpoints 111 | 112 | # pyenv 113 | .python-version 114 | 115 | # celery beat schedule file 116 | celerybeat-schedule 117 | 118 | # dotenv 119 | .env 120 | 121 | # virtualenv 122 | venv/ 123 | ENV/ 124 | 125 | # Spyder project settings 126 | .spyderproject 127 | 128 | # Rope project settings 129 | .ropeproject 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Hongyang Li 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zoom-out-and-in Network for region proposal and object detection 2 | 3 | The codebase for: 4 | * (Nov 2016): Zoom network with recursive training, arXiv link: [[arXiv: 1702.05711]](https://arxiv.org/abs/1702.05711) 5 | * (July 2017): Zoom network with map attention decision, arXiv link: [[arXiv: 1709.04347]](https://arxiv.org/abs/1709.04347) 6 | 7 | **This codebase is written in Caffe with Matlab wrapper. It supports multi-gpu training. However, this is a quite old repo (active around early 2017) and I no longer maintain it.** 8 | 9 | Then why open-source it? Simply I have a habit to publish code whenever some work is accepted. 10 | 11 | -------------------------------------------------------------------------------- /code/external/fast_rcnn_bbox_transform.m: -------------------------------------------------------------------------------- 1 | function [regression_label] = fast_rcnn_bbox_transform(ex_boxes, gt_boxes) 2 | % [regression_label] = fast_rcnn_bbox_transform(ex_boxes, gt_boxes) 3 | % -------------------------------------------------------- 4 | % Fast R-CNN 5 | % Reimplementation based on Python Fast R-CNN (https://github.com/rbgirshick/fast-rcnn) 6 | % Copyright (c) 2015, Shaoqing Ren 7 | % Licensed under The MIT License [see LICENSE for details] 8 | % -------------------------------------------------------- 9 | 10 | ex_widths = ex_boxes(:, 3) - ex_boxes(:, 1) + 1; 11 | ex_heights = ex_boxes(:, 4) - ex_boxes(:, 2) + 1; 12 | ex_ctr_x = ex_boxes(:, 1) + 0.5 * (ex_widths - 1); 13 | ex_ctr_y = ex_boxes(:, 2) + 0.5 * (ex_heights - 1); 14 | 15 | gt_widths = gt_boxes(:, 3) - gt_boxes(:, 1) + 1; 16 | gt_heights = gt_boxes(:, 4) - gt_boxes(:, 2) + 1; 17 | gt_ctr_x = gt_boxes(:, 1) + 0.5 * (gt_widths - 1); 18 | gt_ctr_y = gt_boxes(:, 2) + 0.5 * (gt_heights - 1); 19 | 20 | targets_dx = (gt_ctr_x - ex_ctr_x) ./ (ex_widths+eps); 21 | targets_dy = (gt_ctr_y - ex_ctr_y) ./ (ex_heights+eps); 22 | targets_dw = log(gt_widths ./ ex_widths); 23 | targets_dh = log(gt_heights ./ ex_heights); 24 | 25 | regression_label = [targets_dx, targets_dy, targets_dw, targets_dh]; 26 | end -------------------------------------------------------------------------------- /code/external/fast_rcnn_bbox_transform_inv.m: -------------------------------------------------------------------------------- 1 | function [pred_boxes] = fast_rcnn_bbox_transform_inv(boxes, box_deltas) 2 | % [pred_boxes] = fast_rcnn_bbox_transform_inv(boxes, box_deltas) 3 | % -------------------------------------------------------- 4 | % Fast R-CNN 5 | % Reimplementation based on Python Fast R-CNN (https://github.com/rbgirshick/fast-rcnn) 6 | % Copyright (c) 2015, Shaoqing Ren 7 | % Licensed under The MIT License [see LICENSE for details] 8 | % -------------------------------------------------------- 9 | 10 | src_w = double(boxes(:, 3) - boxes(:, 1) + 1); 11 | src_h = double(boxes(:, 4) - boxes(:, 2) + 1); 12 | src_ctr_x = double(boxes(:, 1) + 0.5*(src_w-1)); 13 | src_ctr_y = double(boxes(:, 2) + 0.5*(src_h-1)); 14 | 15 | dst_ctr_x = double(box_deltas(:, 1:4:end)); 16 | dst_ctr_y = double(box_deltas(:, 2:4:end)); 17 | dst_scl_x = double(box_deltas(:, 3:4:end)); 18 | dst_scl_y = double(box_deltas(:, 4:4:end)); 19 | 20 | pred_ctr_x = bsxfun(@plus, bsxfun(@times, dst_ctr_x, src_w), src_ctr_x); 21 | pred_ctr_y = bsxfun(@plus, bsxfun(@times, dst_ctr_y, src_h), src_ctr_y); 22 | pred_w = bsxfun(@times, exp(dst_scl_x), src_w); 23 | pred_h = bsxfun(@times, exp(dst_scl_y), src_h); 24 | pred_boxes = zeros(size(box_deltas), 'single'); 25 | pred_boxes(:, 1:4:end) = pred_ctr_x - 0.5*(pred_w-1); 26 | pred_boxes(:, 2:4:end) = pred_ctr_y - 0.5*(pred_h-1); 27 | pred_boxes(:, 3:4:end) = pred_ctr_x + 0.5*(pred_w-1); 28 | pred_boxes(:, 4:4:end) = pred_ctr_y + 0.5*(pred_h-1); 29 | end -------------------------------------------------------------------------------- /code/nms/nms.m: -------------------------------------------------------------------------------- 1 | function pick = nms(boxes, overlap, use_gpu) 2 | % top = nms(boxes, overlap) 3 | % Non-maximum suppression. (FAST VERSION) 4 | % Greedily select high-scoring detections and skip detections 5 | % that are significantly covered by a previously selected 6 | % detection. 7 | % 8 | % NOTE: This is adapted from Pedro Felzenszwalb's version (nms.m), 9 | % but an inner loop has been eliminated to significantly speed it 10 | % up in the case of a large number of boxes 11 | 12 | % Copyright (C) 2011-12 by Tomasz Malisiewicz 13 | % All rights reserved. 14 | % 15 | % This file is part of the Exemplar-SVM library and is made 16 | % available under the terms of the MIT license (see COPYING file). 17 | % Project homepage: https://github.com/quantombone/exemplarsvm 18 | 19 | 20 | if isempty(boxes) 21 | pick = []; 22 | return; 23 | end 24 | 25 | if ~exist('use_gpu', 'var') 26 | use_gpu = false; 27 | end 28 | 29 | if use_gpu 30 | s = boxes(:, end); 31 | if ~issorted(s(end:-1:1)) 32 | [~, I] = sort(s, 'descend'); 33 | boxes = boxes(I, :); 34 | pick = nms_gpu_mex(single(boxes)', double(overlap)); 35 | pick = I(pick); 36 | else 37 | pick = nms_gpu_mex(single(boxes)', double(overlap)); 38 | end 39 | return; 40 | end 41 | 42 | if size(boxes, 1) < 1000000 43 | pick = nms_mex(double(boxes), double(overlap)); 44 | return; 45 | end 46 | 47 | x1 = boxes(:,1); 48 | y1 = boxes(:,2); 49 | x2 = boxes(:,3); 50 | y2 = boxes(:,4); 51 | s = boxes(:,end); 52 | 53 | area = (x2-x1+1) .* (y2-y1+1); 54 | [vals, I] = sort(s); 55 | 56 | pick = s*0; 57 | counter = 1; 58 | while ~isempty(I) 59 | last = length(I); 60 | i = I(last); 61 | pick(counter) = i; 62 | counter = counter + 1; 63 | 64 | xx1 = max(x1(i), x1(I(1:last-1))); 65 | yy1 = max(y1(i), y1(I(1:last-1))); 66 | xx2 = min(x2(i), x2(I(1:last-1))); 67 | yy2 = min(y2(i), y2(I(1:last-1))); 68 | 69 | w = max(0.0, xx2-xx1+1); 70 | h = max(0.0, yy2-yy1+1); 71 | 72 | inter = w.*h; 73 | o = inter ./ (area(i) + area(I(1:last-1)) - inter); 74 | 75 | I = I(find(o<=overlap)); 76 | end 77 | 78 | pick = pick(1:(counter-1)); 79 | -------------------------------------------------------------------------------- /code/nms/nms_gpu_mex.cu: -------------------------------------------------------------------------------- 1 | /* 2 | * Example of how to use the mxGPUArray API in a MEX file. This example shows 3 | * how to write a MEX function that takes a gpuArray input and returns a 4 | * gpuArray output, e.g. B=mexFunction(A). 5 | * 6 | * Copyright 2012 The MathWorks, Inc. 7 | */ 8 | 9 | #include "mex.h" 10 | #include 11 | #include 12 | 13 | #define DIVUP(m,n) ((m)/(n)+((m)%(n)>0)) 14 | int const threadsPerBlock = (sizeof(unsigned long long) * 8); 15 | 16 | /* 17 | * Device code 18 | */ 19 | __device__ inline float devIoU(float const * const a, float const * const b) 20 | { 21 | float left = max(a[0], b[0]), right = min(a[2], b[2]); 22 | float top = max(a[1], b[1]), bottom = min(a[3], b[3]); 23 | float width = max(right - left + 1, 0.f), height = max(bottom - top + 1, 0.f); 24 | float interS = width * height; 25 | float Sa = (a[2] - a[0] + 1) * (a[3] - a[1] + 1); 26 | float Sb = (b[2] - b[0] + 1) * (b[3] - b[1] + 1); 27 | return interS / (Sa + Sb - interS); 28 | } 29 | 30 | __global__ void nms_kernel(const int n_boxes, const float nms_overlap_thres, const float *dev_boxes, unsigned long long *dev_mask) 31 | { 32 | const int row_start = blockIdx.y, col_start = blockIdx.x; 33 | const int row_size = min(n_boxes - row_start * threadsPerBlock, threadsPerBlock), col_size = min(n_boxes - col_start * threadsPerBlock, threadsPerBlock); 34 | 35 | //if (row_start > col_start) return; 36 | 37 | __shared__ float block_boxes[threadsPerBlock * 5]; 38 | if (threadIdx.x < col_size) 39 | { 40 | block_boxes[threadIdx.x * 5 + 0] = dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0]; 41 | block_boxes[threadIdx.x * 5 + 1] = dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1]; 42 | block_boxes[threadIdx.x * 5 + 2] = dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2]; 43 | block_boxes[threadIdx.x * 5 + 3] = dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3]; 44 | block_boxes[threadIdx.x * 5 + 4] = dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4]; 45 | } 46 | __syncthreads(); 47 | 48 | if (threadIdx.x < row_size) 49 | { 50 | const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x; 51 | const float *cur_box = dev_boxes + cur_box_idx * 5; 52 | int i = 0; 53 | unsigned long long t = 0; 54 | int start = 0; 55 | if (row_start == col_start) start = threadIdx.x + 1; 56 | for (i = start; i < col_size; i++) 57 | { 58 | if (devIoU(cur_box, block_boxes + i * 5) > nms_overlap_thres) 59 | { 60 | t |= 1ULL << i; 61 | } 62 | } 63 | const int col_blocks = DIVUP(n_boxes, threadsPerBlock); 64 | dev_mask[cur_box_idx * col_blocks + col_start] = t; 65 | } 66 | } 67 | 68 | /* 69 | * Host code 70 | */ 71 | void mexFunction(int nlhs, mxArray *plhs[], 72 | int nrhs, const mxArray *prhs[]) 73 | { 74 | 75 | /* Declare all variables.*/ 76 | mxArray const *boxes, *ov_thres; 77 | float *boxes_host = NULL; 78 | float *boxes_dev = NULL; 79 | unsigned long long *mask_dev = NULL; 80 | 81 | /* Throw an error if the input is not a array. */ 82 | if (nrhs != 2) { 83 | mexErrMsgTxt("nms_gpu_mex::need 2 inputs"); 84 | } 85 | 86 | boxes = prhs[0]; 87 | if (mxGetClassID(boxes) != mxSINGLE_CLASS) { 88 | mexErrMsgTxt("nms_gpu_mex::input boxes must be single"); 89 | } 90 | 91 | ov_thres = prhs[1]; 92 | if (mxGetClassID(ov_thres) != mxDOUBLE_CLASS) { 93 | mexErrMsgTxt("nms_gpu_mex::input boxes must be double"); 94 | } 95 | 96 | float nms_overlap_thres = (float)mxGetScalar(ov_thres); 97 | 98 | int boxes_dim = mxGetM(boxes); 99 | int boxes_num = mxGetN(boxes); 100 | if (boxes_dim != 5) 101 | { 102 | mexErrMsgTxt("nms_gpu_mex::input boxes's row must be 5"); 103 | } 104 | 105 | boxes_host = (float *)(mxGetPr(boxes)); 106 | const int col_blocks = DIVUP(boxes_num, threadsPerBlock); 107 | 108 | cudaMalloc(&boxes_dev, mxGetNumberOfElements(boxes) * sizeof(float)); 109 | cudaMemcpy(boxes_dev, boxes_host, mxGetNumberOfElements(boxes) * sizeof(float), cudaMemcpyHostToDevice); 110 | 111 | /* Create a GPUArray to hold the result and get its underlying pointer. */ 112 | cudaMalloc(&mask_dev, boxes_num * col_blocks * sizeof(unsigned long long)); 113 | 114 | 115 | /* 116 | * Call the kernel using the CUDA runtime API. We are using a 1-d grid here, 117 | * and it would be possible for the number of elements to be too large for 118 | * the grid. For this example we are not guarding against this possibility. 119 | */ 120 | 121 | dim3 blocks(DIVUP(boxes_num, threadsPerBlock), DIVUP(boxes_num, threadsPerBlock)); 122 | dim3 threads(threadsPerBlock); 123 | nms_kernel << > >(boxes_num, nms_overlap_thres, boxes_dev, mask_dev); 124 | 125 | std::vector mask_host(boxes_num * col_blocks); 126 | cudaMemcpy(&mask_host[0], mask_dev, sizeof(unsigned long long) * boxes_num * col_blocks, cudaMemcpyDeviceToHost); 127 | 128 | std::vector remv(col_blocks); 129 | memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks); 130 | 131 | std::vector keep; 132 | keep.reserve(boxes_num); 133 | for (int i = 0; i < boxes_num; i++) 134 | { 135 | int nblock = i / threadsPerBlock; 136 | int inblock = i % threadsPerBlock; 137 | 138 | if (!(remv[nblock] & (1ULL << inblock))) 139 | { 140 | keep.push_back(i + 1); // to matlab's index 141 | 142 | unsigned long long *p = &mask_host[0] + i * col_blocks; 143 | for (int j = nblock; j < col_blocks; j++) 144 | { 145 | remv[j] |= p[j]; 146 | } 147 | } 148 | } 149 | 150 | /* Wrap the result up as a MATLAB cpuArray for return. */ 151 | mwSize dims[4] = { (int)keep.size(), 1, 1, 1 }; 152 | plhs[0] = mxCreateNumericArray(4, dims, mxINT32_CLASS, mxREAL); 153 | 154 | int *output = (int *)(mxGetPr(plhs[0])); 155 | memcpy(output, &keep[0], (int)keep.size() * sizeof(int)); 156 | 157 | 158 | cudaFree(boxes_dev); 159 | cudaFree(mask_dev); 160 | } 161 | -------------------------------------------------------------------------------- /code/nms/nms_mex.cpp: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #ifdef _MSC_VER 3 | #include 4 | #include 5 | #endif 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | struct score { 11 | double s; 12 | int idx; 13 | bool operator() (score i, score j) { return (i.idx < j.idx);} 14 | } score; 15 | 16 | template 17 | void nms(const mxArray *input_boxes, double overlap, vector &vPick, int &nPick) 18 | { 19 | int nSample = (int)mxGetM(input_boxes); 20 | int nDim_boxes = (int)mxGetN(input_boxes); 21 | 22 | T *pBoxes = (T*)mxGetData(input_boxes); 23 | 24 | vector vArea(nSample); 25 | for (int i = 0; i < nSample; ++i) 26 | { 27 | vArea[i] = double(pBoxes[2*nSample + i] - pBoxes[0*nSample + i] + 1) 28 | * (pBoxes[3*nSample + i] - pBoxes[1*nSample + i] + 1); 29 | if (vArea[i] < 0) 30 | mexErrMsgTxt("Boxes area must >= 0"); 31 | } 32 | 33 | std::multimap scores; 34 | for (int i = 0; i < nSample; ++i) 35 | scores.insert(std::pair(pBoxes[4*nSample + i], i)); 36 | 37 | nPick = 0; 38 | 39 | do 40 | { 41 | int last = scores.rbegin()->second; 42 | vPick[nPick] = last; 43 | nPick += 1; 44 | 45 | for (typename std::multimap::iterator it = scores.begin(); it != scores.end();) 46 | { 47 | int it_idx = it->second; 48 | T xx1 = max(pBoxes[0*nSample + last], pBoxes[0*nSample + it_idx]); 49 | T yy1 = max(pBoxes[1*nSample + last], pBoxes[1*nSample + it_idx]); 50 | T xx2 = min(pBoxes[2*nSample + last], pBoxes[2*nSample + it_idx]); 51 | T yy2 = min(pBoxes[3*nSample + last], pBoxes[3*nSample + it_idx]); 52 | 53 | double w = max(T(0.0), xx2-xx1+1), h = max(T(0.0), yy2-yy1+1); 54 | 55 | double ov = w*h / (vArea[last] + vArea[it_idx] - w*h); 56 | 57 | if (ov > overlap) 58 | { 59 | it = scores.erase(it); 60 | } 61 | else 62 | { 63 | it++; 64 | } 65 | } 66 | 67 | } while (scores.size() != 0); 68 | } 69 | 70 | 71 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 72 | { 73 | if (nrhs != 2) 74 | mexErrMsgTxt("Wrong number of inputs"); 75 | if (nlhs != 1) 76 | mexErrMsgTxt("One output"); 77 | 78 | const mxArray *input_boxes = prhs[0]; 79 | if (mxGetClassID(input_boxes) != mxDOUBLE_CLASS && mxGetClassID(input_boxes) != mxSINGLE_CLASS) 80 | mexErrMsgTxt("Input boxes must be Double or Single"); 81 | 82 | const mxArray *input_overlap = prhs[1]; 83 | if (mxGetClassID(input_overlap) != mxDOUBLE_CLASS ) 84 | mexErrMsgTxt("Input overlap must be Double"); 85 | 86 | double overlap = mxGetScalar(input_overlap); 87 | 88 | int nSample = (int)mxGetM(input_boxes); 89 | int nDim_boxes = (int)mxGetN(input_boxes); 90 | 91 | if (nSample * nDim_boxes == 0) 92 | { 93 | plhs[0] = mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL); 94 | return; 95 | } 96 | 97 | if (nDim_boxes != 5) 98 | mexErrMsgTxt("nms_mex boxes must has 5 columns"); 99 | 100 | 101 | int nPick = 0; 102 | vector vPick(nSample); 103 | if(mxGetClassID(input_boxes) == mxDOUBLE_CLASS) 104 | nms(input_boxes, overlap, vPick, nPick); 105 | else 106 | nms(input_boxes, overlap, vPick, nPick); 107 | 108 | plhs[0] = mxCreateNumericMatrix(nPick, 1, mxDOUBLE_CLASS, mxREAL); 109 | double *pRst = mxGetPr(plhs[0]); 110 | for (int i = 0; i < nPick; ++i) 111 | pRst[i] = vPick[i] + 1; 112 | } 113 | -------------------------------------------------------------------------------- /code/nms/nms_multiclass.m: -------------------------------------------------------------------------------- 1 | function picks = nms_multiclass(boxes, overlap) 2 | % top = nms(boxes, overlap) 3 | % Non-maximum suppression. (FAST VERSION) 4 | % Greedily select high-scoring detections and skip detections 5 | % that are significantly covered by a previously selected 6 | % detection. 7 | % 8 | % NOTE: This is adapted from Pedro Felzenszwalb's version (nms.m), 9 | % but an inner loop has been eliminated to significantly speed it 10 | % up in the case of a large number of boxes 11 | 12 | % Copyright (C) 2011-12 by Tomasz Malisiewicz 13 | % All rights reserved. 14 | % 15 | % This file is part of the Exemplar-SVM library and is made 16 | % available under the terms of the MIT license (see COPYING file). 17 | % Project homepage: https://github.com/quantombone/exemplarsvm 18 | 19 | 20 | if isempty(boxes) 21 | picks = {}; 22 | return; 23 | end 24 | 25 | if size(boxes, 1) < 10000 26 | picks = nms_multiclass_mex(double(boxes), double(overlap)); 27 | return; 28 | end 29 | 30 | x1 = boxes(:,1); 31 | y1 = boxes(:,2); 32 | x2 = boxes(:,3); 33 | y2 = boxes(:,4); 34 | 35 | area = (x2-x1+1) .* (y2-y1+1); 36 | 37 | picks = cell(size(boxes, 2)-4, 1); 38 | for iS = 5:size(boxes, 2) 39 | s = boxes(:,iS); 40 | [~, I] = sort(s); 41 | 42 | pick = s*0; 43 | counter = 1; 44 | while ~isempty(I) 45 | last = length(I); 46 | i = I(last); 47 | pick(counter) = i; 48 | counter = counter + 1; 49 | 50 | xx1 = max(x1(i), x1(I(1:last-1))); 51 | yy1 = max(y1(i), y1(I(1:last-1))); 52 | xx2 = min(x2(i), x2(I(1:last-1))); 53 | yy2 = min(y2(i), y2(I(1:last-1))); 54 | 55 | w = max(0.0, xx2-xx1+1); 56 | h = max(0.0, yy2-yy1+1); 57 | 58 | inter = w.*h; 59 | o = inter ./ (area(i) + area(I(1:last-1)) - inter); 60 | 61 | I = I(o<=overlap); 62 | end 63 | 64 | pick = pick(1:(counter-1)); 65 | picks{iS-4} = pick; 66 | end 67 | -------------------------------------------------------------------------------- /code/nms/nms_multiclass_mex.cpp: -------------------------------------------------------------------------------- 1 | #include "mex.h" 2 | #ifdef WIN32 3 | #include 4 | #include 5 | #else 6 | #include 7 | #endif 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | struct score { 14 | double s; 15 | int idx; 16 | bool operator() (score i, score j) { return (i.idx < j.idx);} 17 | } score; 18 | 19 | template 20 | void nms(const mxArray *input_boxes, int iScoreIdx, double overlap, const vector &vArea, vector &vPick, int &nPick) 21 | { 22 | int nSample = (int)mxGetM(input_boxes); 23 | int nDim_boxes = (int)mxGetN(input_boxes); 24 | 25 | T *pBoxes = (T*)mxGetData(input_boxes); 26 | 27 | //vector vArea(nSample); 28 | //for (int i = 0; i < nSample; ++i) 29 | //{ 30 | // vArea[i] = double(pBoxes[2*nSample + i] - pBoxes[0*nSample + i] + 1) 31 | // * (pBoxes[3*nSample + i] - pBoxes[1*nSample + i] + 1); 32 | // if (vArea[i] < 0) 33 | // mexErrMsgTxt("Boxes area must >= 0"); 34 | //} 35 | 36 | std::multimap scores; 37 | for (int i = 0; i < nSample; ++i) 38 | scores.insert(std::pair(pBoxes[iScoreIdx*nSample + i], i)); 39 | 40 | nPick = 0; 41 | 42 | do 43 | { 44 | int last = scores.rbegin()->second; 45 | vPick[nPick] = last; 46 | nPick += 1; 47 | 48 | for (typename std::multimap::iterator it = scores.begin(); it != scores.end();) 49 | { 50 | int it_idx = it->second; 51 | T xx1 = std::max(pBoxes[0*nSample + last], pBoxes[0*nSample + it_idx]); 52 | T yy1 = std::max(pBoxes[1*nSample + last], pBoxes[1*nSample + it_idx]); 53 | T xx2 = std::min(pBoxes[2*nSample + last], pBoxes[2*nSample + it_idx]); 54 | T yy2 = std::min(pBoxes[3*nSample + last], pBoxes[3*nSample + it_idx]); 55 | 56 | double w = max(0.0, xx2-xx1+1), h = max(0.0, yy2-yy1+1); 57 | 58 | double ov = w*h / (vArea[last] + vArea[it_idx] - w*h); 59 | 60 | if (ov > overlap) 61 | { 62 | #ifdef WIN32 63 | it = scores.erase(it); 64 | #else 65 | typename std::multimap::iterator save=it; ++save; 66 | scores.erase(it); 67 | it=save; 68 | #endif 69 | } 70 | else 71 | { 72 | it++; 73 | } 74 | } 75 | 76 | } while (scores.size() != 0); 77 | } 78 | 79 | 80 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]) 81 | { 82 | if (nrhs != 2) 83 | mexErrMsgTxt("Wrong number of inputs"); 84 | if (nlhs != 1) 85 | mexErrMsgTxt("One output"); 86 | 87 | const mxArray *input_boxes = prhs[0]; 88 | if (mxGetClassID(input_boxes) != mxDOUBLE_CLASS && mxGetClassID(input_boxes) != mxSINGLE_CLASS) 89 | mexErrMsgTxt("Input boxes must be Double or Single"); 90 | 91 | const mxArray *input_overlap = prhs[1]; 92 | if (mxGetClassID(input_overlap) != mxDOUBLE_CLASS ) 93 | mexErrMsgTxt("Input overlap must be Double"); 94 | 95 | double overlap = mxGetScalar(input_overlap); 96 | 97 | int nSample = (int)mxGetM(input_boxes); 98 | int nDim_boxes = (int)mxGetN(input_boxes); 99 | 100 | if (nSample * nDim_boxes == 0) 101 | { 102 | plhs[0] = mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL); 103 | return; 104 | } 105 | 106 | if (nDim_boxes < 5) 107 | mexErrMsgTxt("nms_mex boxes must has least 5 columns"); 108 | 109 | vector vArea(nSample); 110 | if(mxGetClassID(input_boxes) == mxDOUBLE_CLASS) 111 | { 112 | double *pBoxes = (double*)mxGetData(input_boxes); 113 | for (int i = 0; i < nSample; ++i) 114 | { 115 | vArea[i] = double(pBoxes[2*nSample + i] - pBoxes[0*nSample + i] + 1) 116 | * (pBoxes[3*nSample + i] - pBoxes[1*nSample + i] + 1); 117 | if (vArea[i] < 0) 118 | mexErrMsgTxt("Boxes area must >= 0"); 119 | } 120 | } 121 | else 122 | { 123 | if(mxGetClassID(input_boxes) == mxDOUBLE_CLASS) 124 | { 125 | float *pBoxes = (float*)mxGetData(input_boxes); 126 | for (int i = 0; i < nSample; ++i) 127 | { 128 | vArea[i] = double(pBoxes[2*nSample + i] - pBoxes[0*nSample + i] + 1) 129 | * (pBoxes[3*nSample + i] - pBoxes[1*nSample + i] + 1); 130 | if (vArea[i] < 0) 131 | mexErrMsgTxt("Boxes area must >= 0"); 132 | } 133 | } 134 | } 135 | 136 | vector nPick(nDim_boxes - 4, 0); 137 | vector > vPicks(nDim_boxes - 4); 138 | plhs[0] = mxCreateCellMatrix_730(nDim_boxes - 4, 1); 139 | 140 | #pragma omp parallel for ordered schedule(dynamic) 141 | for (int i = 0; i < vPicks.size(); ++i) 142 | { 143 | vPicks[i].resize(nSample); 144 | 145 | if(mxGetClassID(input_boxes) == mxDOUBLE_CLASS) 146 | nms(input_boxes, i+4, overlap, vArea, vPicks[i], nPick[i]); 147 | else 148 | nms(input_boxes, i+4, overlap, vArea, vPicks[i], nPick[i]); 149 | 150 | mxArray *mxPick = mxCreateNumericMatrix(nPick[i], 1, mxDOUBLE_CLASS, mxREAL); 151 | double *pRst = mxGetPr(mxPick); 152 | for (int j = 0; j < nPick[i]; ++j) 153 | pRst[j] = vPicks[i][j] + 1; 154 | 155 | mxSetCell(plhs[0], i, mxPick); 156 | } 157 | 158 | } -------------------------------------------------------------------------------- /code/nms/nvmex.m: -------------------------------------------------------------------------------- 1 | function nvmex(cuFileName, outDir) 2 | %NVMEX Compiles and links a CUDA file for MATLAB usage 3 | % NVMEX(FILENAME) will create a MEX-File (also with the name FILENAME) by 4 | % invoking the CUDA compiler, nvcc, and then linking with the MEX 5 | % function in MATLAB. 6 | 7 | if ispc % Windows 8 | Host_Compiler_Location = '-ccbin "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64"'; 9 | CUDA_INC_Location = ['"' getenv('CUDA_PATH') '\include"']; 10 | CUDA_SAMPLES_Location =['"' getenv('NVCUDASAMPLES6_5_ROOT') '\common\inc"']; 11 | PIC_Option = ''; 12 | if ( strcmp(computer('arch'),'win32') ==1) 13 | machine_str = ' --machine 32 '; 14 | CUDA_LIB_Location = ['"' getenv('CUDA_PATH') '\lib\Win32"']; 15 | elseif ( strcmp(computer('arch'),'win64') ==1) 16 | machine_str = ' --machine 64 '; 17 | CUDA_LIB_Location = ['"' getenv('CUDA_PATH') '\lib\x64"']; 18 | end 19 | NVCC = 'nvcc'; 20 | else % Mac and Linux (assuming gcc is on the path) 21 | CUDA_INC_Location = '/usr/local/cuda/include'; 22 | CUDA_SAMPLES_Location = '/usr/local/cuda/samples/common/inc'; 23 | Host_Compiler_Location = ' '; 24 | PIC_Option = ' --compiler-options -fPIC '; 25 | machine_str = []; 26 | CUDA_LIB_Location = '/usr/local/cuda/lib64'; 27 | NVCC = '/usr/local/cuda/bin/nvcc'; 28 | end 29 | % !!! End of things to modify !!! 30 | [~, filename] = fileparts(cuFileName); 31 | nvccCommandLine = [ ... 32 | NVCC ' --compile ' Host_Compiler_Location ' ' ... 33 | '-o ' filename '.o ' ... 34 | machine_str PIC_Option ... 35 | ' -I' '"' matlabroot '/extern/include "' ... 36 | ' -I' CUDA_INC_Location ' -I' CUDA_SAMPLES_Location ... 37 | ' "' cuFileName '" ' 38 | ]; 39 | mexCommandLine = ['mex ' '-outdir ' outDir ' ' filename '.o' ' -L' CUDA_LIB_Location ' -lcudart']; 40 | disp(nvccCommandLine); 41 | warning off; 42 | status = system(nvccCommandLine); 43 | warning on; 44 | if status < 0 45 | error 'Error invoking nvcc'; 46 | end 47 | disp(mexCommandLine); 48 | eval(mexCommandLine); 49 | end 50 | -------------------------------------------------------------------------------- /code/utils/RectLTRB2LTWH.m: -------------------------------------------------------------------------------- 1 | function [ rectsLTWH ] = RectLTRB2LTWH( rectsLTRB ) 2 | %rects (l, t, r, b) to (l, t, w, h) 3 | 4 | rectsLTWH = [rectsLTRB(:, 1), rectsLTRB(:, 2), rectsLTRB(:, 3)-rectsLTRB(:,1)+1, rectsLTRB(:,4)-rectsLTRB(:,2)+1]; 5 | end 6 | 7 | -------------------------------------------------------------------------------- /code/utils/RectLTWH2LTRB.m: -------------------------------------------------------------------------------- 1 | function [ rectsLTRB ] = RectLTWH2LTRB(rectsLTWH) 2 | %rects (l, t, r, b) to (l, t, w, h) 3 | 4 | rectsLTRB = [rectsLTWH(:, 1), rectsLTWH(:, 2), rectsLTWH(:, 1)+rectsLTWH(:,3)-1, rectsLTWH(:,2)+rectsLTWH(:,4)-1]; 5 | end 6 | 7 | -------------------------------------------------------------------------------- /code/utils/append_roi_weight.m: -------------------------------------------------------------------------------- 1 | function caffe_solver = append_roi_weight(solver_def_file, gpu_id, init_net_set) 2 | 3 | resNet_caffe = caffe.Solver(init_net_set{3}, 0); 4 | resNet_caffe.use_caffemodel(init_net_set{2}); 5 | 6 | % save the weights of resNet 7 | resNet_layer_names = resNet_caffe.nets{1}.layer_names; 8 | resNet_weights = []; 9 | cnt = 0; 10 | for i = 1:length(resNet_layer_names) 11 | 12 | curr_layer_name = resNet_layer_names{i}; 13 | for j = 1:10 14 | try 15 | curr_weight = resNet_caffe.nets{1}.params(curr_layer_name, j).get_data(); 16 | if j == 1, cnt = cnt + 1; end 17 | resNet_weights(cnt).layer_name = curr_layer_name; 18 | resNet_weights(cnt).weights{j} = curr_weight; 19 | catch 20 | break; 21 | end 22 | end 23 | 24 | end 25 | caffe.reset_all; 26 | stard_ind = 436; % 'res5a_branch1' 27 | end_ind = 465; % 'scale5c_branch2' 28 | 29 | caffe_solver = caffe.Solver(solver_def_file, gpu_id); 30 | net_names_debug = caffe_solver.nets{1}.layer_names; 31 | 32 | fprintf('copy first half weights from D15a model ...\n'); 33 | caffe_solver.use_caffemodel(init_net_set{1}); 34 | 35 | fprintf('copy second half weights from resNet model ...\n'); 36 | gpu_num = length(gpu_id); 37 | for i = stard_ind : end_ind 38 | for kk = 1:3 39 | curr_layer_name = sprintf('RPN%d_%s', kk, resNet_weights(i).layer_name); 40 | not_copy = false; 41 | 42 | for j = 1:length(resNet_weights(i).weights) 43 | for mm = 1:gpu_num 44 | try 45 | caffe_solver.nets{mm}.set_params_data(curr_layer_name, j, ... 46 | resNet_weights(i).weights{j}); 47 | catch 48 | warning('do not copy (%s) layer \n', curr_layer_name); 49 | not_copy = true; 50 | break; 51 | end 52 | end 53 | if not_copy, break; end 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /code/utils/assets/active_caffe_mex.m: -------------------------------------------------------------------------------- 1 | function active_caffe_mex(gpu_id, caffe_version) 2 | % active_caffe_mex(gpu_id, caffe_version) 3 | % -------------------------------------------------------- 4 | % Faster R-CNN 5 | % Copyright (c) 2015, Shaoqing Ren 6 | % Licensed under The MIT License [see LICENSE for details] 7 | % -------------------------------------------------------- 8 | 9 | % set gpu in matlab 10 | gpuDevice(gpu_id); 11 | 12 | if ~exist('caffe_version', 'var') || isempty(caffe_version) 13 | caffe_version = 'caffe'; 14 | end 15 | cur_dir = pwd; 16 | %caffe_dir = fullfile(pwd, 'external', 'caffe', 'matlab', caffe_version); 17 | caffe_dir = fullfile(pwd, 'external', 'caffe', 'matlab'); 18 | 19 | if ~exist(caffe_dir, 'dir') 20 | warning('Specified caffe folder (%s) does not exist, change to default one (%s)', ... 21 | caffe_dir, fullfile(pwd, 'external', 'caffe', 'matlab')); 22 | caffe_dir = fullfile(pwd, 'external', 'caffe', 'matlab'); 23 | end 24 | 25 | addpath(genpath(caffe_dir)); 26 | cd(caffe_dir); 27 | caffe.set_device(gpu_id-1); 28 | cd(cur_dir); 29 | end 30 | -------------------------------------------------------------------------------- /code/utils/assets/auto_select_gpu.m: -------------------------------------------------------------------------------- 1 | function gpu_id = auto_select_gpu() 2 | % gpu_id = auto_select_gpu() 3 | % Select the gpu which has the maximum free memory 4 | % -------------------------------------------------------- 5 | % Faster R-CNN 6 | % Copyright (c) 2015, Shaoqing Ren 7 | % Licensed under The MIT License [see LICENSE for details] 8 | % -------------------------------------------------------- 9 | 10 | % deselects all GPU devices 11 | gpuDevice([]); 12 | 13 | maxFreeMemory = 0; 14 | for i = 1:gpuDeviceCount 15 | g = gpuDevice(i); 16 | freeMemory = g.FreeMemory(); 17 | fprintf('GPU %d: free memory %d\n', i, freeMemory); 18 | if freeMemory > maxFreeMemory 19 | maxFreeMemory = freeMemory; 20 | gpu_id = i; 21 | end 22 | end 23 | fprintf('Use GPU %d\n', gpu_id); 24 | 25 | % deselects all GPU devices 26 | gpuDevice([]); 27 | end 28 | -------------------------------------------------------------------------------- /code/utils/assets/boxes_filter.m: -------------------------------------------------------------------------------- 1 | function aboxes = boxes_filter(aboxes, per_nms_topN, ... 2 | nms_overlap_thres, after_nms_topN) 3 | use_gpu = true; 4 | 5 | % to speed up nms 6 | if per_nms_topN > 0 7 | aboxes = aboxes(1:min(length(aboxes), per_nms_topN), :); 8 | end 9 | % do nms 10 | if nms_overlap_thres > 0 && nms_overlap_thres < 1 11 | aboxes = aboxes(nms(aboxes, nms_overlap_thres, use_gpu), :); 12 | end 13 | if after_nms_topN > 0 14 | aboxes = aboxes(1:min(length(aboxes), after_nms_topN), :); 15 | end 16 | end -------------------------------------------------------------------------------- /code/utils/assets/boxes_filter_inline_normal.m: -------------------------------------------------------------------------------- 1 | function aboxes = boxes_filter_inline_normal(aboxes, ... 2 | per_nms_topN, nms_overlap_thres, after_nms_topN, use_gpu) 3 | 4 | % to speed up nms (current = -1) 5 | % nms_overlap_thres = 0.7 6 | % after_nms_topN = 2000 7 | if per_nms_topN > 0 8 | aboxes = cellfun(@(x) x(1:min(length(x), per_nms_topN), :), aboxes, 'UniformOutput', false); 9 | end 10 | % do nms 11 | show_num = 1000; 12 | % fprintf('do nms during test, taking quite a while (brew some coffe or take a walk!:)...\n'); 13 | if nms_overlap_thres > 0 && nms_overlap_thres < 1 14 | if use_gpu 15 | for i = 1:length(aboxes) 16 | % if i == 1 || i == length(aboxes) || mod(i, show_num)==0 17 | % fprintf('\tgpu nms \t\t(%d/%d) \n', i, length(aboxes)); 18 | % end 19 | aboxes{i} = aboxes{i}(nms(aboxes{i}, nms_overlap_thres, use_gpu), :); 20 | end 21 | else 22 | parfor i = 1:length(aboxes) 23 | aboxes{i} = aboxes{i}(nms(aboxes{i}, nms_overlap_thres), :); 24 | end 25 | end 26 | end 27 | aver_boxes_num = mean(cellfun(@(x) size(x, 1), aboxes, 'UniformOutput', true)); 28 | fprintf('aver_boxes_num = %d, select top %d\n', round(aver_boxes_num), after_nms_topN); 29 | 30 | if after_nms_topN > 0 31 | aboxes = cellfun(@(x) x(1:min(size(x,1), after_nms_topN), :), aboxes, 'UniformOutput', false); 32 | end 33 | end 34 | 35 | 36 | -------------------------------------------------------------------------------- /code/utils/assets/change_edgebox.m: -------------------------------------------------------------------------------- 1 | function entry = change_edgebox( entry ) 2 | %UNTITLED Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | entry(:, 3) = entry(:, 1) + entry(:, 3) - 1; 6 | entry(:, 4) = entry(:, 2) + entry(:, 4) - 1; 7 | 8 | end 9 | 10 | -------------------------------------------------------------------------------- /code/utils/assets/check_im_num.m: -------------------------------------------------------------------------------- 1 | function check_im_num() 2 | % check image number 3 | clear; clc; 4 | % val1, train14 5 | 6 | val1_path = '../datasets/ilsvrc14_det/ILSVRC2014_devkit/data/det_lists/val1.txt'; 7 | val_bbox_path = '../datasets/ilsvrc14_det/ILSVRC2013_DET_bbox_val'; % no slash 8 | addpath('../datasets/ilsvrc14_det/ILSVRC2014_devkit/evaluation'); 9 | train_path = '../datasets/ilsvrc14_det/ILSVRC2014_devkit/data/det_lists/'; 10 | train_bbox_path = '../datasets/ilsvrc14_det/ILSVRC2014_DET_bbox_train'; % no slash 11 | 12 | fid = fopen(val1_path, 'r'); 13 | temp = textscan(fid, '%s%s'); 14 | val1_im_list = temp{1}; 15 | %[noGT_num_val1, list] = check(val1_im_list, val_bbox_path); 16 | 17 | for i = 1:200 18 | fid = fopen([train_path sprintf('train_pos_%d.txt', i)], 'r'); 19 | temp = textscan(fid, '%s'); 20 | train_list = temp{1}; 21 | % only train14 22 | train_list = train_list(cellfun(@(x) strcmp(x(1:10), 'ILSVRC2014'), train_list)); 23 | train(i).total_per_cls = length(train_list); 24 | [train(i).cnt, train(i).list] = check(train_list, train_bbox_path); 25 | end 26 | train_im_total = sum(extractfield(train, 'total_per_cls')); 27 | noGT_train_cnt = sum(extractfield(train, 'cnt')); 28 | 29 | function [no_gt_cnt_val1, no_gt_list_val1] = check(val1_im_list, val_bbox_path) 30 | 31 | no_gt_cnt_val1 = 0; 32 | no_gt_list_val1 = cell(1); 33 | for i = 1:length(val1_im_list) 34 | rec = VOCreadxml([val_bbox_path '/' val1_im_list{i} '.xml']); 35 | if ~isfield(rec.annotation, 'object') || isempty(rec.annotation.object) 36 | no_gt_cnt_val1 = no_gt_cnt_val1+1; 37 | no_gt_list_val1{no_gt_cnt_val1,1} = val1_im_list{i}; 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /code/utils/assets/compute_coco_mean.m: -------------------------------------------------------------------------------- 1 | % compute coco image mean 2 | 3 | train_set = './data/datasets/coco/train2014'; 4 | val_set = './data/datasets/coco/val2014'; 5 | 6 | ld = load('./model/pretrain/coco_mean_image_train.mat'); 7 | train_rgb = ld.train_rgb; 8 | 9 | % train_list = dir([train_set '/*.jpg']); 10 | % train_rgb = zeros(length(train_list), 3); 11 | % parfor i = 1:length(train_list) 12 | % im = imread([train_set '/' train_list(i).name]); 13 | % if size(im, 3) == 1 14 | % im = repmat(im, [1 1 3]); 15 | % end 16 | % train_rgb(i, :) = [mean(mean(im(:, :, 1))) ... 17 | % mean(mean(im(:, :, 2))) mean(mean(im(:, :, 3)))]; 18 | % end 19 | % disp(mean(train_rgb)); 20 | % save('./model/pretrain/coco_mean_image_train.mat', 'train_rgb'); 21 | 22 | val_list = dir([val_set '/*.jpg']); 23 | val_rgb = zeros(length(val_list), 3); 24 | 25 | parfor i = 1:length(val_list) 26 | im = imread([val_set '/' val_list(i).name]); 27 | if size(im, 3) == 1 28 | im = repmat(im, [1 1 3]); 29 | end 30 | val_rgb(i, :) = [mean(mean(im(:, :, 1))) ... 31 | mean(mean(im(:, :, 2))) mean(mean(im(:, :, 3)))]; 32 | end 33 | disp(mean(val_rgb)); 34 | save('./model/pretrain/coco_mean_image_val.mat', 'val_rgb'); 35 | 36 | image_mean = mean([train_rgb; val_rgb]); 37 | image_mean = single(reshape(image_mean, [1 1 3])); 38 | save('./model/pretrain/coco_mean_image.mat', 'image_mean'); 39 | -------------------------------------------------------------------------------- /code/utils/assets/extract_14train_only.m: -------------------------------------------------------------------------------- 1 | % make txt file to contain 14 train only 2 | 3 | file_path = '/home/hongyang/dataset/imagenet_det/ILSVRC2014_devkit/data/det_lists'; 4 | txt_path = dir([file_path '/train_pos_*.txt']); 5 | 6 | for i = 1:length(txt_path) 7 | 8 | fid = fopen([file_path '/' txt_path(i).name], 'r'); 9 | temp = textscan(fid, '%s'); 10 | im_list = temp{1}; 11 | 12 | fid2 = fopen([file_path '/' txt_path(i).name(1:end-4) '_hyli.txt'], 'w'); 13 | 14 | for j = 1:length(im_list) 15 | 16 | if strcmp(im_list{j}(1:10), 'ILSVRC2014') 17 | fprintf(fid2, [im_list{j} '\n']); 18 | end 19 | end 20 | fclose(fid); 21 | fclose(fid2); 22 | end -------------------------------------------------------------------------------- /code/utils/assets/generate_multi_nms_setting.m: -------------------------------------------------------------------------------- 1 | function set = generate_multi_nms_setting() 2 | % for rpn 3 | % model.stage1_rpn.nms.nms_iou_thrs = [0.90, 0.80, 0.75, 0.70, 0.65, 0.60, 0.55, 0.50]; 4 | % model.stage1_rpn.nms.max_per_image = [3000, 2000, 1000, 800, 400, 200, 100, 50]; 5 | 6 | nms_range{1} = [0.9 : -0.05 : 0.5]; 7 | nms_range{2} = [0.9 : -0.1 : 0.5]; 8 | 9 | max_im = [5000, 3000, 2000]; 10 | decay_factor = [0.9, 0.75, 0.6, 0.5]; 11 | 12 | cnt = 0; 13 | for i = 1:length(max_im) 14 | % if i == 3 15 | % keyboard; 16 | % end 17 | for j = 1:length(decay_factor) 18 | for k = 1:length(nms_range) 19 | cnt = cnt + 1; 20 | set(cnt).nms_iou_thrs = nms_range{k}; 21 | set(cnt).max_per_image = generate_vec(max_im(i), ... 22 | decay_factor(j), length(nms_range{k})); 23 | end 24 | end 25 | end 26 | 27 | function vec = generate_vec(max_im, decay, total_length) 28 | vec = zeros(total_length, 1); 29 | for kk = 1:total_length 30 | if kk == 1, vec(kk) = max_im; 31 | else vec(kk) = floor(decay*vec(kk-1)); end 32 | end 33 | end 34 | end -------------------------------------------------------------------------------- /code/utils/assets/generate_multi_nms_setting_fcn.m: -------------------------------------------------------------------------------- 1 | function set = generate_multi_nms_setting_fcn() 2 | % for fcn 3 | % model.stage1_rpn.nms.nms_iou_thrs = [0.90, 0.80, 0.75, 0.70, 0.65, 0.60, 0.55, 0.50]; 4 | % model.stage1_rpn.nms.max_per_image = [3000, 2000, 1000, 800, 400, 200, 100, 50]; 5 | 6 | nms_range{1} = [0.9 : -0.05 : 0.5]; 7 | nms_range{2} = [0.9 : -0.1 : 0.5]; 8 | 9 | max_im = [2000, 1800, 1500, 1300, 1000]; 10 | decay_factor = [0.9, 0.75, 0.6, 0.5, 0.3]; 11 | 12 | cnt = 0; 13 | for i = 1:length(max_im) 14 | % if i == 3 15 | % keyboard; 16 | % end 17 | for j = 1:length(decay_factor) 18 | for k = 1:length(nms_range) 19 | cnt = cnt + 1; 20 | set(cnt).nms_iou_thrs = nms_range{k}; 21 | set(cnt).max_per_image = generate_vec(max_im(i), ... 22 | decay_factor(j), length(nms_range{k})); 23 | end 24 | end 25 | end 26 | 27 | function vec = generate_vec(max_im, decay, total_length) 28 | vec = zeros(total_length, 1); 29 | for kk = 1:total_length 30 | if kk == 1, vec(kk) = max_im; 31 | else vec(kk) = floor(decay*vec(kk-1)); end 32 | end 33 | end 34 | end -------------------------------------------------------------------------------- /code/utils/assets/generate_train14_txt.m: -------------------------------------------------------------------------------- 1 | function generate_train14_txt() 2 | %GENERATE_TRAIN14_TXT Summary of this function goes here 3 | % Detailed explanation goes here 4 | addpath('../../datasets/ilsvrc14_det/ILSVRC2014_devkit/evaluation'); 5 | 6 | path = '/home/hongyang/dataset/imagenet_det/ILSVRC2014_DET_train/'; 7 | path_dir = dir([path 'ILSVRC2014_*']); 8 | 9 | train_bbox_path = '../../datasets/ilsvrc14_det/ILSVRC2014_DET_bbox_train'; % no slash 10 | 11 | % train14 12 | fid = fopen([path '../ILSVRC2014_devkit/data/det_lists/train14.txt'], 'w'); 13 | for i = 1:length(path_dir) 14 | 15 | im_dir = dir([path path_dir(i).name '/*.JPEG']); 16 | for j = 1:length(im_dir) 17 | 18 | rec = VOCreadxml([train_bbox_path '/' ... 19 | path_dir(i).name '/' im_dir(j).name(1:end-5) '.xml']); 20 | if ~(~isfield(rec.annotation, 'object') || isempty(rec.annotation.object)) 21 | fprintf(fid, [path_dir(i).name '/' im_dir(j).name(1:end-5) '\n']); 22 | end 23 | end 24 | end 25 | 26 | 27 | val_bbox_path = '../../datasets/ilsvrc14_det/ILSVRC2013_DET_bbox_val'; % no slash 28 | % val1 29 | fid = fopen([path '../ILSVRC2014_devkit/data/det_lists/val1.txt'], 'w'); 30 | fid_temp = fopen([path '../ILSVRC2014_devkit/data/det_lists/val1_original.txt'], 'r'); 31 | temp = textscan(fid_temp, '%s %d'); 32 | im_list = temp{1}; 33 | 34 | cnt = 0; 35 | for i = 1:length(im_list) 36 | 37 | rec = VOCreadxml([val_bbox_path '/' im_list{i} '.xml']); 38 | if ~(~isfield(rec.annotation, 'object') || isempty(rec.annotation.object)) 39 | cnt = cnt + 1; 40 | fprintf(fid, [im_list{i} ' ' sprintf('%d', cnt) '\n']); 41 | end 42 | end 43 | fclose(fid_temp); 44 | 45 | % val2 46 | fid = fopen([path '../ILSVRC2014_devkit/data/det_lists/val2.txt'], 'w'); 47 | fid_temp = fopen([path '../ILSVRC2014_devkit/data/det_lists/val2_original.txt'], 'r'); 48 | temp = textscan(fid_temp, '%s %d'); 49 | im_list = temp{1}; 50 | 51 | cnt = 0; 52 | for i = 1:length(im_list) 53 | 54 | rec = VOCreadxml([val_bbox_path '/' im_list{i} '.xml']); 55 | if ~(~isfield(rec.annotation, 'object') || isempty(rec.annotation.object)) 56 | cnt = cnt + 1; 57 | fprintf(fid, [im_list{i} ' ' sprintf('%d', cnt) '\n']); 58 | end 59 | end 60 | 61 | 62 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/AUTHORS.txt: -------------------------------------------------------------------------------- 1 | The author of "jsonlab" toolbox is Qianqian Fang. Qianqian 2 | is currently an Assistant Professor in the Department of Bioengineering, 3 | Northeastern University. 4 | 5 | Address: Qianqian Fang 6 | Department of Bioengineering 7 | Northeastern University 8 | 212A Lake Hall 9 | 360 Huntington Ave, Boston, MA 02115, USA 10 | Office: 503 Holmes Hall 11 | Phone[O]: 617-373-3829 12 | URL: http://fanglab.org 13 | Email: and 14 | 15 | 16 | The script loadjson.m was built upon previous works by 17 | 18 | - Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713 19 | date: 2009/11/02 20 | - François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393 21 | date: 2009/03/22 22 | - Joel Feenstra: http://www.mathworks.com/matlabcentral/fileexchange/20565 23 | date: 2008/07/03 24 | 25 | 26 | This toolbox contains patches submitted by the following contributors: 27 | 28 | - Blake Johnson 29 | part of revision 341 30 | 31 | - Niclas Borlin 32 | various fixes in revision 394, including 33 | - loadjson crashes for all-zero sparse matrix. 34 | - loadjson crashes for empty sparse matrix. 35 | - Non-zero size of 0-by-N and N-by-0 empty matrices is lost after savejson/loadjson. 36 | - loadjson crashes for sparse real column vector. 37 | - loadjson crashes for sparse complex column vector. 38 | - Data is corrupted by savejson for sparse real row vector. 39 | - savejson crashes for sparse complex row vector. 40 | 41 | - Yul Kang 42 | patches for svn revision 415. 43 | - savejson saves an empty cell array as [] instead of null 44 | - loadjson differentiates an empty struct from an empty array 45 | 46 | - Mykhailo Bratukha 47 | (Pull#14) Bug fix: File path is wrongly inerpreted as JSON string 48 | 49 | - Insik Kim 50 | (Pull#12) Bug fix: Resolving bug that cell type is converted to json with transposed data 51 | 52 | - Sertan Senturk 53 | (Pull#10,#11) Feature: Added matlab object saving to savejson and saveubjson 54 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/ChangeLog.txt: -------------------------------------------------------------------------------- 1 | ============================================================================ 2 | 3 | JSONlab - a toolbox to encode/decode JSON/UBJSON files in MATLAB/Octave 4 | 5 | ---------------------------------------------------------------------------- 6 | 7 | JSONlab ChangeLog (key features marked by *): 8 | 9 | == JSONlab 1.2 (codename: Optimus - Update 2), FangQ == 10 | 11 | 2015/12/16 replacing string concatenation by str cells to gain 2x speed in savejson (Issue#17) 12 | 2015/12/11 fix FileName option case bug (SVN rev#495) 13 | 2015/12/11 add SingletCell option, add SingletArray to replace NoRowBracket (Issue#15,#8) 14 | 2015/11/10 fix bug for inerpreting file names as JSON string - by Mykhailo Bratukha (Pull#14) 15 | 2015/10/16 fix bug for cell with transposed data - by Insik Kim (Pull#12) 16 | 2015/09/25 support exporting matlab object to JSON - by Sertan Senturk (Pull#10, #11) 17 | 18 | == JSONlab 1.1 (codename: Optimus - Update 1), FangQ == 19 | 20 | 2015/05/05 *massively accelerating loadjson for parsing large collection of unstructured small objects 21 | 2015/05/05 force array bracket in 1x1 struct to maintain depth (Issue#1) 22 | 2015/05/05 parse logicals in loadjson 23 | 2015/05/05 make options case insensitive 24 | 2015/05/01 reading unicode encoded json files (thanks to Sertan Senturk,Issue#3) 25 | 2015/04/30 allow \uXXXX to represent a unicode in a string (Issue#2) 26 | 2015/03/30 save a 0x0 solid real empty array as null and handel empty struct array 27 | 2015/03/30 properly handle escape characters in a string 28 | 2015/01/24 *implement the UBJSON Draft12 new name format 29 | 2015/01/13 correct cell array indentation inconsistency 30 | 31 | == JSONlab 1.0 (codename: Optimus - Final), FangQ == 32 | 33 | 2015/01/02 polish help info for all major functions, update examples, finalize 1.0 34 | 2014/12/19 fix a bug to strictly respect NoRowBracket in savejson 35 | 36 | == JSONlab 1.0.0-RC2 (codename: Optimus - RC2), FangQ == 37 | 38 | 2014/11/22 show progress bar in loadjson ('ShowProgress') 39 | 2014/11/17 *add Compact option in savejson to output compact JSON format ('Compact') 40 | 2014/11/17 add FastArrayParser in loadjson to specify fast parser applicable levels 41 | 2014/09/18 *start official github mirror: https://github.com/fangq/jsonlab 42 | 43 | == JSONlab 1.0.0-RC1 (codename: Optimus - RC1), FangQ == 44 | 45 | 2014/09/17 fix several compatibility issues when running on octave versions 3.2-3.8 46 | 2014/09/17 *support 2D cell and struct arrays in both savejson and saveubjson 47 | 2014/08/04 escape special characters in a JSON string 48 | 2014/02/16 fix a bug when saving ubjson files 49 | 50 | == JSONlab 0.9.9 (codename: Optimus - beta), FangQ == 51 | 52 | 2014/01/22 use binary read and write in saveubjson and loadubjson 53 | 54 | == JSONlab 0.9.8-1 (codename: Optimus - alpha update 1), FangQ == 55 | 56 | 2013/10/07 better round-trip conservation for empty arrays and structs (patch submitted by Yul Kang) 57 | 58 | == JSONlab 0.9.8 (codename: Optimus - alpha), FangQ == 59 | 2013/08/23 *universal Binary JSON (UBJSON) support, including both saveubjson and loadubjson 60 | 61 | == JSONlab 0.9.1 (codename: Rodimus, update 1), FangQ == 62 | 2012/12/18 *handling of various empty and sparse matrices (fixes submitted by Niclas Borlin) 63 | 64 | == JSONlab 0.9.0 (codename: Rodimus), FangQ == 65 | 66 | 2012/06/17 *new format for an invalid leading char, unpacking hex code in savejson 67 | 2012/06/01 support JSONP in savejson 68 | 2012/05/25 fix the empty cell bug (reported by Cyril Davin) 69 | 2012/04/05 savejson can save to a file (suggested by Patrick Rapin) 70 | 71 | == JSONlab 0.8.1 (codename: Sentiel, Update 1), FangQ == 72 | 73 | 2012/02/28 loadjson quotation mark escape bug, see http://bit.ly/yyk1nS 74 | 2012/01/25 patch to handle root-less objects, contributed by Blake Johnson 75 | 76 | == JSONlab 0.8.0 (codename: Sentiel), FangQ == 77 | 78 | 2012/01/13 *speed up loadjson by 20 fold when parsing large data arrays in matlab 79 | 2012/01/11 remove row bracket if an array has 1 element, suggested by Mykel Kochenderfer 80 | 2011/12/22 *accept sequence of 'param',value input in savejson and loadjson 81 | 2011/11/18 fix struct array bug reported by Mykel Kochenderfer 82 | 83 | == JSONlab 0.5.1 (codename: Nexus Update 1), FangQ == 84 | 85 | 2011/10/21 fix a bug in loadjson, previous code does not use any of the acceleration 86 | 2011/10/20 loadjson supports JSON collections - concatenated JSON objects 87 | 88 | == JSONlab 0.5.0 (codename: Nexus), FangQ == 89 | 90 | 2011/10/16 package and release jsonlab 0.5.0 91 | 2011/10/15 *add json demo and regression test, support cpx numbers, fix double quote bug 92 | 2011/10/11 *speed up readjson dramatically, interpret _Array* tags, show data in root level 93 | 2011/10/10 create jsonlab project, start jsonlab website, add online documentation 94 | 2011/10/07 *speed up savejson by 25x using sprintf instead of mat2str, add options support 95 | 2011/10/06 *savejson works for structs, cells and arrays 96 | 2011/09/09 derive loadjson from JSON parser from MATLAB Central, draft savejson.m 97 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/LICENSE_BSD.txt: -------------------------------------------------------------------------------- 1 | Copyright 2011-2015 Qianqian Fang . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are 4 | permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of 7 | conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 10 | of conditions and the following disclaimer in the documentation and/or other materials 11 | provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 15 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 16 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 20 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 21 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | 23 | The views and conclusions contained in the software and documentation are those of the 24 | authors and should not be interpreted as representing official policies, either expressed 25 | or implied, of the copyright holders. 26 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hli2020/zoom_network/a59f1c6b14cdbcf6124692bde4315ee8ab8bc961/code/utils/assets/jsonlab/README.txt -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/demo_jsonlab_basic.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Demonstration of Basic Utilities of JSONlab 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | 5 | rngstate = rand ('state'); 6 | randseed=hex2dec('623F9A9E'); 7 | clear data2json json2data 8 | 9 | fprintf(1,'\n%%=================================================\n') 10 | fprintf(1,'%% a simple scalar value \n') 11 | fprintf(1,'%%=================================================\n\n') 12 | 13 | data2json=pi 14 | savejson('',data2json) 15 | json2data=loadjson(ans) 16 | 17 | fprintf(1,'\n%%=================================================\n') 18 | fprintf(1,'%% a complex number\n') 19 | fprintf(1,'%%=================================================\n\n') 20 | 21 | clear i; 22 | data2json=1+2*i 23 | savejson('',data2json) 24 | json2data=loadjson(ans) 25 | 26 | fprintf(1,'\n%%=================================================\n') 27 | fprintf(1,'%% a complex matrix\n') 28 | fprintf(1,'%%=================================================\n\n') 29 | 30 | data2json=magic(6); 31 | data2json=data2json(:,1:3)+data2json(:,4:6)*i 32 | savejson('',data2json) 33 | json2data=loadjson(ans) 34 | 35 | fprintf(1,'\n%%=================================================\n') 36 | fprintf(1,'%% MATLAB special constants\n') 37 | fprintf(1,'%%=================================================\n\n') 38 | 39 | data2json=[NaN Inf -Inf] 40 | savejson('specials',data2json) 41 | json2data=loadjson(ans) 42 | 43 | fprintf(1,'\n%%=================================================\n') 44 | fprintf(1,'%% a real sparse matrix\n') 45 | fprintf(1,'%%=================================================\n\n') 46 | 47 | data2json=sprand(10,10,0.1) 48 | savejson('sparse',data2json) 49 | json2data=loadjson(ans) 50 | 51 | fprintf(1,'\n%%=================================================\n') 52 | fprintf(1,'%% a complex sparse matrix\n') 53 | fprintf(1,'%%=================================================\n\n') 54 | 55 | data2json=data2json-data2json*i 56 | savejson('complex_sparse',data2json) 57 | json2data=loadjson(ans) 58 | 59 | fprintf(1,'\n%%=================================================\n') 60 | fprintf(1,'%% an all-zero sparse matrix\n') 61 | fprintf(1,'%%=================================================\n\n') 62 | 63 | data2json=sparse(2,3); 64 | savejson('all_zero_sparse',data2json) 65 | json2data=loadjson(ans) 66 | 67 | fprintf(1,'\n%%=================================================\n') 68 | fprintf(1,'%% an empty sparse matrix\n') 69 | fprintf(1,'%%=================================================\n\n') 70 | 71 | data2json=sparse([]); 72 | savejson('empty_sparse',data2json) 73 | json2data=loadjson(ans) 74 | 75 | fprintf(1,'\n%%=================================================\n') 76 | fprintf(1,'%% an empty 0-by-0 real matrix\n') 77 | fprintf(1,'%%=================================================\n\n') 78 | 79 | data2json=[]; 80 | savejson('empty_0by0_real',data2json) 81 | json2data=loadjson(ans) 82 | 83 | fprintf(1,'\n%%=================================================\n') 84 | fprintf(1,'%% an empty 0-by-3 real matrix\n') 85 | fprintf(1,'%%=================================================\n\n') 86 | 87 | data2json=zeros(0,3); 88 | savejson('empty_0by3_real',data2json) 89 | json2data=loadjson(ans) 90 | 91 | fprintf(1,'\n%%=================================================\n') 92 | fprintf(1,'%% a sparse real column vector\n') 93 | fprintf(1,'%%=================================================\n\n') 94 | 95 | data2json=sparse([0,3,0,1,4]'); 96 | savejson('sparse_column_vector',data2json) 97 | json2data=loadjson(ans) 98 | 99 | fprintf(1,'\n%%=================================================\n') 100 | fprintf(1,'%% a sparse complex column vector\n') 101 | fprintf(1,'%%=================================================\n\n') 102 | 103 | data2json=data2json-1i*data2json; 104 | savejson('complex_sparse_column_vector',data2json) 105 | json2data=loadjson(ans) 106 | 107 | fprintf(1,'\n%%=================================================\n') 108 | fprintf(1,'%% a sparse real row vector\n') 109 | fprintf(1,'%%=================================================\n\n') 110 | 111 | data2json=sparse([0,3,0,1,4]); 112 | savejson('sparse_row_vector',data2json) 113 | json2data=loadjson(ans) 114 | 115 | fprintf(1,'\n%%=================================================\n') 116 | fprintf(1,'%% a sparse complex row vector\n') 117 | fprintf(1,'%%=================================================\n\n') 118 | 119 | data2json=data2json-1i*data2json; 120 | savejson('complex_sparse_row_vector',data2json) 121 | json2data=loadjson(ans) 122 | 123 | fprintf(1,'\n%%=================================================\n') 124 | fprintf(1,'%% a structure\n') 125 | fprintf(1,'%%=================================================\n\n') 126 | 127 | data2json=struct('name','Think Different','year',1997,'magic',magic(3),... 128 | 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false)) 129 | savejson('astruct',data2json,struct('ParseLogical',1)) 130 | json2data=loadjson(ans) 131 | class(json2data.astruct.embedded.left) 132 | 133 | fprintf(1,'\n%%=================================================\n') 134 | fprintf(1,'%% a structure array\n') 135 | fprintf(1,'%%=================================================\n\n') 136 | 137 | data2json=struct('name','Nexus Prime','rank',9); 138 | data2json(2)=struct('name','Sentinel Prime','rank',9); 139 | data2json(3)=struct('name','Optimus Prime','rank',9); 140 | savejson('Supreme Commander',data2json) 141 | json2data=loadjson(ans) 142 | 143 | fprintf(1,'\n%%=================================================\n') 144 | fprintf(1,'%% a cell array\n') 145 | fprintf(1,'%%=================================================\n\n') 146 | 147 | data2json=cell(3,1); 148 | data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,... 149 | 'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0); 150 | data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']); 151 | data2json{3}=[10.04,10.10,11.04,11.10] 152 | savejson('debian',data2json,struct('FloatFormat','%.2f')) 153 | json2data=loadjson(ans) 154 | 155 | fprintf(1,'\n%%=================================================\n') 156 | fprintf(1,'%% invalid field-name handling\n') 157 | fprintf(1,'%%=================================================\n\n') 158 | 159 | json2data=loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}') 160 | 161 | fprintf(1,'\n%%=================================================\n') 162 | fprintf(1,'%% a 2D cell array\n') 163 | fprintf(1,'%%=================================================\n\n') 164 | 165 | data2json={{1,{2,3}},{4,5},{6};{7},{8,9},{10}}; 166 | savejson('data2json',data2json) 167 | json2data=loadjson(ans) % only savejson works for cell arrays, loadjson has issues 168 | 169 | fprintf(1,'\n%%=================================================\n') 170 | fprintf(1,'%% a 2D struct array\n') 171 | fprintf(1,'%%=================================================\n\n') 172 | 173 | data2json=repmat(struct('idx',0,'data','structs'),[2,3]) 174 | for i=1:6 175 | data2json(i).idx=i; 176 | end 177 | savejson('data2json',data2json) 178 | json2data=loadjson(ans) 179 | 180 | rand ('state',rngstate); 181 | 182 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/demo_ubjson_basic.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Demonstration of Basic Utilities of JSONlab 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | 5 | rngstate = rand ('state'); 6 | randseed=hex2dec('623F9A9E'); 7 | clear data2json json2data 8 | 9 | fprintf(1,'\n%%=================================================\n') 10 | fprintf(1,'%% a simple scalar value \n') 11 | fprintf(1,'%%=================================================\n\n') 12 | 13 | data2json=pi 14 | saveubjson('',data2json) 15 | json2data=loadubjson(ans) 16 | 17 | fprintf(1,'\n%%=================================================\n') 18 | fprintf(1,'%% a complex number\n') 19 | fprintf(1,'%%=================================================\n\n') 20 | 21 | clear i; 22 | data2json=1+2*i 23 | saveubjson('',data2json) 24 | json2data=loadubjson(ans) 25 | 26 | fprintf(1,'\n%%=================================================\n') 27 | fprintf(1,'%% a complex matrix\n') 28 | fprintf(1,'%%=================================================\n\n') 29 | 30 | data2json=magic(6); 31 | data2json=data2json(:,1:3)+data2json(:,4:6)*i 32 | saveubjson('',data2json) 33 | json2data=loadubjson(ans) 34 | 35 | fprintf(1,'\n%%=================================================\n') 36 | fprintf(1,'%% MATLAB special constants\n') 37 | fprintf(1,'%%=================================================\n\n') 38 | 39 | data2json=[NaN Inf -Inf] 40 | saveubjson('specials',data2json) 41 | json2data=loadubjson(ans) 42 | 43 | fprintf(1,'\n%%=================================================\n') 44 | fprintf(1,'%% a real sparse matrix\n') 45 | fprintf(1,'%%=================================================\n\n') 46 | 47 | data2json=sprand(10,10,0.1) 48 | saveubjson('sparse',data2json) 49 | json2data=loadubjson(ans) 50 | 51 | fprintf(1,'\n%%=================================================\n') 52 | fprintf(1,'%% a complex sparse matrix\n') 53 | fprintf(1,'%%=================================================\n\n') 54 | 55 | data2json=data2json-data2json*i 56 | saveubjson('complex_sparse',data2json) 57 | json2data=loadubjson(ans) 58 | 59 | fprintf(1,'\n%%=================================================\n') 60 | fprintf(1,'%% an all-zero sparse matrix\n') 61 | fprintf(1,'%%=================================================\n\n') 62 | 63 | data2json=sparse(2,3); 64 | saveubjson('all_zero_sparse',data2json) 65 | json2data=loadubjson(ans) 66 | 67 | fprintf(1,'\n%%=================================================\n') 68 | fprintf(1,'%% an empty sparse matrix\n') 69 | fprintf(1,'%%=================================================\n\n') 70 | 71 | data2json=sparse([]); 72 | saveubjson('empty_sparse',data2json) 73 | json2data=loadubjson(ans) 74 | 75 | fprintf(1,'\n%%=================================================\n') 76 | fprintf(1,'%% an empty 0-by-0 real matrix\n') 77 | fprintf(1,'%%=================================================\n\n') 78 | 79 | data2json=[]; 80 | saveubjson('empty_0by0_real',data2json) 81 | json2data=loadubjson(ans) 82 | 83 | fprintf(1,'\n%%=================================================\n') 84 | fprintf(1,'%% an empty 0-by-3 real matrix\n') 85 | fprintf(1,'%%=================================================\n\n') 86 | 87 | data2json=zeros(0,3); 88 | saveubjson('empty_0by3_real',data2json) 89 | json2data=loadubjson(ans) 90 | 91 | fprintf(1,'\n%%=================================================\n') 92 | fprintf(1,'%% a sparse real column vector\n') 93 | fprintf(1,'%%=================================================\n\n') 94 | 95 | data2json=sparse([0,3,0,1,4]'); 96 | saveubjson('sparse_column_vector',data2json) 97 | json2data=loadubjson(ans) 98 | 99 | fprintf(1,'\n%%=================================================\n') 100 | fprintf(1,'%% a sparse complex column vector\n') 101 | fprintf(1,'%%=================================================\n\n') 102 | 103 | data2json=data2json-1i*data2json; 104 | saveubjson('complex_sparse_column_vector',data2json) 105 | json2data=loadubjson(ans) 106 | 107 | fprintf(1,'\n%%=================================================\n') 108 | fprintf(1,'%% a sparse real row vector\n') 109 | fprintf(1,'%%=================================================\n\n') 110 | 111 | data2json=sparse([0,3,0,1,4]); 112 | saveubjson('sparse_row_vector',data2json) 113 | json2data=loadubjson(ans) 114 | 115 | fprintf(1,'\n%%=================================================\n') 116 | fprintf(1,'%% a sparse complex row vector\n') 117 | fprintf(1,'%%=================================================\n\n') 118 | 119 | data2json=data2json-1i*data2json; 120 | saveubjson('complex_sparse_row_vector',data2json) 121 | json2data=loadubjson(ans) 122 | 123 | fprintf(1,'\n%%=================================================\n') 124 | fprintf(1,'%% a structure\n') 125 | fprintf(1,'%%=================================================\n\n') 126 | 127 | data2json=struct('name','Think Different','year',1997,'magic',magic(3),... 128 | 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false)) 129 | saveubjson('astruct',data2json,struct('ParseLogical',1)) 130 | json2data=loadubjson(ans) 131 | 132 | fprintf(1,'\n%%=================================================\n') 133 | fprintf(1,'%% a structure array\n') 134 | fprintf(1,'%%=================================================\n\n') 135 | 136 | data2json=struct('name','Nexus Prime','rank',9); 137 | data2json(2)=struct('name','Sentinel Prime','rank',9); 138 | data2json(3)=struct('name','Optimus Prime','rank',9); 139 | saveubjson('Supreme Commander',data2json) 140 | json2data=loadubjson(ans) 141 | 142 | fprintf(1,'\n%%=================================================\n') 143 | fprintf(1,'%% a cell array\n') 144 | fprintf(1,'%%=================================================\n\n') 145 | 146 | data2json=cell(3,1); 147 | data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,... 148 | 'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0); 149 | data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']); 150 | data2json{3}=[10.04,10.10,11.04,11.10] 151 | saveubjson('debian',data2json,struct('FloatFormat','%.2f')) 152 | json2data=loadubjson(ans) 153 | 154 | fprintf(1,'\n%%=================================================\n') 155 | fprintf(1,'%% invalid field-name handling\n') 156 | fprintf(1,'%%=================================================\n\n') 157 | 158 | json2data=loadubjson(saveubjson('',loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}'))) 159 | 160 | fprintf(1,'\n%%=================================================\n') 161 | fprintf(1,'%% a 2D cell array\n') 162 | fprintf(1,'%%=================================================\n\n') 163 | 164 | data2json={{1,{2,3}},{4,5},{6};{7},{8,9},{10}}; 165 | saveubjson('data2json',data2json) 166 | json2data=loadubjson(ans) % only savejson works for cell arrays, loadjson has issues 167 | 168 | fprintf(1,'\n%%=================================================\n') 169 | fprintf(1,'%% a 2D struct array\n') 170 | fprintf(1,'%%=================================================\n\n') 171 | 172 | data2json=repmat(struct('idx',0,'data','structs'),[2,3]) 173 | for i=1:6 174 | data2json(i).idx=i; 175 | end 176 | saveubjson('data2json',data2json) 177 | json2data=loadubjson(ans) 178 | 179 | rand ('state',rngstate); 180 | 181 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/example1.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "John", 3 | "lastName": "Smith", 4 | "age": 25, 5 | "address": 6 | { 7 | "streetAddress": "21 2nd Street", 8 | "city": "New York", 9 | "state": "NY", 10 | "postalCode": "10021" 11 | }, 12 | "phoneNumber": 13 | [ 14 | { 15 | "type": "home", 16 | "number": "212 555-1234" 17 | }, 18 | { 19 | "type": "fax", 20 | "number": "646 555-4567" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/example2.json: -------------------------------------------------------------------------------- 1 | { 2 | "glossary": { 3 | "title": "example glossary", 4 | "GlossDiv": { 5 | "title": "S", 6 | "GlossList": { 7 | "GlossEntry": { 8 | "ID": "SGML", 9 | "SortAs": "SGML", 10 | "GlossTerm": "Standard Generalized Markup Language", 11 | "Acronym": "SGML", 12 | "Abbrev": "ISO 8879:1986", 13 | "GlossDef": { 14 | "para": "A meta-markup language, used to create markup languages such as DocBook.", 15 | "GlossSeeAlso": ["GML", "XML"] 16 | }, 17 | "GlossSee": "markup" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/example3.json: -------------------------------------------------------------------------------- 1 | {"menu": { 2 | "id": "file", 3 | "value": "_&File", 4 | "popup": { 5 | "menuitem": [ 6 | {"value": "_&New", "onclick": "CreateNewDoc(\"'\\\"Untitled\\\"'\")"}, 7 | {"value": "_&Open", "onclick": "OpenDoc()"}, 8 | {"value": "_&Close", "onclick": "CloseDoc()"} 9 | ] 10 | } 11 | }} 12 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/example4.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "sample" : { 4 | "rho" : 1 5 | } 6 | }, 7 | { 8 | "sample" : { 9 | "rho" : 2 10 | } 11 | }, 12 | [ 13 | { 14 | "_ArrayType_" : "double", 15 | "_ArraySize_" : [1,2], 16 | "_ArrayData_" : [1,0] 17 | }, 18 | { 19 | "_ArrayType_" : "double", 20 | "_ArraySize_" : [1,2], 21 | "_ArrayData_" : [1,1] 22 | }, 23 | { 24 | "_ArrayType_" : "double", 25 | "_ArraySize_" : [1,2], 26 | "_ArrayData_" : [1,2] 27 | } 28 | ], 29 | [ 30 | "Paper", 31 | "Scissors", 32 | "Stone" 33 | ], 34 | ["a", "b\\", "c\"","d\\\"","e\"[","f\\\"[","g[\\","h[\\\""] 35 | ] 36 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/jsonlab_selftest.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Regression Test Unit of loadjson and savejson 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | 5 | for i=1:4 6 | fname=sprintf('example%d.json',i); 7 | if(exist(fname,'file')==0) break; end 8 | fprintf(1,'===============================================\n>> %s\n',fname); 9 | json=savejson('data',loadjson(fname)); 10 | fprintf(1,'%s\n',json); 11 | fprintf(1,'%s\n',savejson('data',loadjson(fname),'Compact',1)); 12 | data=loadjson(json); 13 | savejson('data',data,'selftest.json'); 14 | data=loadjson('selftest.json'); 15 | end 16 | 17 | for i=1:4 18 | fname=sprintf('example%d.json',i); 19 | if(exist(fname,'file')==0) break; end 20 | fprintf(1,'===============================================\n>> %s\n',fname); 21 | json=saveubjson('data',loadjson(fname)); 22 | fprintf(1,'%s\n',json); 23 | data=loadubjson(json); 24 | savejson('',data); 25 | saveubjson('data',data,'selftest.ubj'); 26 | data=loadubjson('selftest.ubj'); 27 | end 28 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/examples/jsonlab_speedtest.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Benchmarking processing speed of savejson and loadjson 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | 5 | datalen=[1e3 1e4 1e5 1e6]; 6 | len=length(datalen); 7 | tsave=zeros(len,1); 8 | tload=zeros(len,1); 9 | for i=1:len 10 | tic; 11 | json=savejson('data',struct('d1',rand(datalen(i),3),'d2',rand(datalen(i),3)>0.5)); 12 | tsave(i)=toc; 13 | data=loadjson(json); 14 | tload(i)=toc-tsave(i); 15 | fprintf(1,'matrix size: %d\n',datalen(i)); 16 | end 17 | 18 | loglog(datalen,tsave,'o-',datalen,tload,'r*-'); 19 | legend('savejson runtime (s)','loadjson runtime (s)'); 20 | xlabel('array size'); 21 | ylabel('running time (s)'); 22 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/jsonopt.m: -------------------------------------------------------------------------------- 1 | function val=jsonopt(key,default,varargin) 2 | % 3 | % val=jsonopt(key,default,optstruct) 4 | % 5 | % setting options based on a struct. The struct can be produced 6 | % by varargin2struct from a list of 'param','value' pairs 7 | % 8 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 9 | % 10 | % $Id: loadjson.m 371 2012-06-20 12:43:06Z fangq $ 11 | % 12 | % input: 13 | % key: a string with which one look up a value from a struct 14 | % default: if the key does not exist, return default 15 | % optstruct: a struct where each sub-field is a key 16 | % 17 | % output: 18 | % val: if key exists, val=optstruct.key; otherwise val=default 19 | % 20 | % license: 21 | % BSD License, see LICENSE_BSD.txt files for details 22 | % 23 | % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 24 | % 25 | 26 | val=default; 27 | if(nargin<=2) return; end 28 | opt=varargin{1}; 29 | if(isstruct(opt)) 30 | if(isfield(opt,key)) 31 | val=getfield(opt,key); 32 | elseif(isfield(opt,lower(key))) 33 | val=getfield(opt,lower(key)); 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/mergestruct.m: -------------------------------------------------------------------------------- 1 | function s=mergestruct(s1,s2) 2 | % 3 | % s=mergestruct(s1,s2) 4 | % 5 | % merge two struct objects into one 6 | % 7 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 8 | % date: 2012/12/22 9 | % 10 | % input: 11 | % s1,s2: a struct object, s1 and s2 can not be arrays 12 | % 13 | % output: 14 | % s: the merged struct object. fields in s1 and s2 will be combined in s. 15 | % 16 | % license: 17 | % BSD License, see LICENSE_BSD.txt files for details 18 | % 19 | % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 20 | % 21 | 22 | if(~isstruct(s1) || ~isstruct(s2)) 23 | error('input parameters contain non-struct'); 24 | end 25 | if(length(s1)>1 || length(s2)>1) 26 | error('can not merge struct arrays'); 27 | end 28 | fn=fieldnames(s2); 29 | s=s1; 30 | for i=1:length(fn) 31 | s=setfield(s,fn{i},getfield(s2,fn{i})); 32 | end 33 | 34 | -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/struct2jdata.m: -------------------------------------------------------------------------------- 1 | function newdata=struct2jdata(data,varargin) 2 | % 3 | % newdata=struct2jdata(data,opt,...) 4 | % 5 | % convert a JData object (in the form of a struct array) into an array 6 | % 7 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 8 | % 9 | % input: 10 | % data: a struct array. If data contains JData keywords in the first 11 | % level children, these fields are parsed and regrouped into a 12 | % data object (arrays, trees, graphs etc) based on JData 13 | % specification. The JData keywords are 14 | % "_ArrayType_", "_ArraySize_", "_ArrayData_" 15 | % "_ArrayIsSparse_", "_ArrayIsComplex_" 16 | % opt: (optional) a list of 'Param',value pairs for additional options 17 | % The supported options include 18 | % 'Recursive', if set to 1, will apply the conversion to 19 | % every child; 0 to disable 20 | % 21 | % output: 22 | % newdata: the covnerted data if the input data does contain a JData 23 | % structure; otherwise, the same as the input. 24 | % 25 | % examples: 26 | % obj=struct('_ArrayType_','double','_ArraySize_',[2 3], 27 | % '_ArrayIsSparse_',1 ,'_ArrayData_',null); 28 | % ubjdata=struct2jdata(obj); 29 | % 30 | % license: 31 | % BSD License, see LICENSE_BSD.txt files for details 32 | % 33 | % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 34 | % 35 | 36 | fn=fieldnames(data); 37 | newdata=data; 38 | len=length(data); 39 | if(jsonopt('Recursive',0,varargin{:})==1) 40 | for i=1:length(fn) % depth-first 41 | for j=1:len 42 | if(isstruct(getfield(data(j),fn{i}))) 43 | newdata(j)=setfield(newdata(j),fn{i},jstruct2array(getfield(data(j),fn{i}))); 44 | end 45 | end 46 | end 47 | end 48 | if(~isempty(strmatch('x0x5F_ArrayType_',fn)) && ~isempty(strmatch('x0x5F_ArrayData_',fn))) 49 | newdata=cell(len,1); 50 | for j=1:len 51 | ndata=cast(data(j).x0x5F_ArrayData_,data(j).x0x5F_ArrayType_); 52 | iscpx=0; 53 | if(~isempty(strmatch('x0x5F_ArrayIsComplex_',fn))) 54 | if(data(j).x0x5F_ArrayIsComplex_) 55 | iscpx=1; 56 | end 57 | end 58 | if(~isempty(strmatch('x0x5F_ArrayIsSparse_',fn))) 59 | if(data(j).x0x5F_ArrayIsSparse_) 60 | if(~isempty(strmatch('x0x5F_ArraySize_',fn))) 61 | dim=double(data(j).x0x5F_ArraySize_); 62 | if(iscpx && size(ndata,2)==4-any(dim==1)) 63 | ndata(:,end-1)=complex(ndata(:,end-1),ndata(:,end)); 64 | end 65 | if isempty(ndata) 66 | % All-zeros sparse 67 | ndata=sparse(dim(1),prod(dim(2:end))); 68 | elseif dim(1)==1 69 | % Sparse row vector 70 | ndata=sparse(1,ndata(:,1),ndata(:,2),dim(1),prod(dim(2:end))); 71 | elseif dim(2)==1 72 | % Sparse column vector 73 | ndata=sparse(ndata(:,1),1,ndata(:,2),dim(1),prod(dim(2:end))); 74 | else 75 | % Generic sparse array. 76 | ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3),dim(1),prod(dim(2:end))); 77 | end 78 | else 79 | if(iscpx && size(ndata,2)==4) 80 | ndata(:,3)=complex(ndata(:,3),ndata(:,4)); 81 | end 82 | ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3)); 83 | end 84 | end 85 | elseif(~isempty(strmatch('x0x5F_ArraySize_',fn))) 86 | if(iscpx && size(ndata,2)==2) 87 | ndata=complex(ndata(:,1),ndata(:,2)); 88 | end 89 | ndata=reshape(ndata(:),data(j).x0x5F_ArraySize_); 90 | end 91 | newdata{j}=ndata; 92 | end 93 | if(len==1) 94 | newdata=newdata{1}; 95 | end 96 | end -------------------------------------------------------------------------------- /code/utils/assets/jsonlab/varargin2struct.m: -------------------------------------------------------------------------------- 1 | function opt=varargin2struct(varargin) 2 | % 3 | % opt=varargin2struct('param1',value1,'param2',value2,...) 4 | % or 5 | % opt=varargin2struct(...,optstruct,...) 6 | % 7 | % convert a series of input parameters into a structure 8 | % 9 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 10 | % date: 2012/12/22 11 | % 12 | % input: 13 | % 'param', value: the input parameters should be pairs of a string and a value 14 | % optstruct: if a parameter is a struct, the fields will be merged to the output struct 15 | % 16 | % output: 17 | % opt: a struct where opt.param1=value1, opt.param2=value2 ... 18 | % 19 | % license: 20 | % BSD License, see LICENSE_BSD.txt files for details 21 | % 22 | % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 23 | % 24 | 25 | len=length(varargin); 26 | opt=struct; 27 | if(len==0) return; end 28 | i=1; 29 | while(i<=len) 30 | if(isstruct(varargin{i})) 31 | opt=mergestruct(opt,varargin{i}); 32 | elseif(ischar(varargin{i}) && i max_size 9 | im_scale = double(max_size) / double(im_size_max); 10 | end 11 | end -------------------------------------------------------------------------------- /code/utils/assets/print_model.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import argparse 4 | import sys 5 | sys.path.insert(0, '/home/hongyang/project/faster_rcnn/external/caffe/python/caffe/proto') 6 | #import caffe 7 | from caffe_pb2 import NetParameter 8 | 9 | if __name__ == '__main__': 10 | parser = argparse.ArgumentParser( 11 | 'Copy and rename certain layers into another model.') 12 | parser.add_argument('model', type=str, 13 | help='Source model.') 14 | args = parser.parse_args() 15 | 16 | source_model = NetParameter.FromString(open(args.model, 'rb').read()) 17 | 18 | for layer in source_model.layer: 19 | print layer.name 20 | -------------------------------------------------------------------------------- /code/utils/assets/proposal_prepare_anchors.m: -------------------------------------------------------------------------------- 1 | function [anchors, output_width_map, output_height_map] = ... 2 | proposal_prepare_anchors(conf, cache_name, test_net_def_file) 3 | 4 | [output_width_map, output_height_map] = ... 5 | proposal_calc_output_size(conf, test_net_def_file); 6 | 7 | anchors = proposal_generate_anchors(cache_name, 'scales', 2.^[3:5]); 8 | end -------------------------------------------------------------------------------- /code/utils/assets/show_box_simple.m: -------------------------------------------------------------------------------- 1 | function show_box_simple( im, boxes, color ) 2 | %SHOW_BOX_SIMPLE Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | linewidth = 2; 6 | if nargin < 3 7 | color = 'r'; 8 | end 9 | 10 | hold on; 11 | for i = 1:size(boxes, 1) 12 | box = boxes(i, :); 13 | rectangle('Position', RectLTRB2LTWH(box), 'LineWidth', linewidth, 'EdgeColor', color); 14 | end 15 | hold off; 16 | 17 | function [ rectsLTWH ] = RectLTRB2LTWH( rectsLTRB ) 18 | %rects (l, t, r, b) to (l, t, w, h) 19 | rectsLTWH = [rectsLTRB(:, 1), rectsLTRB(:, 2), rectsLTRB(:, 3)-rectsLTRB(:,1)+1, rectsLTRB(:,4)-rectsLTRB(2)+1]; 20 | end 21 | end -------------------------------------------------------------------------------- /code/utils/assets/showboxes.m: -------------------------------------------------------------------------------- 1 | function showboxes(im, boxes, legends, color_conf) 2 | % Draw bounding boxes on top of an image. 3 | % showboxes(im, boxes) 4 | % 5 | % ------------------------------------------------------- 6 | 7 | fix_width = 800; 8 | if isa(im, 'gpuArray') 9 | im = gather(im); 10 | end 11 | imsz = size(im); 12 | scale = fix_width / imsz(2); 13 | im = imresize(im, scale); 14 | 15 | if size(boxes{1}, 2) >= 5 16 | boxes = cellfun(@(x) [x(:, 1:4) * scale, x(:, 5)], boxes, 'UniformOutput', false); 17 | else 18 | boxes = cellfun(@(x) x(:, 1:4) * scale, boxes, 'UniformOutput', false); 19 | end 20 | 21 | if ~exist('color_conf', 'var') 22 | color_conf = 'default'; 23 | end 24 | 25 | image(im); 26 | axis image; 27 | axis off; 28 | set(gcf, 'Color', 'white'); 29 | 30 | valid_boxes = cellfun(@(x) ~isempty(x), boxes, 'UniformOutput', true); 31 | valid_boxes_num = sum(valid_boxes); 32 | 33 | if valid_boxes_num > 0 34 | switch color_conf 35 | case 'default' 36 | colors_candidate = colormap('hsv'); 37 | colors_candidate = colors_candidate(1:(floor(size(colors_candidate, 1)/valid_boxes_num)):end, :); 38 | colors_candidate = mat2cell(colors_candidate, ones(size(colors_candidate, 1), 1))'; 39 | colors = cell(size(valid_boxes)); 40 | colors(valid_boxes) = colors_candidate(1:sum(valid_boxes)); 41 | case 'voc' 42 | colors_candidate = colormap('hsv'); 43 | colors_candidate = colors_candidate(1:(floor(size(colors_candidate, 1)/20)):end, :); 44 | colors_candidate = mat2cell(colors_candidate, ones(size(colors_candidate, 1), 1))'; 45 | colors = colors_candidate; 46 | end 47 | 48 | 49 | for i = 1:length(boxes) 50 | if isempty(boxes{i}) 51 | continue; 52 | end 53 | 54 | for j = 1:size(boxes{i}) 55 | box = boxes{i}(j, 1:4); 56 | if size(boxes{i}, 2) >= 5 57 | score = boxes{i}(j, end); 58 | linewidth = 2 + min(max(score, 0), 1) * 2; 59 | rectangle('Position', RectLTRB2LTWH(box), 'LineWidth', linewidth, 'EdgeColor', colors{i}); 60 | label = sprintf('%s : %.3f', legends{i}, score); 61 | text(double(box(1))+2, double(box(2)), label, 'BackgroundColor', 'w'); 62 | else 63 | linewidth = 2; 64 | rectangle('Position', RectLTRB2LTWH(box), 'LineWidth', linewidth, 'EdgeColor', colors{i}); 65 | label = sprintf('%s(%d)', legends{i}, i); 66 | text(double(box(1))+2, double(box(2)), label, 'BackgroundColor', 'w'); 67 | end 68 | end 69 | 70 | end 71 | end 72 | end 73 | 74 | function [ rectsLTWH ] = RectLTRB2LTWH( rectsLTRB ) 75 | %rects (l, t, r, b) to (l, t, w, h) 76 | rectsLTWH = [rectsLTRB(:, 1), rectsLTRB(:, 2), rectsLTRB(:, 3)-rectsLTRB(:,1)+1, rectsLTRB(:,4)-rectsLTRB(2)+1]; 77 | end 78 | 79 | -------------------------------------------------------------------------------- /code/utils/assets/split_json_file.py: -------------------------------------------------------------------------------- 1 | import json 2 | import math 3 | 4 | root = '/home/hongyang/project/externalBox/data_I_want_coco/' 5 | data_name = root + 'deepmask-coco-val-bbox/deepmaskZoom_bbox_coco_val.json' 6 | chunk_num = 50000.0 7 | 8 | with open(data_name) as data_file: 9 | data = json.load(data_file) 10 | # data = range(15) 11 | iter_length = int(math.ceil(len(data)/chunk_num)) 12 | 13 | for i in range(iter_length): 14 | 15 | start_id = int(i*chunk_num) 16 | end_id = int(min(chunk_num + i*chunk_num, len(data))) 17 | curr_data = data[start_id:end_id] 18 | 19 | save_name = 'split_ck_%d_total_%d.json' % (i+1, iter_length) 20 | with open(save_name, 'w') as outfile: 21 | json.dump(curr_data, outfile, ensure_ascii=False) 22 | 23 | print 'process iter: %d, total: %d\n' (i+1, iter_length) 24 | -------------------------------------------------------------------------------- /code/utils/assets/stats_opt.m: -------------------------------------------------------------------------------- 1 | function res = stats_opt(x, y, mode) 2 | 3 | switch mode 4 | case 'norm' 5 | res = [x(1)/y(2) x(2)/y(1) x(3)/y(2) x(4)/y(1)]; 6 | end 7 | end -------------------------------------------------------------------------------- /code/utils/assets/subsample_images.m: -------------------------------------------------------------------------------- 1 | function [imdbs, roidbs] = subsample_images(imdbs, roidbs, max_num_neg_images, seed) 2 | 3 | if ~exist('seed', 'var') 4 | seed = 6; 5 | end 6 | 7 | % class_num = cellfun(@(x) length(x.class_ids), imdbs, 'UniformOutput', true); 8 | % assert(length(unique(class_num)) == 1); 9 | % class_num = unique(class_num); 10 | 11 | rois = cellfun(@(x) x.rois(:), roidbs, 'UniformOutput', false); 12 | rois_combine = cell2mat(rois(:)); 13 | 14 | % fix the random seed for repeatability 15 | prev_rng = seed_rand(seed); 16 | inds = randperm(length(rois_combine), max_num_neg_images); 17 | inds = sort(inds); 18 | 19 | img_idx_start = 1; 20 | for i = 1:length(imdbs) 21 | imdb_img_num = length(imdbs{i}.image_ids); 22 | img_idx_end = img_idx_start + imdb_img_num - 1; 23 | inds_start = find(inds >= img_idx_start, 1, 'first'); 24 | inds_end = find(inds <= img_idx_end, 1, 'last'); 25 | 26 | inds_sub = inds(inds_start:inds_end); 27 | inds_sub = inds_sub - img_idx_start + 1; 28 | 29 | imdbs{i}.image_ids = imdbs{i}.image_ids(inds_sub); 30 | imdbs{i}.sizes = imdbs{i}.sizes(inds_sub, :); 31 | if isfield(imdbs{i}, 'image_dir') 32 | imdbs{i}.image_at = @(x) ... 33 | sprintf('%s/%s.%s', imdbs{i}.image_dir, imdbs{i}.image_ids{x}, imdbs{i}.extension); 34 | else 35 | imdbs{i}.image_at = @(x) ... 36 | sprintf('%s/%s.%s', imdbs{i}.imagedir, imdbs{i}.image_ids{x}, imdbs{i}.extension); 37 | end 38 | roidbs{i}.rois = roidbs{i}.rois(inds_sub); 39 | 40 | img_idx_start = img_idx_start + imdb_img_num; 41 | end 42 | 43 | % restore previous rng 44 | rng(prev_rng); 45 | 46 | end -------------------------------------------------------------------------------- /code/utils/assets/subsample_images_per_class.m: -------------------------------------------------------------------------------- 1 | function [imdbs, roidbs] = subsample_images_per_class(imdbs, roidbs, max_per_class_image_num, seed) 2 | 3 | if ~exist('seed', 'var') 4 | seed = 6; 5 | end 6 | 7 | class_num = cellfun(@(x) length(x.class_ids), imdbs, 'UniformOutput', true); 8 | assert(length(unique(class_num)) == 1); 9 | class_num = unique(class_num); 10 | 11 | rois = cellfun(@(x) x.rois, roidbs, 'UniformOutput', false); 12 | rois_combine = cell2mat(rois(:)); 13 | rois_combine_class = arrayfun(@(x) x.class, rois_combine, 'UniformOutput', false); 14 | 15 | %% select images with max_image_num 16 | 17 | % fix the random seed for repeatability 18 | prev_rng = seed_rand(seed); 19 | inds = cell(class_num, 1); 20 | rois_combine_length = length(rois_combine); 21 | valid_idxs = cell(class_num, 1); 22 | parfor i = 1:class_num 23 | valid_idxs{i} = cellfun(@(x) any(x == i), rois_combine_class, 'UniformOutput', false); 24 | valid_idxs{i} = cell2mat(valid_idxs{i}); 25 | end 26 | 27 | for i = 1:class_num 28 | valid_num = sum(valid_idxs{i}); 29 | 30 | num = min(valid_num, max_per_class_image_num); 31 | inds{i} = 1:rois_combine_length; 32 | inds{i} = inds{i}(valid_idxs{i}); 33 | inds{i} = inds{i}(randperm(length(inds{i}), num)); 34 | end 35 | 36 | inds = cell2mat(inds')'; 37 | inds = unique(inds); 38 | 39 | % restore previous rng 40 | rng(prev_rng); 41 | 42 | img_idx_start = 1; 43 | for i = 1:length(imdbs) 44 | imdb_img_num = length(imdbs{i}.image_ids); 45 | img_idx_end = img_idx_start + imdb_img_num - 1; 46 | inds_start = find(inds >= img_idx_start, 1, 'first'); 47 | inds_end = find(inds <= img_idx_end, 1, 'last'); 48 | 49 | inds_sub = inds(inds_start:inds_end); 50 | inds_sub = inds_sub - img_idx_start + 1; 51 | 52 | imdbs{i}.image_ids = imdbs{i}.image_ids(inds_sub); 53 | imdbs{i}.sizes = imdbs{i}.sizes(inds_sub, :); 54 | if isfield(imdbs{i}, 'image_dir') 55 | imdbs{i}.image_at = @(x) ... 56 | sprintf('%s/%s.%s', imdbs{i}.image_dir, imdbs{i}.image_ids{x}, imdbs{i}.extension); 57 | else 58 | imdbs{i}.image_at = @(x) ... 59 | sprintf('%s/%s.%s', imdbs{i}.imagedir, imdbs{i}.image_ids{x}, imdbs{i}.extension); 60 | end 61 | roidbs{i}.rois = roidbs{i}.rois(inds_sub); 62 | 63 | img_idx_start = img_idx_start + imdb_img_num; 64 | end 65 | 66 | 67 | -------------------------------------------------------------------------------- /code/utils/assets/symbolic_link.m: -------------------------------------------------------------------------------- 1 | function symbolic_link(link, target) 2 | % symbolic_link(link, target) 3 | % -------------------------------------------------------- 4 | % Faster R-CNN 5 | % Copyright (c) 2015, Shaoqing Ren 6 | % Licensed under The MIT License [see LICENSE for details] 7 | % -------------------------------------------------------- 8 | 9 | if ispc() 10 | system(sprintf('mklink /J %s %s', link, target)); 11 | else 12 | system(sprintf('ln -s %s %s', link, target)); 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /code/utils/assets/vis_label.m: -------------------------------------------------------------------------------- 1 | function vis_label(imdb, roidb) 2 | 3 | rois = roidb.rois; 4 | for iIM = 1:length(rois) 5 | im = imread(imdb.image_at(iIM)); 6 | boxes = arrayfun(@(x) rois(iIM).boxes(rois(iIM).class == x, :), 1:length(imdb.classes), 'UniformOutput', false); 7 | legends = imdb.classes; 8 | showboxes(im, boxes, legends); 9 | pause; 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /code/utils/assets/xVOCap.m: -------------------------------------------------------------------------------- 1 | function ap = xVOCap(rec,prec) 2 | % From the PASCAL VOC 2011 devkit 3 | 4 | mrec=[0 ; rec ; 1]; 5 | mpre=[0 ; prec ; 0]; 6 | for i=numel(mpre)-1:-1:1 7 | mpre(i)=max(mpre(i),mpre(i+1)); 8 | end 9 | i=find(mrec(2:end)~=mrec(1:end-1))+1; 10 | ap=sum((mrec(i)-mrec(i-1)).*mpre(i)); 11 | -------------------------------------------------------------------------------- /code/utils/assets/xVOChash_init.m: -------------------------------------------------------------------------------- 1 | function hash = xVOChash_init(strs) 2 | % From the PASCAL VOC 2011 devkit 3 | 4 | hsize=4999; 5 | hash.key=cell(hsize,1); 6 | hash.val=cell(hsize,1); 7 | 8 | for i=1:numel(strs) 9 | s=strs{i}; 10 | h=mod(str2double(s([4 6:end])),hsize)+1; 11 | j=numel(hash.key{h})+1; 12 | hash.key{h}{j}=strs{i}; 13 | hash.val{h}(j)=i; 14 | end 15 | 16 | -------------------------------------------------------------------------------- /code/utils/assets/xVOChash_lookup.m: -------------------------------------------------------------------------------- 1 | function ind = xVOChash_lookup(hash,s) 2 | % From the PASCAL VOC 2011 devkit 3 | 4 | hsize=numel(hash.key); 5 | h=mod(str2double(s([4 6:end])),hsize)+1; 6 | ind=hash.val{h}(strmatch(s,hash.key{h},'exact')); 7 | -------------------------------------------------------------------------------- /code/utils/box_vote.m: -------------------------------------------------------------------------------- 1 | function output = box_vote(input_pool, nms_choose_ind, vote_thres) 2 | 3 | output = zeros(length(nms_choose_ind), 5); 4 | nms_choose_box = input_pool(nms_choose_ind, 1:4); 5 | [true_overlap, ~] = compute_overlap_hyli(nms_choose_box, input_pool(:, 1:4)); 6 | 7 | for i = 1:length(true_overlap) 8 | to_merge_box = input_pool(true_overlap(i).overlap >= vote_thres, :); 9 | output(i, :) = mean(to_merge_box, 1); 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /code/utils/boxes_filter.m: -------------------------------------------------------------------------------- 1 | function [aboxes_per_im_out, ind] = boxes_filter(aboxes_per_im_in, ... 2 | nms_overlap_thres, after_nms_topN, per_nms_topN) 3 | 4 | if nargin < 4, per_nms_topN = -1; end 5 | 6 | % per_nms_topN = -1 7 | % nms_overlap_thres = 0.7 8 | % after_nms_topN = 2000 9 | % 10 | % update: 'ind' outputs the index from 'aboxes_per_im_in' 11 | % each entry inside aboxes is a single matrix, say [12300 x 5] 12 | 13 | if ~iscell(aboxes_per_im_in) 14 | aboxes = cell(1, 1); aboxes{1} = aboxes_per_im_in; 15 | else 16 | aboxes = aboxes_per_im_in; 17 | end 18 | ind = cell(size(aboxes)); 19 | 20 | %% 21 | if per_nms_topN > 0 22 | aboxes = cellfun(@(x) x(1:min(length(x), per_nms_topN), :), ... 23 | aboxes, 'UniformOutput', false); 24 | end 25 | 26 | use_gpu = true; 27 | assert(nms_overlap_thres > 0 && nms_overlap_thres < 1); 28 | for i = 1:length(aboxes) 29 | ind_temp = nms(aboxes{i}, nms_overlap_thres, use_gpu); 30 | aboxes{i} = aboxes{i}(ind_temp, :); 31 | ind{i} = ind_temp(1 : min(size(ind_temp,1), after_nms_topN)); 32 | end 33 | 34 | if after_nms_topN > 0 35 | aboxes = cellfun(@(x) x(1:min(size(x,1), after_nms_topN), :), ... 36 | aboxes, 'UniformOutput', false); 37 | end 38 | 39 | %% 40 | if ~iscell(aboxes_per_im_in) 41 | aboxes_per_im_out = aboxes{1}; 42 | else 43 | aboxes_per_im_out = aboxes; 44 | end 45 | end 46 | 47 | 48 | -------------------------------------------------------------------------------- /code/utils/boxoverlap.m: -------------------------------------------------------------------------------- 1 | function o = boxoverlap(a, b) 2 | % Compute the symmetric intersection over union overlap between a set of 3 | % bounding boxes in a and a single bounding box in b. 4 | % 5 | % a a matrix where each row specifies a bounding box 6 | % b a matrix where each row specifies a bounding box 7 | 8 | % AUTORIGHTS 9 | % ------------------------------------------------------- 10 | % Copyright (C) 2011-2012 Ross Girshick 11 | % Copyright (C) 2008, 2009, 2010 Pedro Felzenszwalb, Ross Girshick 12 | % 13 | % This file is part of the voc-releaseX code 14 | % (http://people.cs.uchicago.edu/~rbg/latent/) 15 | % and is available under the terms of an MIT-like license 16 | % provided in COPYING. Please retain this notice and 17 | % COPYING if you use this file (or a portion of it) in 18 | % your project. 19 | % ------------------------------------------------------- 20 | 21 | o = cell(1, size(b, 1)); 22 | for i = 1:size(b, 1) 23 | x1 = max(a(:,1), b(i,1)); 24 | y1 = max(a(:,2), b(i,2)); 25 | x2 = min(a(:,3), b(i,3)); 26 | y2 = min(a(:,4), b(i,4)); 27 | 28 | w = x2-x1+1; 29 | h = y2-y1+1; 30 | inter = w.*h; 31 | aarea = (a(:,3)-a(:,1)+1) .* (a(:,4)-a(:,2)+1); 32 | barea = (b(i,3)-b(i,1)+1) * (b(i,4)-b(i,2)+1); 33 | % intersection over union overlap 34 | o{i} = inter ./ (aarea+barea-inter); 35 | % set invalid entries to 0 overlap 36 | o{i}(w <= 0) = 0; 37 | o{i}(h <= 0) = 0; 38 | end 39 | 40 | o = cell2mat(o); 41 | -------------------------------------------------------------------------------- /code/utils/collect_bbox_stats.m: -------------------------------------------------------------------------------- 1 | function conf = collect_bbox_stats(opts, conf) 2 | % INACTIVE for now 3 | data_path = fullfile(pwd, 'data/training_test_data/rpn'); 4 | if ~isempty(opts.share_data_name) 5 | train_data_file = fullfile(data_path, opts.share_data_name, 'train.mat'); 6 | else 7 | train_data_file = fullfile(data_path, conf.model_id, 'train.mat'); 8 | end 9 | mkdir_if_missing(fileparts(train_data_file)); 10 | train_data_name_lite = strrep(train_data_file, pwd, ''); 11 | % train data 12 | if exist(train_data_file, 'file') && opts.detect_exist_train_file 13 | 14 | fprintf('|| Loading existant stats of RPN training data (%s) ...\n', ... 15 | train_data_name_lite); 16 | ld = load(train_data_file); 17 | bbox_means = ld.bbox_means; bbox_stds = ld.bbox_stds; 18 | clear ld; fprintf(' Done.\n'); 19 | else 20 | 21 | fprintf('|| Computing stats of RPN training data (%s) ...\n', ... 22 | train_data_name_lite); 23 | [bbox_means, bbox_stds]... 24 | = proposal_prepare_image_roidb_on_the_fly(... 25 | conf.rpn_param, opts.imdb_train, opts.roidb_train); 26 | save(train_data_file, 'bbox_means', 'bbox_stds', '-v7.3'); 27 | fprintf(' Done and saved.\n\n'); 28 | end 29 | conf.rpn_param.bbox_means = bbox_means; 30 | conf.rpn_param.bbox_stds = bbox_stds; 31 | end 32 | 33 | -------------------------------------------------------------------------------- /code/utils/collect_coco_gt.m: -------------------------------------------------------------------------------- 1 | function [roidb_merge, empty_gt] = collect_coco_gt(cocoApi, input) 2 | roidb_merge = []; 3 | empty_gt = false; 4 | 5 | % input: im_id, or im_name (without extension) 6 | % cocoApi can be cell of many Apis, or a single structure 7 | 8 | if isnumeric(input) 9 | % since we only got two different APIs 10 | try 11 | annoIds = cocoApi{1}.getAnnIds('imgIds', input); 12 | anno = cocoApi{1}.loadAnns(annoIds); 13 | catch 14 | annoIds = cocoApi{2}.getAnnIds('imgIds', input); 15 | anno = cocoApi{2}.loadAnns(annoIds); 16 | end 17 | else 18 | list = cocoApi.data.images; 19 | im_id = list(strcmp(extractfield(list, 'file_name'), [input '.jpg'])).id; 20 | annoIds = cocoApi.getAnnIds('imgIds', im_id); 21 | anno = cocoApi.loadAnns(annoIds); 22 | end 23 | 24 | if isempty(anno) 25 | empty_gt = true; 26 | return; 27 | end 28 | 29 | roidb_merge.class = extractfield(anno, 'category_id')'; 30 | boxes = reshape(extractfield(anno, 'bbox'), 4, [])'; 31 | roidb_merge.boxes = [boxes(:, 1) boxes(:, 2) ... 32 | (boxes(:, 1)+boxes(:, 3)) (boxes(:, 2)+boxes(:, 4))]; 33 | end -------------------------------------------------------------------------------- /code/utils/collect_db_info.m: -------------------------------------------------------------------------------- 1 | function imdb_info = collect_db_info(imdbs, roidbs) 2 | roidb_merge = []; imdb_merge_path = []; imdb_merge_size = []; 3 | for i = 1:length(imdbs) 4 | assert( strcmp(imdbs{i}.name, roidbs{i}.name) ); % name match 5 | assert(length(imdbs{i}.image_ids) == length(roidbs{i}.rois)); % number match 6 | roidb_merge = [roidb_merge; roidbs{i}.rois']; 7 | imdb_merge_path = [imdb_merge_path; imdbs{i}.image_ids]; 8 | imdb_merge_size = [imdb_merge_size; imdbs{i}.sizes]; 9 | im_path_root{i} = imdbs{i}.image_dir; 10 | end 11 | imdb_info.roidb_merge = roidb_merge; 12 | imdb_info.imdb_merge_path = imdb_merge_path; 13 | imdb_info.imdb_merge_size = imdb_merge_size; 14 | imdb_info.im_path_root = im_path_root; 15 | end -------------------------------------------------------------------------------- /code/utils/compute_overlap.m: -------------------------------------------------------------------------------- 1 | function [true_overlap, OVERLAP] = compute_overlap(pred_bbox_set, GT_bbox_set) 2 | % AUTORIGHTS 3 | % ------------------------------------------------------- 4 | % Copyright (C) 2015-2017 Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % ------------------------------------------------------- 7 | % input 8 | % pred_bbox_set: pre_num x 4 absotue coordinate values 9 | % GT_bbox_set: GT_num x 4 absotue coordinate values 10 | % 11 | % output 12 | % true_overlap: structure 13 | % overalp: each with GT_num x 1 overlap values 14 | % max: max value to all GTs 15 | % max_ind: index of GTs 16 | % 17 | % updated on Oct.9th, 2015; Mar.8th, 2017 18 | % very slow. consider using 'boxoverlap.m' 19 | 20 | OVERLAP = zeros(size(pred_bbox_set, 1), size(GT_bbox_set, 1)); 21 | true_overlap = struct('overlap', [], 'max', [], 'max_ind', []); 22 | true_overlap = repmat(true_overlap, [size(pred_bbox_set, 1) 1]); 23 | 24 | for mm = 1:size(pred_bbox_set, 1) 25 | pred_bbox = pred_bbox_set(mm, :); 26 | pred_area = (pred_bbox(4)-pred_bbox(2)+1)*(pred_bbox(3)-pred_bbox(1)+1); 27 | overlap = zeros(size(GT_bbox_set,1), 1); 28 | for i = 1:size(GT_bbox_set, 1) 29 | 30 | GT_bbox = GT_bbox_set(i, :); 31 | GT_area = (GT_bbox(4)-GT_bbox(2)+1)*(GT_bbox(3)-GT_bbox(1)+1); 32 | 33 | if pred_bbox(3) < GT_bbox(1) || pred_bbox(1) > GT_bbox(3) 34 | x_overlap = 0; 35 | else 36 | total_x = max(pred_bbox(3), GT_bbox(3)) - ... 37 | min(pred_bbox(1), GT_bbox(1)) + 1; 38 | x_overlap = total_x - abs(GT_bbox(3) - pred_bbox(3)) ... 39 | - abs(GT_bbox(1) - pred_bbox(1)); 40 | end 41 | if pred_bbox(4) < GT_bbox(2) || pred_bbox(2) > GT_bbox(4) 42 | y_overlap = 0; 43 | else 44 | total_y = max(pred_bbox(4), GT_bbox(4)) - ... 45 | min(pred_bbox(2), GT_bbox(2)) + 1; 46 | y_overlap = total_y - abs(GT_bbox(4) - pred_bbox(4)) ... 47 | - abs(GT_bbox(2) - pred_bbox(2)); 48 | end 49 | 50 | intersection = x_overlap * y_overlap; 51 | union = GT_area + pred_area - intersection; 52 | overlap(i) = intersection / union; 53 | end 54 | OVERLAP(mm, :) = overlap'; 55 | true_overlap(mm).overlap = single(overlap); 56 | [max_value, max_ind] = max(overlap); 57 | if sum(overlap) == 0, max_ind = 0; end 58 | true_overlap(mm).max = single(max_value); 59 | true_overlap(mm).max_ind = max_ind; 60 | end 61 | -------------------------------------------------------------------------------- /code/utils/compute_rec_pre.m: -------------------------------------------------------------------------------- 1 | function [mean_rec, mean_rec_size, recall_per_cls] = compute_rec_pre(imdb_info, boxes, eval) 2 | % AUTORIGHTS 3 | % ------------------------------------------------------- 4 | % Copyright (C) 2015-2017 Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % ------------------------------------------------------- 7 | 8 | mean_rec_size = []; 9 | recall_per_cls = []; 10 | 11 | % init stats 12 | % TODO: 'recall_per_cls' 13 | % if strcmp(imdb_info.dataset, 'voc'), cat_num = 20; end 14 | % recall_per_cls(cat_num).name = 'init'; 15 | % recall_per_cls(i).wnid = synsets(i).WNID; 16 | % recall_per_cls(i).name = synsets(i).name; 17 | % recall_per_cls(i).total_inst = 0; 18 | % recall_per_cls(i).correct_inst = 0; 19 | % recall_per_cls(i).recall = 0; 20 | ov_range = eval.ov; 21 | topK_range = eval.top_k; 22 | catch_gt_cnt = zeros(length(topK_range), length(ov_range)); 23 | gt_cnt = 0; 24 | 25 | if eval.eval_size 26 | 27 | scale_num = length(eval.scale_name); 28 | scale_area = cell(scale_num, 1); 29 | 30 | for i = 1:scale_num 31 | if i == 1, scale_area{i} = [0, eval.scale_size(i)^2]; 32 | elseif i == scale_num, scale_area{i} = [eval.scale_size(end)^2, inf]; 33 | else scale_area{i} = [eval.scale_size(i-1)^2 eval.scale_size(i)^2]; 34 | end 35 | end 36 | catch_gt_cnt_scale = zeros(scale_num, length(topK_range), length(ov_range)); 37 | gt_cnt_scale = zeros(scale_num, 1); 38 | end 39 | 40 | %% 41 | im_num = size(boxes, 1); 42 | show_num = 3000; 43 | for i = 1:im_num 44 | 45 | if i == 1 || i == length(im_num) || mod(i, show_num)==1 46 | fprintf('compute recall: (%d/%d)\n', i, length(im_num)); 47 | end 48 | 49 | curr_boxes = boxes{i, 1}; 50 | if iscell(curr_boxes) 51 | curr_boxes = cat(1, curr_boxes{:}); % for gop method 52 | end 53 | im_name = boxes{i, 2}; 54 | index = strcmp(im_name, imdb_info.imdb_merge_path); 55 | gt_info = imdb_info.roidb_merge(index); 56 | h = imdb_info.imdb_merge_size(index, 1); 57 | w = imdb_info.imdb_merge_size(index, 2); 58 | to_eval_gt = gt_info.boxes; 59 | gt_cnt = gt_cnt + size(to_eval_gt, 1); 60 | 61 | if eval.eval_size 62 | [gt_size_ind, gt_cnt_scale] = allocate_gt_size(... 63 | scale_area, to_eval_gt, gt_cnt_scale); 64 | end 65 | 66 | to_eval_box = zeros(size(curr_boxes, 1)+1, 4); 67 | to_eval_box(2:end, :) = curr_boxes(:, 1:4); 68 | to_eval_box(1, :) = [1 1 w h]; 69 | % matrix [gt_num x box_num] 70 | overlap = boxoverlap(to_eval_gt, to_eval_box); 71 | ov_cell = num2cell(overlap, 2); 72 | 73 | for m = 1:length(topK_range) 74 | for n = 1:length(ov_range) 75 | currTop = topK_range(m); 76 | currOv = ov_range(n); 77 | max_ov = cellfun(@(x) max(x(1:min(currTop, length(x))) >= currOv, [], 2), ov_cell); 78 | catch_gt_cnt(m, n) = catch_gt_cnt(m, n) + sum(max_ov); 79 | 80 | if eval.eval_size 81 | catch_gt_cnt_scale(:, m, n) = catch_gt_cnt_scale(:, m, n) + ... 82 | tiny2(gt_size_ind, max_ov, scale_num); 83 | end 84 | end 85 | end 86 | end 87 | 88 | mean_rec = catch_gt_cnt ./ gt_cnt; 89 | if eval.eval_size 90 | mean_rec_size = bsxfun(@rdivide, catch_gt_cnt_scale, gt_cnt_scale); 91 | end 92 | end 93 | 94 | function [gt_size_ind, gt_cnt_scale] = allocate_gt_size(scale_area, to_eval_gt, gt_cnt_scale) 95 | gt_area = (to_eval_gt(:, 1)-to_eval_gt(:, 3)+1).*(to_eval_gt(:, 2)-to_eval_gt(:, 4)+1); 96 | gt_size_ind = cellfun(@(x) tiny(scale_area, x), num2cell(gt_area)); 97 | 98 | for i = 1:length(gt_cnt_scale) 99 | gt_cnt_scale(i) = gt_cnt_scale(i) + sum(gt_size_ind==i); 100 | end 101 | end 102 | 103 | function index = tiny(scale_area, area) 104 | for kk = 1:length(scale_area) 105 | if (area <= scale_area{kk}(2)) && (scale_area{kk}(1) < area) 106 | index = kk; break; 107 | end 108 | end 109 | end 110 | 111 | function catch_gt_per_scale = tiny2(gt_size_ind, max_ov, scale_num) 112 | catch_gt_per_scale = zeros(scale_num, 1); 113 | for i = 1:scale_num 114 | catch_gt_per_scale(i) = sum(max_ov(gt_size_ind==i)); 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /code/utils/convert_ilsvrc_rec.m: -------------------------------------------------------------------------------- 1 | function [cls, bbox, flag] = convert_ilsvrc_rec( rec ) 2 | %UNTITLED Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | % cls: cell [n x 1], where n is the number of objects 6 | % bbox: double mat [n x 4] 7 | % flag: true if it contains GT in this image 8 | 9 | flag = true; cls = []; bbox = []; 10 | if isempty(rec.annotation.object), flag = false; return; end 11 | 12 | gt = squeeze(struct2cell(rec.annotation.object)); 13 | cls = gt(1, :)'; 14 | bbox = str2double(squeeze(struct2cell(cell2mat(gt(2, :)))))'; 15 | bbox = bbox(:, [1 3 2 4]); 16 | end 17 | 18 | -------------------------------------------------------------------------------- /code/utils/convert_pascal_rec.m: -------------------------------------------------------------------------------- 1 | function [cls, bbox, flag] = convert_pascal_rec( rec ) 2 | %UNTITLED Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | % cls: cell [n x 1], where n is the number of objects 6 | % bbox: double mat [n x 4] 7 | % flag: true if it contains GT in this image 8 | 9 | flag = true; cls = []; bbox = []; 10 | if isempty(rec.objects), flag = false; return; end 11 | 12 | gt = squeeze(struct2cell(rec.objects)); 13 | cls = gt(1, :)'; % cell [gt_num x 1] 14 | bbox = cell2mat(gt(8, :)); 15 | bbox = reshape(bbox, [4 length(cls)])'; 16 | 17 | class_list = {'aeroplane','bicycle','bird','boat',... 18 | 'bottle','bus','car','cat',... 19 | 'chair','cow','diningtable','dog',... 20 | 'horse','motorbike','person','pottedplant',... 21 | 'sheep','sofa','train','tvmonitor'}; 22 | cls = cellfun(@(x) find(strcmp(x, class_list)), cls); 23 | end 24 | 25 | -------------------------------------------------------------------------------- /code/utils/cprintf.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hli2020/zoom_network/a59f1c6b14cdbcf6124692bde4315ee8ab8bc961/code/utils/cprintf.m -------------------------------------------------------------------------------- /code/utils/find_nan_weight.m: -------------------------------------------------------------------------------- 1 | function find_nan_weight(caffe_solver, iter) 2 | 3 | layer_names = caffe_solver.nets{1}.layer_names; 4 | 5 | for i = 1:length(layer_names) 6 | curr_layer_name = layer_names{i}; 7 | for j = 1:10 8 | try 9 | curr_weight = caffe_solver.nets{1}.params(curr_layer_name, j).get_data(); 10 | if any(isnan(curr_weight)) 11 | fprintf('abs iter:: %d\tlayer\t%s (param id j=%d) has NaN\n', iter, curr_layer_name, j); 12 | end 13 | catch 14 | break; 15 | end 16 | end 17 | end 18 | end -------------------------------------------------------------------------------- /code/utils/get_coco_info.m: -------------------------------------------------------------------------------- 1 | function imdb_info = get_coco_info(imdbs) 2 | imdb_info.im_id = []; 3 | imdb_info.imdb_merge_size = []; 4 | imdb_info.imdb_merge_path = []; 5 | 6 | for i = 1:length(imdbs) 7 | curr_struct = imdbs{i}.data.images; 8 | curr_size_mat = [extractfield(curr_struct, 'height')' extractfield(curr_struct, 'width')']; 9 | imdb_info.imdb_merge_size = [imdb_info.imdb_merge_size; curr_size_mat]; 10 | 11 | imdb_info.im_id = [imdb_info.im_id; extractfield(curr_struct, 'id')']; 12 | imdb_info.imdb_merge_path = [imdb_info.imdb_merge_path; extractfield(curr_struct, 'file_name')']; 13 | end 14 | end -------------------------------------------------------------------------------- /code/utils/get_imagenet_3k_info.m: -------------------------------------------------------------------------------- 1 | function imdb_info = get_imagenet_3k_info(input) 2 | 3 | imdb_info.label = []; % [100 x 1] double 4 | imdb_info.imdb_merge_size = []; % [100 x 2] double 5 | imdb_info.imdb_merge_path = []; % [100 x 1] cell 6 | imdb_info.im_path_root = []; % [1 x 1] cell 7 | 8 | imdb_info.label = extractfield(input.train_list, 'label')'; 9 | bbox = struct2cell(input.train_list); 10 | imdb_info.bbox = squeeze(bbox(2, :, :)); 11 | 12 | im_size = extractfield(input.train_list, 'size'); 13 | im_size = reshape(im_size, [2 length(input.train_list)])'; 14 | imdb_info.imdb_merge_size = double(im_size); 15 | 16 | imdb_info.imdb_merge_path = extractfield(input.train_list, 'im_name')'; 17 | imdb_info.im_path_root{1} = input.train_root; 18 | end -------------------------------------------------------------------------------- /code/utils/get_voc_info.m: -------------------------------------------------------------------------------- 1 | function imdb_info = get_voc_info(mode) 2 | 3 | root1 = 'data/datasets/pascal/VOCdevkit/VOC2007'; 4 | im_path1 = fullfile(pwd, root1, 'JPEGImages'); 5 | root2 = 'data/datasets/pascal/VOCdevkit/VOC2012'; 6 | im_path2 = fullfile(pwd, root2, 'JPEGImages'); 7 | 8 | if strcmp(mode, 'train') 9 | 10 | ld = load('data/datasets/pascal/voc0712_trainval_gt_info.mat'); 11 | % conf.VOC.im_path_root{1} = im_path1; 12 | % conf.VOC.im_path_root{2} = im_path2; 13 | imdb_info.im_path_root{1} = im_path1; 14 | imdb_info.im_path_root{2} = im_path2; 15 | 16 | elseif strcmp(mode, 'test') 17 | 18 | ld = load('data/datasets/pascal/voc07_test_gt_info.mat'); 19 | imdb_info.im_path_root{1} = im_path1; 20 | end 21 | 22 | imdb_info.imdb_merge_size = ld.imdb_merge_size; % [100 x 2] double 23 | imdb_info.imdb_merge_path = ld.imdb_merge_path; % [100 x 1] cell 24 | imdb_info.roidb_merge = ld.roidb_merge; 25 | imdb_info.dataset = 'voc'; % for latter evaluation use 26 | end -------------------------------------------------------------------------------- /code/utils/im_list_to_blob.m: -------------------------------------------------------------------------------- 1 | function blob = im_list_to_blob(ims) 2 | 3 | % hyli: fill out the rest of the image with zero 4 | max_shape = max(cell2mat(cellfun(@size, ims(:), 'UniformOutput', false)), [], 1); 5 | assert(all(cellfun(@(x) size(x, 3), ims, 'UniformOutput', true) == 3)); 6 | num_images = length(ims); 7 | blob = zeros(max_shape(1), max_shape(2), 3, num_images, 'single'); 8 | 9 | for i = 1:length(ims) 10 | im = ims{i}; 11 | blob(1:size(im, 1), 1:size(im, 2), :, i) = im; 12 | end 13 | end -------------------------------------------------------------------------------- /code/utils/im_to_scale.m: -------------------------------------------------------------------------------- 1 | function [im, bbox] = im_to_scale(im_ori, bbox_ori, ... 2 | shorter_dim_range, max_dim, small_case) 3 | % the function below should be a generic method for all tasks 4 | % NOTE: this function resides in the 'cvpr17_proposal_dev' repo 5 | 6 | if nargin < 5 7 | use_smaller_dim = false; 8 | else 9 | use_smaller_dim = true; 10 | end 11 | 12 | if size(im_ori, 3) ~= 3 13 | im_ori = repmat(im_ori, [1 1 3]); 14 | end 15 | 16 | try 17 | shorter_dim = randi([shorter_dim_range(1) shorter_dim_range(2)], 1); 18 | catch 19 | assert(length(shorter_dim_range)==1); 20 | shorter_dim = shorter_dim_range; 21 | end 22 | 23 | % (80% prob with the shorter_dim above) OR (20% prob with 'conf.small_dim') 24 | if use_smaller_dim 25 | if rand(1) < 0.2 26 | shorter_dim = small_case.shorter_dim; 27 | max_dim = small_case.max_dim; 28 | end 29 | end 30 | 31 | h = size(im_ori, 1); w = size(im_ori, 2); 32 | if h>= w 33 | scale = shorter_dim / w; 34 | new_h = floor(h * scale); 35 | im = imresize(im_ori, [new_h shorter_dim]); 36 | else 37 | scale = shorter_dim / h; 38 | new_w = floor(w * scale); 39 | im = imresize(im_ori, [shorter_dim new_w]); 40 | end 41 | bbox = floor(bbox_ori.*scale); 42 | 43 | % re-compute image if larger dim exceeds max_dim 44 | larger_dim = max(size(im)); 45 | if larger_dim > max_dim 46 | scale_down_factor = max_dim/larger_dim; 47 | im = imresize(im, scale_down_factor); 48 | bbox = floor(bbox.*scale_down_factor); 49 | end 50 | 51 | new_w = size(im, 2); 52 | new_h = size(im, 1); 53 | % check bbox coordinate 54 | bbox_num = size(bbox, 1); 55 | bbox(:, 1) = max(bbox(:, 1), ones(bbox_num, 1)); 56 | bbox(:, 2) = max(bbox(:, 2), ones(bbox_num, 1)); 57 | bbox(:, 3) = min(bbox(:, 3), repmat(new_w, [bbox_num, 1])); 58 | bbox(:, 4) = min(bbox(:, 4), repmat(new_h, [bbox_num, 1])); -------------------------------------------------------------------------------- /code/utils/init_weight_from_other_model.m: -------------------------------------------------------------------------------- 1 | function caffe_solver = init_weight_from_other_model(... 2 | weight_detail, pretrain_model, solver_def_file, gpu_id) 3 | % IMPORTANT note: 4 | % we use uniformly 'solver_def_file' as the network structure, which 5 | % is the same as the to-be-trained model/task; in some cases, the ft 6 | % model from RPN is shorter (say 4b32), the 'ft_weights' still has 7 | % data in higher layers (say 4b35), but thosee params are initiated 8 | % as DEFAULT or as said in the solver file. 9 | 10 | % jot down the weights and clear solvers 11 | solver_pretrain = caffe.Solver(solver_def_file, 0); 12 | solver_pretrain.use_caffemodel(pretrain_model); 13 | pretrain_layer_names = solver_pretrain.nets{1}.layer_names; 14 | pretrain_weights = []; 15 | cnt = 0; 16 | for i = 1:length(pretrain_layer_names) 17 | 18 | curr_layer_name = pretrain_layer_names{i}; 19 | for j = 1:10 20 | try 21 | curr_weight = solver_pretrain.nets{1}.params(curr_layer_name, j).get_data(); 22 | if j == 1, cnt = cnt + 1; end 23 | pretrain_weights(cnt).layer_name = curr_layer_name; 24 | pretrain_weights(cnt).weights{j} = curr_weight; 25 | catch 26 | break; 27 | end 28 | end 29 | 30 | end 31 | caffe.reset_all; 32 | 33 | solver_rpn_finetune = caffe.Solver(solver_def_file, 0); 34 | solver_rpn_finetune.use_caffemodel(weight_detail(1).init_from); 35 | ft_layer_names = solver_rpn_finetune.nets{1}.layer_names; 36 | ft_weights = []; 37 | cnt = 0; 38 | for i = 1:length(ft_layer_names) 39 | 40 | curr_layer_name = ft_layer_names{i}; 41 | for j = 1:10 42 | try 43 | curr_weight = solver_rpn_finetune.nets{1}.params(curr_layer_name, j).get_data(); 44 | if j == 1, cnt = cnt + 1; end 45 | ft_weights(cnt).layer_name = curr_layer_name; 46 | ft_weights(cnt).weights{j} = curr_weight; 47 | catch 48 | break; 49 | end 50 | end 51 | 52 | end 53 | caffe.reset_all; 54 | 55 | % assign the weights 56 | caffe_solver = caffe.Solver(solver_def_file, gpu_id); 57 | num_gpu = length(gpu_id); 58 | end_layer_id = find( strcmp(extractfield(ft_weights, 'layer_name'), ... 59 | weight_detail(1).end_layer) == 1); 60 | 61 | % first from ft model 62 | cprintf('blue', 'load (ft RPN model) params from layer "%s" to "%s"\n\n', ... 63 | ft_weights(1).layer_name, ft_weights(end_layer_id).layer_name); 64 | 65 | for i = 1 : end_layer_id 66 | curr_layer_name = ft_weights(i).layer_name; 67 | for j = 1:length(ft_weights(i).weights) 68 | curr_weights = ft_weights(i).weights{j}; 69 | for kk = 1:num_gpu 70 | caffe_solver.nets{kk}.set_params_data(curr_layer_name, j, curr_weights); 71 | end 72 | end 73 | end 74 | 75 | % then from pretrained model for the rest layers 76 | cprintf('blue', 'load (pretrained model) params from layer "%s" to "%s"\n\n', ... 77 | ft_weights(end_layer_id+1).layer_name, ft_weights(end).layer_name); 78 | 79 | for i = (end_layer_id+1) : length(pretrain_weights) 80 | curr_layer_name = pretrain_weights(i).layer_name; 81 | for j = 1:length(pretrain_weights(i).weights) 82 | curr_weights = pretrain_weights(i).weights{j}; 83 | for kk = 1:num_gpu 84 | caffe_solver.nets{kk}.set_params_data(curr_layer_name, j, curr_weights); 85 | end 86 | end 87 | end 88 | 89 | fprintf('network weight init done (from different models)!\n'); 90 | -------------------------------------------------------------------------------- /code/utils/mkdir_if_missing.m: -------------------------------------------------------------------------------- 1 | function made = mkdir_if_missing(path) 2 | made = false; 3 | if exist(path, 'dir') == 0 4 | mkdir(path); 5 | made = true; 6 | end 7 | -------------------------------------------------------------------------------- /code/utils/parse_rst.m: -------------------------------------------------------------------------------- 1 | function results = parse_rst(results, rst_net, iter, debug) 2 | % from Liu Yu, adapted to multi-gpu training 3 | % average the results across different cards 4 | 5 | rst_singleNet = rst_net{1}; % first net result 6 | rst_singleNet = changeNanToZero(rst_singleNet, iter, 1, debug); 7 | 8 | % i is the net index, j is the data index per net 9 | for i = 2 : length(rst_net) 10 | 11 | rst_net{i} = changeNanToZero(rst_net{i}, iter, i, debug); 12 | for j = 1 : length(rst_singleNet) 13 | rst_singleNet(j).data = rst_singleNet(j).data + rst_net{i}(j).data; 14 | end 15 | end 16 | 17 | for j = 1 : length(rst_singleNet) 18 | rst_singleNet(j).data = rst_singleNet(j).data ./ length(rst_net); 19 | end 20 | 21 | if isempty(results) 22 | for j = 1:length(rst_singleNet) 23 | results.(rst_singleNet(j).blob_name).data = []; 24 | end 25 | end 26 | 27 | for j = 1:length(rst_singleNet) 28 | results.(rst_singleNet(j).blob_name).data = ... 29 | [results.(rst_singleNet(j).blob_name).data; rst_singleNet(j).data(:)]; 30 | end 31 | end 32 | 33 | function rst_singleNet = changeNanToZero(rst_singleNet, iter, which_net, debug) 34 | raw_data = extractfield(rst_singleNet, 'data'); 35 | if debug 36 | if any(isnan(raw_data)) 37 | cprintf('blue', 'abs iter:\t%d, which_gpu: #%d, NaN result occurs. change to ZERO just in matlab GUI.\n', ... 38 | iter, which_net); 39 | end 40 | end 41 | raw_data(isnan(raw_data)) = 0; 42 | for kk = 1:length(rst_singleNet) 43 | rst_singleNet(kk).data = raw_data(kk); 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /code/utils/prep_im_for_blob.m: -------------------------------------------------------------------------------- 1 | function im_resize = prep_im_for_blob(im, target_size, conf) 2 | % target_size is the shorter_dim 3 | % this function is both used for training and test 4 | 5 | im_means = conf.DATA.image_mean; 6 | if strcmp(conf.mode, 'train') 7 | max_size = conf.rpn_max_size; 8 | else 9 | max_size = conf.test_multiscale_max_size; 10 | end 11 | wh = [size(im,1) size(im,2)]; 12 | shorter = min(wh); longer = max(wh); 13 | resize_factor = target_size/shorter; 14 | 15 | potential_max_size = (target_size/shorter)*longer; 16 | if potential_max_size > max_size 17 | resize_factor = max_size/longer; 18 | end 19 | new_h = floor(resize_factor*size(im,1)); 20 | new_w = floor(resize_factor*size(im,2)); 21 | 22 | if conf.check_certain_scale 23 | % find the nearest scale 24 | scale_set = conf.certain_scale; 25 | new_h = switch_to_nearest_scale(new_h, scale_set); 26 | new_w = switch_to_nearest_scale(new_w, scale_set); 27 | end 28 | 29 | im_resize = imresize(im, [new_h new_w], 'bilinear', 'antialiasing', false); 30 | im_resize = single(im_resize); 31 | try 32 | im_resize = bsxfun(@minus, im_resize, im_means); 33 | catch 34 | im_means = imresize(im_means, [size(im_resize, 1), size(im_resize, 2)], ... 35 | 'bilinear', 'antialiasing', false); 36 | im_resize = bsxfun(@minus, im_resize, im_means); 37 | end 38 | end 39 | 40 | function new = switch_to_nearest_scale(old, scale_set) 41 | [~, ind] = min((scale_set - old).^2); 42 | new = scale_set(ind); 43 | end 44 | -------------------------------------------------------------------------------- /code/utils/procid.m: -------------------------------------------------------------------------------- 1 | function s = procid() 2 | % Returns a string identifying the process. 3 | 4 | % AUTORIGHTS 5 | % ------------------------------------------------------- 6 | % Copyright (C) 2009-2012 Ross Girshick 7 | % 8 | % This file is part of the voc-releaseX code 9 | % (http://people.cs.uchicago.edu/~rbg/latent/) 10 | % and is available under the terms of an MIT-like license 11 | % provided in COPYING. Please retain this notice and 12 | % COPYING if you use this file (or a portion of it) in 13 | % your project. 14 | % ------------------------------------------------------- 15 | 16 | d = pwd(); 17 | i = strfind(d, filesep); 18 | d = d(i(end)+1:end); 19 | s = d; 20 | -------------------------------------------------------------------------------- /code/utils/rolling_mean.m: -------------------------------------------------------------------------------- 1 | function rolling_mean( data, radius ) 2 | % AUTORIGHTS 3 | % ------------------------------------------------------- 4 | % Copyright (C) 2015-2017 Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % ------------------------------------------------------- 7 | 8 | if nargin < 2 9 | radius = 50; 10 | end 11 | 12 | new_data = zeros(size(data)); 13 | 14 | for i = 1:length(data) 15 | start_ind = max(i-radius, 1); 16 | end_ind = min(i+radius, length(data)); 17 | new_data(i) = mean(data(start_ind:end_ind)); 18 | end 19 | 20 | figure; 21 | grid on; 22 | hold on; 23 | plot(data); 24 | plot(new_data, 'linewidth', 2); 25 | hold off; 26 | -------------------------------------------------------------------------------- /code/utils/scale_rois.m: -------------------------------------------------------------------------------- 1 | function scaled_rois = scale_rois(rois, im_size, im_size_resize) 2 | % add the following to prevent empty box in roidb 3 | if isempty(rois) 4 | scaled_rois=[]; 5 | return 6 | end 7 | scale = (im_size_resize - 1) ./ (im_size - 1); 8 | scaled_rois = bsxfun(@times, rois-1, [scale(2), scale(1), scale(2), scale(1)]) + 1; 9 | end -------------------------------------------------------------------------------- /code/utils/seed_rand.m: -------------------------------------------------------------------------------- 1 | function prev_rng = seed_rand(seed) 2 | % seed_rand - Set random number generator to a fixed seed. 3 | % prev_rng = seed_rand(seed) 4 | % 5 | % Strategic use ensures that results are reproducible. 6 | % 7 | % To restore the previous rng after calling this do: 8 | % rng(prev_rng); 9 | 10 | % AUTORIGHTS 11 | % --------------------------------------------------------- 12 | % Copyright (c) 2014, Ross Girshick 13 | % 14 | % This file is part of the R-CNN code and is available 15 | % under the terms of the Simplified BSD License provided in 16 | % LICENSE. Please retain this notice and LICENSE if you use 17 | % this file (or any portion of it) in your project. 18 | % --------------------------------------------------------- 19 | 20 | if nargin < 1 21 | % This value works best for me. 22 | seed = 3; 23 | % Just kidding, of course ;-). 24 | end 25 | 26 | prev_rng = rng; 27 | rng(seed, 'twister') 28 | -------------------------------------------------------------------------------- /code/utils/tic_toc_print.m: -------------------------------------------------------------------------------- 1 | function tic_toc_print(fmt, varargin) 2 | % Print only after 1 second has passed since the last print. 3 | % Arguments are the same as for fprintf. 4 | 5 | % AUTORIGHTS 6 | % ------------------------------------------------------- 7 | % Copyright (C) 2009-2012 Ross Girshick 8 | % 9 | % This file is part of the voc-releaseX code 10 | % (http://people.cs.uchicago.edu/~rbg/latent/) 11 | % and is available under the terms of an MIT-like license 12 | % provided in COPYING. Please retain this notice and 13 | % COPYING if you use this file (or a portion of it) in 14 | % your project. 15 | % ------------------------------------------------------- 16 | 17 | persistent th; 18 | 19 | if isempty(th) 20 | th = tic(); 21 | end 22 | 23 | if toc(th) > 1 24 | fprintf(fmt, varargin{:}); 25 | drawnow; 26 | th = tic(); 27 | end 28 | -------------------------------------------------------------------------------- /code/utils/update_recall_stats.m: -------------------------------------------------------------------------------- 1 | function [recall, gt_resize_log] = update_recall_stats(... 2 | recall, gt_resize_log, gt_info, gt_stats) 3 | 4 | cls_list = unique(gt_info(:,1)); 5 | level_num = 3; 6 | 7 | im_resize = gt_stats.im_size_resize(1:2); 8 | for i = 1:length(cls_list) 9 | 10 | curr_cls = cls_list(i); 11 | detect_mat = gt_info(gt_info(:, 1)==curr_cls, 2:end); 12 | curr_cls_total_num = sum(gt_info(:, 1)==curr_cls); 13 | curr_cls_all_level_vec = zeros(curr_cls_total_num, 1); 14 | for kk = 1:level_num 15 | curr_cls_curr_level_correct_num = sum(detect_mat(:, kk)); 16 | curr_cls_all_level_vec = curr_cls_all_level_vec | detect_mat(:, kk); 17 | recall.(sprintf('level_%d', kk))(curr_cls, 1) = ... 18 | curr_cls_total_num + recall.(sprintf('level_%d', kk))(curr_cls, 1); 19 | recall.(sprintf('level_%d', kk))(curr_cls, 2) = ... 20 | curr_cls_curr_level_correct_num + recall.(sprintf('level_%d', kk))(curr_cls, 2); 21 | end 22 | recall.all(curr_cls, 1) = curr_cls_total_num + recall.all(curr_cls, 1); 23 | recall.all(curr_cls, 2) = sum(curr_cls_all_level_vec) + recall.all(curr_cls, 2); 24 | 25 | gt_resize_log{curr_cls, 1} = cat(1, ... 26 | gt_resize_log{curr_cls, 1}, ... 27 | gt_stats.gt_resize_rois(gt_info(:, 1)==curr_cls, 2:end)); 28 | 29 | gt_resize_log{curr_cls, 2} = cat(1, ... 30 | gt_resize_log{curr_cls, 2}, ... 31 | repmat(im_resize, [curr_cls_total_num 1])); 32 | end 33 | end -------------------------------------------------------------------------------- /code/utils/visual_anchor_test.m: -------------------------------------------------------------------------------- 1 | function [catch_total, inst_total, gt_obj_fail] = visual_anchor_test( ... 2 | im_path, curr_im_name, proposals_ori, use_coco, coco_gt, gt_path, ... 3 | catch_total, inst_total, roi_followup, cat_book) 4 | %UNTITLED Summary of this function goes here 5 | % Detailed explanation goes here 6 | 7 | top_k = 300; 8 | 9 | if roi_followup 10 | 11 | to_show_proposal{1} = proposals_ori.raw_boxes_roi{1,1}; 12 | % PAY ATTENTION TO THIS. In 'visualize_test', we only have results of 13 | % individual nms value; however, in 'proposal_im_detect', we merged all 14 | % possible nms values (say 0.7:-0.05:0.5), that's why {5}. 15 | try 16 | to_show_proposal{2} = proposals_ori.aboxes{5}; % nms=0.5 17 | catch 18 | % choose several proposals after regression 19 | to_show_proposal{2} = proposals_ori.aboxes; % nms=0.5 20 | to_show_proposal = process_regression_result(to_show_proposal, proposals_ori.raw_boxes_roi); 21 | end 22 | ov_range = 0.5 : 0.05 : 0.95; 23 | 24 | else 25 | % normal function 26 | to_show_proposal{1} = proposals_ori; 27 | ov_range = 0.5; 28 | end 29 | 30 | if use_coco 31 | addpath(genpath('./data/datasets/coco/coco_eval')); 32 | im = imread([im_path '/' curr_im_name '.jpg']); 33 | else 34 | ld = load('./data/datasets/ilsvrc14_det/ILSVRC2014_devkit/data/meta_det.mat'); 35 | gt_info = ld.synsets_det; clear ld; 36 | dataset_root = './data/datasets/ilsvrc14_det/ILSVRC2014_devkit'; 37 | addpath([dataset_root '/evaluation']); 38 | im = imread([im_path '/' curr_im_name '.JPEG']); 39 | end 40 | 41 | %% 42 | for sub_fig_iter = 1:length(to_show_proposal) 43 | 44 | subplot(1, length(to_show_proposal), sub_fig_iter); 45 | hold on; 46 | imshow(mat2gray(im)); 47 | 48 | % draw gt 49 | if use_coco 50 | [gt_info, empty_gt] = collect_coco_gt(coco_gt, curr_im_name); 51 | gt_rois = gt_info.boxes; 52 | if empty_gt, return; end 53 | else 54 | rec = VOCreadxml([gt_path '/' curr_im_name '.xml']); 55 | % if length(rec.annotation.object) > 2, keyboard; end 56 | gt_rois = zeros(length(rec.annotation.object), 4); 57 | for i = 1:length(rec.annotation.object) 58 | gt_obj = cellfun(@(x) str2double(x), ... 59 | struct2cell(rec.annotation.object(i).bndbox), 'uniformoutput', false); 60 | gt_obj = cell2mat(gt_obj); 61 | gt_obj = [gt_obj(1) gt_obj(3) gt_obj(2) gt_obj(4)]; 62 | gt_rois(i, :) = gt_obj; 63 | end 64 | end 65 | 66 | % draw boxes 67 | try 68 | proposals = floor(to_show_proposal{sub_fig_iter}(1:top_k, 1:4)); 69 | catch 70 | % in case there are not enough top_k 71 | proposals = floor(to_show_proposal{sub_fig_iter}(:, 1:4)); 72 | end 73 | proposals(end, :) = [1 1 size(im, 2), size(im, 1)]; 74 | 75 | proposals = double(proposals); 76 | [true_overlap, ~] = compute_overlap_hyli(gt_rois, proposals); 77 | 78 | gt_obj_fail = []; 79 | gt_fail_label = cell(1); 80 | if use_coco, inst_num = size(gt_rois, 1); 81 | else inst_num = length(rec.annotation.object); end 82 | 83 | curr_recall = zeros(length(ov_range), 1); 84 | 85 | for ov_iter = 1 : length(ov_range) 86 | 87 | draw_fig = false; 88 | cnt = 0; 89 | curr_ov = ov_range(ov_iter); 90 | if curr_ov == 0.5, draw_fig = true; end 91 | 92 | for i = 1 : inst_num 93 | gt_obj = gt_rois(i, :); 94 | match_prop = proposals(true_overlap(i).overlap >= curr_ov, :); 95 | 96 | if use_coco 97 | lable_name = cat_book(... 98 | extractfield(cat_book, 'id') == gt_info.class(i) ).name; 99 | else 100 | lable_name = gt_info(strcmp(rec.annotation.object(i).name, ... 101 | extractfield(gt_info, 'WNID'))).name; 102 | end 103 | 104 | if ~isempty(match_prop) 105 | if draw_fig 106 | prop_label = cell(size(match_prop, 1), 1); 107 | for kk = 1:length(prop_label), prop_label{kk} = lable_name; end 108 | % draw match boxes 109 | cellfun(@(x) rectangle('Position', RectLTRB2LTWH(x), 'EdgeColor', 'b', ... 110 | 'linewidth', 2), num2cell(match_prop, 2)); 111 | % cellfun(@(x, y) text(x(1), x(2), sprintf('%s', y), 'backgroundcolor', 'b'), ... 112 | % num2cell(match_prop, 2), prop_label); 113 | % draw successfully catched up GTs 114 | rectangle('Position', RectLTRB2LTWH(gt_obj), 'EdgeColor', 'r', 'linewidth', 2); 115 | % text(gt_obj(1), gt_obj(2), lable_name, 'backgroundcolor', 'r'); 116 | end 117 | else 118 | cnt = cnt + 1; 119 | gt_obj_fail = [gt_obj_fail; gt_obj]; 120 | gt_fail_label{cnt, 1} = lable_name; 121 | end 122 | end 123 | curr_recall(ov_iter) = (inst_num - cnt) / inst_num; 124 | 125 | if draw_fig 126 | 127 | % draw failure GTs 128 | if ~isempty(gt_obj_fail) 129 | 130 | cellfun(@(x) rectangle('Position', RectLTRB2LTWH(x), 'EdgeColor', 'magenta', ... 131 | 'linewidth', 2, 'linestyle', '--'), num2cell(gt_obj_fail, 2)); 132 | cellfun(@(x, y) text(x(1), x(2), sprintf('%s', y), 'backgroundcolor', 'magenta'), ... 133 | num2cell(gt_obj_fail, 2), gt_fail_label); 134 | end 135 | % title 136 | text(20, (size(im, 1)+30), sprintf('fig# %d, catch: %d / fail: %d, name: %s\n', ... 137 | sub_fig_iter, size(gt_rois, 1)-size(gt_obj_fail, 1), size(gt_obj_fail, 1), strrep(curr_im_name, '_', '\_'))); 138 | end 139 | end % loopr for ov_range 140 | 141 | if roi_followup 142 | % title 143 | text(20, (size(im, 1)+60), sprintf('av recall: %.3f\n', mean(curr_recall))); 144 | text(20, (size(im, 1)+80), sprintf('recall detail: %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n', curr_recall)); 145 | end 146 | hold off; 147 | 148 | catch_total = catch_total + size(gt_rois, 1)-size(gt_obj_fail, 1); 149 | inst_total = inst_total + size(gt_rois, 1); 150 | end % loop for each to-show-proposal 151 | end 152 | 153 | -------------------------------------------------------------------------------- /code/zoom_net/assets/evaluate.m: -------------------------------------------------------------------------------- 1 | % plot average recall 2 | close all; clear; 3 | % folder_name{1} = 'coco_attract'; 4 | % input_proposals = ... 5 | % '../externalBox/COCO_dataset_bbox/AttractionNet/mscoco_val_2014/boxes'; 6 | 7 | % imdb.name = 'coco_val'; 8 | % folder_name{1} = 'coco_solo_no_regress'; 9 | % only_one_method = true; 10 | % input_proposals = ... 11 | % './output/rpn/D15a_coco_s170_resume/coco_val/iter_50000_dense_test/nms_0.70/split'; 12 | 13 | % % for coco 14 | % imdb.name = 'coco_val'; 15 | % root = '../externalBox/data_I_want_coco'; 16 | % special_care = false; 17 | % folder_name{1} = 'BING'; 18 | % folder_name{2} = 'edge_boxes_70'; 19 | % folder_name{3} = 'endres'; 20 | % folder_name{4} = 'geodesic'; 21 | % folder_name{5} = 'MCG'; 22 | % folder_name{6} = 'randomized_prims'; 23 | % folder_name{7} = 'rigor'; 24 | % folder_name{8} = 'selective_search'; 25 | 26 | % imdb.name = 'coco_val'; 27 | % root = '../externalBox/data_I_want_coco'; 28 | % special_care = true; 29 | % % folder_name{1} = 'fast_dbox_data_deepBox_coco'; file_name{1} = 'result_5k.mat'; %'val2014.mat'; 30 | % folder_name{1} = 'deepmask-coco-val-bbox'; file_name{1} = 'deepMask_final'; 31 | % folder_name{2} = 'sharpmask-coco-val-bbox'; file_name{2} = 'sharpMask_final'; 32 | 33 | 34 | % % for imagenet 35 | imdb.name = 'ilsvrc14_val2'; 36 | % root = '../externalBox/data_I_want'; 37 | % folder_name{1} = 'split_d15a_s170_nms0.7'; % sop_baseline; 38 | only_one_method = true; 39 | input_proposals = './output/rpn/D16a_roi_s31/ilsvrc14_val2/iter_160000_noDense_test/nms_0.50/split'; 40 | folder_name{1} = 'sop'; 41 | special_choice = {'naive_2_nms7'}; % roi-followup 42 | 43 | only_one_method = true; 44 | input_proposals = '../externalBox/AttractioNet/box_proposals/author_provide/val2/oct_19_fair'; 45 | folder_name{1} = 'attract'; 46 | 47 | % folder_name{3} = 'attract'; 48 | % root = '../externalBox/data_I_want'; 49 | % folder_name{1} = 'bing'; 50 | % folder_name{2} = 'edgebox_70'; 51 | % folder_name{3} = 'endres'; 52 | % folder_name{4} = 'gop'; 53 | % folder_name{5} = 'mcg'; 54 | % folder_name{6} = 'prims'; 55 | % folder_name{7} = 'rigor'; 56 | % folder_name{8} = 'ss'; 57 | 58 | % ================================================= 59 | top_k = [10, 100, 300, 500, 700, 1000, 1500, 2000]; 60 | ov = 0.5 : 0.05 : 0.95; 61 | imdb.flip = false; 62 | 63 | eval_size = true; 64 | scale_size = [32, 96]; 65 | scale_topK = 100; 66 | scale_name = {'small', 'medium', 'large'}; 67 | 68 | if strcmp(imdb.name, 'coco_val') 69 | root_dir = './data/datasets/coco'; 70 | %root_dir = 'D:/G-COCO'; 71 | addpath(genpath([root_dir '/coco_eval'])); 72 | imdb.image_dir = [root_dir '/val2014']; 73 | imdb.extension = 'jpg'; 74 | imdb.coco = CocoApi([root_dir '/annotations/instances_minival2014.json']); 75 | dataset = 'coco'; 76 | else 77 | dataset = 'ilsvrc'; 78 | end 79 | 80 | try 81 | only_one_method; 82 | catch 83 | only_one_method = false; 84 | end 85 | for fuck = 1:length(folder_name) % each method 86 | 87 | save_dir = ['./experiment/evaluate/' dataset '/' folder_name{fuck}]; 88 | mkdir_if_missing(save_dir); 89 | if strcmp(dataset, 'ilsvrc') 90 | 91 | if ~only_one_method, input_proposals = fullfile(root, folder_name{fuck}, 'ILSV'); end 92 | 93 | elseif strcmp(dataset, 'coco') 94 | 95 | if ~only_one_method 96 | if special_care 97 | input_proposals = fullfile(root, folder_name{fuck}, file_name{fuck}); 98 | else 99 | input_proposals = fullfile(root, folder_name{fuck}, 'mat/COCO_val2014_0'); 100 | end 101 | imdb.skip_check = true; 102 | end 103 | end 104 | 105 | %% 106 | % for mm = 1:length(special_choice) 107 | % imdb.special_choice = special_choice{mm}; 108 | 109 | if eval_size 110 | recall = zeros(length(top_k)+length(scale_size)+1, length(ov)+1); 111 | else 112 | recall = zeros(length(top_k), length(ov)+1); % plus last column: av 113 | end 114 | 115 | imdb.raw_proposals = []; 116 | try 117 | suffix = ['_' imdb.special_choice]; 118 | catch 119 | suffix = ''; 120 | end 121 | 122 | for i = 1:size(recall, 1) % each top_k 123 | 124 | if i <= length(top_k) 125 | curr_topK = top_k(i); 126 | cprintf('blue', 'prop num = %d, method: %s, dataset: %s\n', ... 127 | curr_topK, folder_name{fuck}, dataset); 128 | save_name_prefix = [imdb.name '_' sprintf('topK_%d_av_rec_', curr_topK)]; 129 | else 130 | % evalute different boxes 131 | m = i - length(top_k); 132 | if m == 1 133 | imdb.scale_range = [0 scale_size(m)]; 134 | elseif m == length(scale_size)+1 135 | imdb.scale_range = [scale_size(end) inf]; 136 | else 137 | imdb.scale_range = [scale_size(m-1) scale_size(m)]; 138 | end 139 | curr_topK = scale_topK; 140 | cprintf('blue', 'area box: [%d %d], prop num = %d, method: %s, dataset: %s\n', ... 141 | imdb.scale_range, curr_topK, folder_name{fuck}, dataset); 142 | save_name_prefix = [imdb.name '_' sprintf('%s_av_rec_', scale_name{m})]; 143 | end 144 | 145 | check = dir([save_dir '/' save_name_prefix '*']); 146 | if isempty(check) 147 | for j = 1:length(ov) % each overlap 148 | imdb.ov = ov(j); 149 | [~, recall(i, j), proposals] = compute_recall_ilsvrc(... 150 | input_proposals, curr_topK, imdb); 151 | imdb.raw_proposals = proposals; 152 | fprintf('recall @%.2f = %.3f, ', ov(j), recall(i, j)); 153 | fprintf('%s\n', folder_name{fuck}); 154 | end 155 | recall(i, length(ov)+1) = mean(recall(i, 1:length(ov))); 156 | cprintf('blue', 'av = %.3f\n\n', recall(i, length(ov)+1)); 157 | save_name = sprintf('%s%.3f%s.mat', save_name_prefix, ... 158 | recall(i, length(ov)+1), suffix); 159 | 160 | curr_recall = recall(i, :); 161 | save(fullfile(save_dir, save_name), 'curr_recall'); 162 | 163 | try 164 | imdb = rmfield(imdb, 'scale_range'); 165 | catch 166 | end 167 | else 168 | fprintf('file exists. skip evaluation.\n'); 169 | % TODO: reload recall results, otherwise the 'reall' will 170 | % be all zeros; 171 | end 172 | end 173 | 174 | recall = recall ./ 100; 175 | save(fullfile(save_dir, 'recall_overall.mat'), 'recall'); 176 | % end 177 | end 178 | exit; 179 | -------------------------------------------------------------------------------- /code/zoom_net/assets/rpn_compute_stats_TODO.m: -------------------------------------------------------------------------------- 1 | function [bbox_means, bbox_stds] = ... 2 | proposal_prepare_image_roidb_on_the_fly(conf, imdbs, roidbs) 3 | % -------------------------------------------------------- 4 | % formerly known as 'proposal_prepare_image_roidb_on_the_fly' 5 | % now changed to 'rpn_compute_bbox_stats' 6 | % -------------------------------------------------------- 7 | 8 | if ~iscell(imdbs) 9 | imdbs = {imdbs}; 10 | roidbs = {roidbs}; 11 | end 12 | 13 | imdbs = imdbs(:); 14 | roidbs = roidbs(:); 15 | 16 | assert(conf.target_only_gt==true); 17 | roidb_merge = []; imdb_merge_path = []; imdb_merge_size = []; 18 | for i = 1:length(imdbs) 19 | assert( strcmp(imdbs{i}.name, roidbs{i}.name) ); % name match 20 | assert(length(imdbs{i}.image_ids) == length(roidbs{i}.rois)); % number match 21 | roidb_merge = [roidb_merge; roidbs{i}.rois']; 22 | imdb_merge_path = [imdb_merge_path; imdbs{i}.image_ids]; 23 | imdb_merge_size = [imdb_merge_size; imdbs{i}.sizes]; 24 | im_path_root{i} = imdbs{i}.image_dir; 25 | end 26 | num_images = length(roidb_merge); 27 | fprintf(' || RPN: see via (%d) training images...\n', num_images); 28 | %% 29 | fprintf(' || RPN: begin to compute bbox regression targets and stats...\n'); 30 | % Compute values needed for means and stds 31 | % means and stds -- k * 4, include background class, here k = 1 for rpn 32 | % var(x) = E(x^2) - E(x)^2 33 | class_counts = zeros(1, 1) + eps; 34 | sums = zeros(1, 4); 35 | squared_sums = zeros(1, 4); 36 | 37 | for i = 1:num_images 38 | im_size = imdb_merge_size(i, :); 39 | [anchors, im_scales] = proposal_locate_anchors(conf, im_size); 40 | gt_rois = roidb_merge(i).boxes; % only contains gt boxes 41 | gt_labels = roidb_merge(i).class; 42 | curr_im_bbox_targets = cellfun(@(x, y) ... 43 | hyli_rpn_compute_targets(conf, scale_rois(gt_rois, im_size, y), gt_labels, x, im_size, y), ... 44 | anchors, im_scales, 'UniformOutput', false); 45 | for j = 1:length(conf.scales) 46 | targets = curr_im_bbox_targets{j}; 47 | gt_inds = find(targets(:, 1) > 0); 48 | if ~isempty(gt_inds) 49 | class_counts = class_counts + length(gt_inds); 50 | sums = sums + sum(targets(gt_inds, 2:end), 1); 51 | squared_sums = squared_sums + sum(targets(gt_inds, 2:end).^2, 1); 52 | end 53 | end 54 | 55 | end 56 | bbox_means = bsxfun(@rdivide, sums, class_counts); 57 | bbox_stds = (bsxfun(@minus, bsxfun(@rdivide, squared_sums, class_counts), bbox_means.^2)).^0.5; 58 | 59 | % % Normalize targets 60 | % for i = 1:num_images 61 | % for j = 1:length(conf.scales) 62 | % targets = image_roidb(i).bbox_targets{j}; 63 | % gt_inds = find(targets(:, 1) > 0); 64 | % if ~isempty(gt_inds) 65 | % image_roidb(i).bbox_targets{j}(gt_inds, 2:end) = ... 66 | % bsxfun(@minus, image_roidb(i).bbox_targets{j}(gt_inds, 2:end), means); 67 | % image_roidb(i).bbox_targets{j}(gt_inds, 2:end) = ... 68 | % bsxfun(@rdivide, image_roidb(i).bbox_targets{j}(gt_inds, 2:end), stds); 69 | % end 70 | % end 71 | % end 72 | 73 | fprintf(' || done!\n'); 74 | end 75 | 76 | 77 | function scaled_rois = scale_rois(rois, im_size, im_scale) 78 | % add the following to prevent empty box in roidb 79 | if isempty(rois) 80 | scaled_rois=[]; 81 | return 82 | end 83 | im_size_scaled = round(im_size * im_scale); 84 | scale = (im_size_scaled - 1) ./ (im_size - 1); 85 | scaled_rois = bsxfun(@times, rois-1, [scale(2), scale(1), scale(2), scale(1)]) + 1; 86 | 87 | end 88 | 89 | -------------------------------------------------------------------------------- /code/zoom_net/assets/rpn_compute_targets_v0.m: -------------------------------------------------------------------------------- 1 | function [bbox_targets, src_rois, gt_info, anchors] = rpn_compute_targets_v0( ... 2 | conf, gt_rois, gt_labels, anchors, im_size_resize) 3 | % output: bbox_targets 4 | % positive: [class_label, regression_label] 5 | % ignore: [-2, zero(regression_label)] 6 | % negative: [-1, zero(regression_label)] 7 | % gray: [0, zero(regression_label)] 8 | % NOTE: gt_rois and anchors are all the resized (say 500 -> 600) results! 9 | 10 | if isempty(gt_rois) 11 | bbox_targets = zeros(size(anchors, 1), 5, 'double'); 12 | bbox_targets(:, 1) = -1; 13 | return; 14 | end 15 | 16 | gt_labels = single(gt_labels); 17 | assert(all(gt_labels > 0)); 18 | 19 | if conf.revise_boundary_box 20 | % revise boundary boxes, just keep them! 21 | [new_anchors, check_] = refine_box(anchors, im_size_resize); 22 | % overlap between anchors and gt_rois 23 | ex_gt_overlaps = zeros(size(anchors, 1), size(gt_rois, 1)); 24 | ex_gt_overlaps(check_, :) = boxoverlap(new_anchors, gt_rois); 25 | % update anchors also! 26 | anchors(check_, :) = new_anchors; 27 | else 28 | % overlap between anchors and gt_rois 29 | ex_gt_overlaps = boxoverlap(anchors, gt_rois); 30 | % drop anchors which run out off image boundaries 31 | if conf.drop_boxes_runoff_image 32 | contained_in_image = is_contain_in_image(anchors, im_size_resize); 33 | ex_gt_overlaps(~contained_in_image, :) = 0; 34 | end 35 | end 36 | 37 | % for each anchor, get its max overlap with all gt_rois 38 | [ex_max_overlaps, ex_assignment] = max(ex_gt_overlaps, [], 2); 39 | % for each gt_rois, get its max overlap with anchors, 40 | % this is to ensure each gt has AT LEAST one matching anchor 41 | [gt_max_overlaps, gt_assignment] = max(ex_gt_overlaps, [], 1); 42 | % anchors with gt_max_overlaps may have more than one, 43 | % find them all as gt_best_matches 44 | % NOTE: must have 'gt_ind' here 45 | [gt_best_matches, gt_ind_must_keep_this_var] = find(bsxfun(@eq, ex_gt_overlaps, gt_max_overlaps)); 46 | 47 | %% chooese fg/bg indices 48 | % both (ex_max_overlaps >= conf.fg_thresh) and gt_best_matches are 49 | % assigned as positive examples 50 | % IMPORTANGT: leave out 'gt_best_matches' 51 | % fg_inds = unique([find(ex_max_overlaps >= conf.fg_thresh); gt_best_matches]); 52 | fg_inds = unique(find(ex_max_overlaps >= conf.fg_thresh)); 53 | 54 | % the logic for assigning labels to anchors can be satisfied 55 | % by both the positive label and the negative label; when this 56 | % happens, we prioritize the positive label to pursue high recall 57 | bg_inds = setdiff(find(ex_max_overlaps < conf.bg_thresh_hi & ... 58 | ex_max_overlaps >= conf.bg_thresh_lo), fg_inds); 59 | 60 | gray_inds = unique(find( ex_max_overlaps <= conf.gray_hi ... 61 | & ex_max_overlaps >= conf.gray_lo )); 62 | 63 | % if conf.drop_boxes_runoff_image && ~conf.revise_boundary_box 64 | % contained_in_image_ind = find(contained_in_image); 65 | % fg_inds = intersect(fg_inds, contained_in_image_ind); 66 | % bg_inds = intersect(bg_inds, contained_in_image_ind); 67 | % end 68 | % if isempty(bg_inds), keyboard; end 69 | 70 | %% 71 | % Find which gt ROI each ex ROI has max overlap with: 72 | % this will be the ex ROI's gt target 73 | target_rois = gt_rois(ex_assignment(fg_inds), :); 74 | src_rois = anchors(fg_inds, :); 75 | 76 | gt_info_catch_ind = zeros(size(gt_labels, 1), 1); 77 | gt_info_catch_ind(unique(ex_assignment(fg_inds))) = 1; 78 | gt_info = [gt_info_catch_ind single(gt_labels), gt_rois]; 79 | 80 | % we predict regression_label which is generated by an un-linear 81 | % transformation from src_rois and target_rois 82 | [regression_label] = fast_rcnn_bbox_transform(src_rois, target_rois); 83 | bbox_targets = -2*ones(size(anchors, 1), 5, 'double'); 84 | bbox_targets(fg_inds, :) = [gt_labels(ex_assignment(fg_inds)), regression_label]; 85 | bbox_targets(bg_inds, 1) = -1; 86 | bbox_targets(gray_inds, 1) = 0; 87 | end 88 | 89 | function contained = is_contain_in_image(boxes, im_size) 90 | contained = boxes >= 1 & bsxfun(@le, boxes, [im_size(2), im_size(1), im_size(2), im_size(1)]); 91 | contained = all(contained, 2); 92 | end 93 | 94 | function [anchors, check] = refine_box(anchors, im_size) 95 | anchors(anchors(:, 1) <= 0, 1) = 1; 96 | anchors(anchors(:, 2) <= 0, 2) = 1; 97 | 98 | anchors(anchors(:, 3) > im_size(2), 3) = im_size(2); 99 | anchors(anchors(:, 4) > im_size(1), 4) = im_size(1); 100 | 101 | check = all( (anchors(:, 1) < anchors(:, 3) & anchors(:, 2) < anchors(:, 4)), 2 ); 102 | anchors = anchors(check, :); 103 | end -------------------------------------------------------------------------------- /code/zoom_net/assets/update_rpn_boxes.m: -------------------------------------------------------------------------------- 1 | function recursive_rpn_box = update_rpn_boxes(... 2 | caffe_solver, level_num, net_inputs, all_rois_blob, rois_per_iter, image_size) 3 | % -------------------------------------------------------- 4 | % Zoom Network 5 | % Copyright (c) 2017, Hongyang Li 6 | % Licensed under The MIT License [see LICENSE for details] 7 | % -------------------------------------------------------- 8 | caffe_solver.set_phase('test'); 9 | reg_channel_num = size(net_inputs{1}{4}, 3); 10 | gpu_num = length(caffe_solver.nets); 11 | layer_name_template = @(x) sprintf('roi_bbox_pred%d', x); 12 | recursive_rpn_box = cell(gpu_num, 1); 13 | 14 | %% 15 | % prepare net_inputs, note that each input may have different roi_num 16 | roi_num_longest = 0; 17 | for i = 1 : gpu_num 18 | 19 | roi_num = size(all_rois_blob{i}, 4); 20 | input_block = {all_rois_blob{i}, zeros(1, 1, 1, roi_num), ... 21 | zeros(1, 1, reg_channel_num, roi_num), zeros(1, 1, reg_channel_num, roi_num)}; 22 | 23 | for kk = 1:level_num 24 | start_ind = 2+(kk-1)*4; 25 | end_ind = 5+(kk-1)*4; 26 | net_inputs{i}(start_ind:end_ind) = input_block; 27 | end 28 | if roi_num >= roi_num_longest, roi_num_longest = roi_num; end 29 | end 30 | 31 | % split into smaller chunks 32 | for kk = 1 : ceil(roi_num_longest / rois_per_iter) 33 | 34 | sub_ind_start = 1 + (kk-1) * rois_per_iter; 35 | sub_ind_end = min(roi_num_longest, kk * rois_per_iter); 36 | 37 | sub_net_inputs = cell(gpu_num, 1); 38 | for i = 1 : gpu_num 39 | 40 | sub_net_inputs{i}{1} = net_inputs{i}{1}; % image blob 41 | curr_im_roi_num = size(net_inputs{i}{2}, 4); 42 | 43 | for j = 2:length(net_inputs{i}) 44 | 45 | temp = net_inputs{i}{j}; % the j-th blob (label_blob, roi_blob, etc) in i-th image 46 | if sub_ind_end <= curr_im_roi_num 47 | sub_net_inputs{i}{j} = temp(:, :, :, sub_ind_start:sub_ind_end); 48 | else 49 | % say 761:800, yet temp (gpu2) only has 777 ROIs 50 | % fill the rest with zeros 51 | total_sub_length = sub_ind_end - sub_ind_start + 1; 52 | channel_num = size(temp, 3); 53 | 54 | if curr_im_roi_num >= sub_ind_start 55 | sub_net_inputs{i}{j} = temp(:, :, :, sub_ind_start:curr_im_roi_num); 56 | sub_net_inputs{i}{j}(:, :, channel_num, end+1: total_sub_length) = zeros; 57 | else 58 | 59 | sub_net_inputs{i}{j}(:, :, channel_num, 1:total_sub_length) = zeros; 60 | end 61 | end 62 | end 63 | end 64 | 65 | caffe_solver.reshape_as_input(sub_net_inputs); 66 | caffe_solver.forward(sub_net_inputs); 67 | 68 | for i = 1 : gpu_num 69 | 70 | % process output in each gpu/image 71 | im_size = image_size{i}.origin; 72 | scaled_im_size = image_size{i}.resize; 73 | ori_boxes = squeeze(all_rois_blob{i})'; % [1675 x 4] 74 | ori_boxes(end+1:roi_num_longest, :) = zeros; 75 | 76 | boxes = ori_boxes(sub_ind_start:sub_ind_end, 2:end) + 1; 77 | % store results for three levels 78 | pred_boxes = zeros(size(boxes, 1), size(boxes, 2), level_num); 79 | 80 | for j = 1:level_num 81 | 82 | output = ... 83 | caffe_solver.nets{i}.blobs(layer_name_template(j)).get_data(); 84 | reg_output = output(5:8, :)'; 85 | curr_level_pred_boxes = fast_rcnn_bbox_transform_inv(boxes, reg_output); 86 | % scale back 87 | curr_level_pred_boxes = bsxfun(@times, curr_level_pred_boxes - 1, ... 88 | ([im_size(2), im_size(1), im_size(2), im_size(1)] - 1) ./ ... 89 | ([scaled_im_size(2), scaled_im_size(1), scaled_im_size(2), scaled_im_size(1)] - 1)) + 1; 90 | pred_boxes(:, :, j) = clip_boxes(curr_level_pred_boxes, im_size(2), im_size(1)); 91 | end 92 | 93 | recursive_rpn_box{i}(sub_ind_start:sub_ind_end, :) = mean(pred_boxes, 3); 94 | end 95 | end % loopr for each chunk (the longest) 96 | 97 | for i = 1 : gpu_num 98 | curr_im_roi_num = size(net_inputs{i}{2}, 4); 99 | recursive_rpn_box{i} = recursive_rpn_box{i}(1:curr_im_roi_num, :); 100 | end 101 | caffe_solver.set_phase('train'); 102 | end 103 | 104 | function boxes = clip_boxes(boxes, im_width, im_height) 105 | % x1 >= 1 & <= im_width 106 | boxes(:, 1:4:end) = max(min(boxes(:, 1:4:end), im_width), 1); 107 | % y1 >= 1 & <= im_height 108 | boxes(:, 2:4:end) = max(min(boxes(:, 2:4:end), im_height), 1); 109 | % x2 >= 1 & <= im_width 110 | boxes(:, 3:4:end) = max(min(boxes(:, 3:4:end), im_width), 1); 111 | % y2 >= 1 & <= im_height 112 | boxes(:, 4:4:end) = max(min(boxes(:, 4:4:end), im_height), 1); 113 | end -------------------------------------------------------------------------------- /code/zoom_net/minor/copy_weights_to_mirror_layer.m: -------------------------------------------------------------------------------- 1 | function caffe_solver = copy_weights_to_mirror_layer(caffe_solver, gpu_num) 2 | 3 | layer_name = caffe_solver.nets{1}.layer_names; 4 | for i = 1:length(layer_name) 5 | 6 | copyed_ = false; 7 | curr_layer_name = layer_name{i}; 8 | if length(curr_layer_name) >= 10 && strcmp(curr_layer_name(1:10), 'inception_') 9 | mirror_name = [curr_layer_name(1:12) '_mirror' curr_layer_name(13:end)]; 10 | 11 | if find(strcmp(mirror_name, layer_name)) 12 | for j = 1:10 13 | try 14 | curr_weight = caffe_solver.nets{1}.params(curr_layer_name, j).get_data(); 15 | for mm = 1:gpu_num 16 | caffe_solver.nets{mm}.set_params_data(mirror_name, j, curr_weight); 17 | 18 | end 19 | copyed_ = true; 20 | catch 21 | break; 22 | end 23 | end 24 | if copyed_ 25 | fprintf('copy weights from (%s) to (%s) ...\n', curr_layer_name, mirror_name); 26 | end 27 | end 28 | end 29 | end -------------------------------------------------------------------------------- /code/zoom_net/minor/default_config.m: -------------------------------------------------------------------------------- 1 | function [conf, dataset] = default_config(mode, conf) 2 | % -------------------------------------------------------- 3 | % Zoom Network 4 | % Copyright (c) 2017, Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % -------------------------------------------------------- 7 | 8 | if strcmp(mode, 'train') 9 | 10 | conf.mode = 'train'; 11 | conf.gpu_id = 0:3; 12 | conf.dynamic_train_scale = true; 13 | conf.batch_size = 256; 14 | conf.ims_per_batch = 1; 15 | conf.rpn_max_size = 900; 16 | conf.rpn_min_size = 100; 17 | % make samples (fg/bg) more balanced 18 | conf.adjust_sample_ratio = true; 19 | conf.fg_fraction = 0.5; 20 | conf.fg_thresh = 0.6; 21 | conf.bg_thresh_hi = 0.15; 22 | conf.bg_thresh_lo = eps; 23 | conf.use_flip = false; 24 | % whether use other proposals as training data 25 | conf.target_only_gt = true; 26 | conf.loss_bbox_weight = [1 1 1]; 27 | conf.loss_cls_weight = [1 1 1]; 28 | % training logistics 29 | conf.save_interval = 5000; 30 | conf.init_net_file = fullfile(pwd, ... 31 | 'data', 'bn_inception_iter_900000.caffemodel'); 32 | 33 | elseif strcmp(mode, 'test') 34 | 35 | conf.mode = 'test'; 36 | conf.gpu_id = 0; 37 | conf.test.T = 1; 38 | conf.test.nms_mode = 'normal_nms'; 39 | conf.test.nms_thres = 0.6; % 0.7 : -0.05 : 0.5; 40 | conf.test.box_vote = false; 41 | conf.test.box_vote_ov_thres = 0.8; 42 | 43 | conf.test.keepTopBeforeNMS = 15000; 44 | conf.test.nms_keep_at_level = 3000; 45 | conf.test_scale_range = (1400:-50:250); 46 | conf.test_multiscale_max_size = 1600; 47 | % filter out small boxes during test 48 | conf.test.min_box_size = 2; 49 | conf.test.eval_top_k = 300; 50 | 51 | % not sure if they are active now 52 | conf.test.rois_per_iter = []; 53 | conf.test.useTopBox_num = []; 54 | end 55 | 56 | %% configuration 57 | conf.rng_seed = 4; 58 | % different depth, corresponding to various resolutions 59 | conf.multi_depth = true; 60 | % has numel(rpn_feat_stride) depths in the network 61 | conf.rpn_feat_stride = [8, 16, 32]; 62 | conf.revise_boundary_box = true; 63 | % only some scales are feasible as input due to the network structure 64 | conf.check_certain_scale = true; 65 | % add a RoI head 66 | conf.roi_followup = false; 67 | conf.train_T = 1; 68 | % class number (fg/bg/intermediate) 69 | conf.add_gray_cls = true; 70 | conf.gray_hi = 0.49; 71 | conf.gray_lo = 0.25; 72 | % anchor 73 | conf.base_size = 16*sqrt(2); 74 | conf.anchor_scale = 2.^(0:5); 75 | conf.ratios = [0.25, 0.5, 1, 2, 3]; 76 | % preset possible image size 77 | conf.min_size = max(conf.rpn_feat_stride); 78 | conf.max_size = 2000; 79 | 80 | % || image mean and init network (will be passed on to variable 'model' outside) 81 | ld = load('data/image_mean.mat'); 82 | if strcmp(conf.dataset, 'coco') 83 | conf.DATA.image_mean = ld.coco; 84 | else 85 | % strcmp(conf.dataset, 'imagenet') || strcmp(conf.dataset, 'imagenet_3k') 86 | conf.DATA.image_mean = ld.ilsvrc14_det; 87 | end 88 | clear ld; 89 | 90 | %% dataset 91 | dataset = []; 92 | if strcmp(conf.dataset, 'coco') 93 | 94 | root_dir = './data/datasets/coco'; 95 | addpath(genpath([root_dir '/coco_eval'])); 96 | cprintf('blue', 'loading COCO dataset ... \n'); 97 | dataset.imdb_train{1} = CocoApi([root_dir '/annotations/instances_train2014.json']); 98 | fprintf('train_train (%d) images\n', length(dataset.imdb_train{1}.data.images)); 99 | dataset.imdb_train{2} = CocoApi([root_dir '/annotations/instances_valminusminival2014.json']); 100 | fprintf('train_val (%d) images\n', length(dataset.imdb_train{2}.data.images)); 101 | dataset.roidb_train = cell(size(dataset.imdb_train)); 102 | 103 | dataset.imdb_test.coco = CocoApi([root_dir '/annotations/instances_minival2014.json']); 104 | fprintf('val_val (%d) images\n', length(dataset.imdb_test.coco.data.images)); 105 | dataset.roidb_test = struct(); 106 | conf.COCO.train_root{1} = [root_dir '/train2014']; 107 | conf.COCO.train_root{2} = [root_dir '/val2014']; 108 | conf.COCO.test_root = [root_dir '/val2014']; 109 | 110 | elseif strcmp(conf.dataset, 'imagenet_3k') 111 | 112 | root_dir = './data/datasets/imagenet_3k'; 113 | cprintf('blue', 'loading Extended ImageNet dataset ... \n'); 114 | conf.EI.train_root = [root_dir '/cls_3k_train_im_v0']; 115 | conf.EI.test_root = [root_dir '/cls_3k_val_im_v0']; 116 | ld = load('data/datasets/imagenet_3k/image_3k_subset_v1.mat'); 117 | conf.EI.train_list = ld.train_list; 118 | conf.EI.val_list = ld.val_list; clear ld; 119 | 120 | fprintf('train (%d) images\n', length(conf.EI.train_list)); 121 | fprintf('val (%d) images\n', length(conf.EI.val_list)); 122 | % useless, for legacy reason 123 | dataset.imdb_train{1} = []; 124 | dataset.roidb_train = cell(size(dataset.imdb_train)); 125 | 126 | elseif strcmp(conf.dataset, 'voc') 127 | dataset.imdb_train{1} = []; 128 | dataset.roidb_train = cell(size(dataset.imdb_train)); 129 | end 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /code/zoom_net/minor/draw_damn_image.m: -------------------------------------------------------------------------------- 1 | function draw_damn_image(conf, im_file_name, gt_info, im_size_resize, ... 2 | src_rois, gt_rois, add_gray_cls, labels, ... 3 | fg_rois_per_image, rois_per_image, src_rois_label, choose_fg_index, investigate) 4 | % -------------------------------------------------------- 5 | % Zoom Network 6 | % Copyright (c) 2017, Hongyang Li 7 | % Licensed under The MIT License [see LICENSE for details] 8 | % -------------------------------------------------------- 9 | 10 | gt_label = gt_info(:, 2); 11 | gt_all = gt_info(:, 3:end); 12 | gt_all_hw = floor([gt_all(:, 4)-gt_all(:, 2), gt_all(:, 3)-gt_all(:, 1)]); 13 | figure(conf.temp_curr_level); 14 | im = imread(im_file_name); 15 | im = bsxfun(@minus, single(im), conf.DATA.image_mean); 16 | target_size = im_size_resize; 17 | im_resize = imresize(im, target_size, 'bilinear', 'antialiasing', false); 18 | 19 | hold on; 20 | imshow(mat2gray(im_resize)); 21 | gt_info = double(round(gt_info)); 22 | gt_rois_success = gt_info(logical(gt_info(:,1)), 3:end); 23 | gt_rois_fail = gt_info(~logical(gt_info(:,1)), 3:end); 24 | % % temp 25 | % ld = load('./data/datasets/ilsvrc14_det/ILSVRC2014_devkit/data/meta_det.mat'); 26 | % temp = ld.synsets_det(1:200); 27 | % gt_str = extractfield(temp(gt_label), 'name')'; 28 | % gt_str_success = gt_str(logical(gt_info(:,1))); 29 | if size(src_rois, 1) ~= 0 30 | 31 | % cellfun(@(x) rectangle('Position', RectLTRB2LTWH(x), 'EdgeColor', 'g'), ... 32 | % num2cell(src_rois, 2)); 33 | cellfun(@(x, y) text(x(1), x(2), sprintf('%d', y), 'backgroundcolor', 'g'), ... 34 | num2cell(src_rois, 2), num2cell(src_rois_label)); 35 | cellfun(@(x) rectangle('Position', RectLTRB2LTWH(x), 'EdgeColor', 'g', 'LineWidth', 1), ... 36 | num2cell(src_rois(choose_fg_index, :), 2)); 37 | % draw a single pos sample 38 | rectangle('Position', RectLTRB2LTWH(src_rois(1,:)), 'EdgeColor', 'b', 'linewidth', 2); 39 | text(src_rois(1,1), src_rois(1,2), sprintf('%d', src_rois_label(1)), 'color', 'w', ... 40 | 'backgroundcolor', 'b'); 41 | end 42 | % draw GT 43 | cellfun(@(x) rectangle('Position', RectLTRB2LTWH(x), 'EdgeColor', 'r', 'linewidth', 2), ... 44 | num2cell(gt_rois_success, 2)); 45 | cellfun(@(x) rectangle('Position', RectLTRB2LTWH(x), 'EdgeColor', 'r', ... 46 | 'linewidth', 2, 'linestyle', '--'), ... 47 | num2cell(gt_rois_fail, 2)); 48 | cellfun(@(x, y, z) text(x(3), x(2), sprintf('%d (%d,%d)', y, z(1), z(2)), 'backgroundcolor', 'r'), ... 49 | num2cell(double(gt_all), 2), num2cell(gt_label), num2cell(gt_all_hw, 2)); 50 | 51 | %============ 52 | anchors = investigate.anchors; 53 | gt_rois_resize = investigate.gt_box_resize; 54 | overlap = compute_overlap(gt_rois_resize, anchors); 55 | nearest_anchor = anchors(extractfield(overlap, 'max_ind'), :); 56 | ov_score = extractfield(overlap, 'max'); 57 | gt_indicator = ov_score>0; 58 | w = size(im_resize, 2); h = size(im_resize, 1); 59 | nearest_anchor(:, 1) = max(nearest_anchor(:, 1), 1); 60 | nearest_anchor(:, 2) = max(nearest_anchor(:, 2), 1); 61 | nearest_anchor(:, 3) = min(nearest_anchor(:, 3), w); 62 | nearest_anchor(:, 4) = min(nearest_anchor(:, 4), h); 63 | 64 | for fuck = 1:length(gt_indicator) 65 | if gt_indicator(fuck) 66 | rectangle('Position', RectLTRB2LTWH(nearest_anchor(fuck, :)), 'EdgeColor', 'y', 'linewidth', 1.5); 67 | text(nearest_anchor(fuck,3), nearest_anchor(fuck,4), sprintf('%.2f', ov_score(fuck)), 'color', 'b', ... 68 | 'backgroundcolor', 'y'); 69 | end 70 | end 71 | hold off; 72 | 73 | % write batch number info and others 74 | [~, im_name, ~] = fileparts(im_file_name); 75 | title(sprintf('level: %d, feat stride: %d\nindex, %d, %s (resized image: %d x %d)\nall pos anchor boxes (%d, green), GT boxes (total %d in red, %d failed)', ... 76 | conf.temp_curr_level, conf.rpn_feat_stride(conf.temp_curr_level), ... 77 | conf.temp_which_ind, strrep(im_name, '_', '\_'), size(im_resize, 1), size(im_resize, 2), ... 78 | size(src_rois, 1), size(gt_rois, 1), sum(~gt_info(:,1)))); 79 | 80 | if ~add_gray_cls 81 | text(1, target_size(1), sprintf(... 82 | 'actual fg/bg:: %d/%d\ndefault fg/batchSize:: %d/%d', ... 83 | length(find(labels>0)), length(find(labels==0)), ... 84 | fg_rois_per_image, rois_per_image), 'backgroundcolor', 'g'); 85 | else 86 | text(1, target_size(1), sprintf(... 87 | 'actual fg/bg:: %d/%d\ndefault fg/batchSize:: %d/%d\ngray cls num:: %d', ... 88 | length(find(labels==1)), length(find(labels==0)), ... 89 | fg_rois_per_image, rois_per_image, ... 90 | length(find(labels==2))), 'backgroundcolor', 'g'); 91 | end 92 | show_anchor_folder = sprintf('./output/visualize_anchor/%s', conf.model_id); 93 | mkdir_if_missing(show_anchor_folder); 94 | 95 | print(gcf, '-dpng', '-r0', sprintf('%s/ind_%d_level_%d.jpg', ... 96 | show_anchor_folder, conf.temp_which_ind, conf.temp_curr_level)); 97 | print(sprintf('%s/ind_%d_level_%d.pdf', ... 98 | show_anchor_folder, conf.temp_which_ind, conf.temp_curr_level), '-dpdf', '-r0'); 99 | end 100 | -------------------------------------------------------------------------------- /code/zoom_net/minor/dynamic_change_scale.m: -------------------------------------------------------------------------------- 1 | function new_scale = dynamic_change_scale(conf, gt_rois, im_size) 2 | 3 | % ugly_size_set = conf.base_size .* conf.anchor_scale; 4 | % % randomly choose one anchor size and one GT 5 | % ugly_size = ugly_size_set(randi(length(ugly_size_set))); 6 | 7 | % liuyu: 8 | ugly_size = randi(conf.liuyu.range); 9 | 10 | chosen_gt = gt_rois(randi(size(gt_rois, 1)), :); 11 | gt_shorter_dim = min(chosen_gt(3)-chosen_gt(1), chosen_gt(4)-chosen_gt(2)); 12 | im_shorter_dim = min(im_size(1), im_size(2)); 13 | 14 | new_scale = round( ( ugly_size / gt_shorter_dim ) * im_shorter_dim ); 15 | end 16 | -------------------------------------------------------------------------------- /code/zoom_net/minor/fetch_required_info.m: -------------------------------------------------------------------------------- 1 | function imdb_info_required = fetch_required_info(imdb_info, sub_ind_list, dataset) 2 | % -------------------------------------------------------- 3 | % Zoom Network 4 | % Copyright (c) 2017, Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % -------------------------------------------------------- 7 | 8 | imdb_info_required = cell(length(sub_ind_list), 1); 9 | 10 | for i = 1:length(imdb_info_required) 11 | 12 | imdb_info_required{i}.imdb_merge_size = imdb_info.imdb_merge_size(sub_ind_list{i}, :); 13 | imdb_info_required{i}.im_path_root = imdb_info.im_path_root; 14 | imdb_info_required{i}.imdb_merge_path = imdb_info.imdb_merge_path(sub_ind_list{i}); 15 | if strcmp(dataset, 'coco') 16 | imdb_info_required{i}.im_id = imdb_info.im_id(sub_ind_list{i}); 17 | 18 | elseif strcmp(dataset, 'imagenet') || strcmp(dataset, 'voc') 19 | imdb_info_required{i}.roidb_merge = imdb_info.roidb_merge(sub_ind_list{i}); 20 | 21 | elseif strcmp(dataset, 'imagenet_3k') 22 | % update the 'roidb_merge' field 23 | imdb_info_required{i}.roidb_merge.boxes = cell2mat(imdb_info.bbox(sub_ind_list{i})); 24 | obj_num = size(imdb_info_required{i}.roidb_merge.boxes, 1); 25 | imdb_info_required{i}.roidb_merge.class = ... 26 | repmat(imdb_info.label(sub_ind_list{i}), [obj_num 1]); 27 | end 28 | end -------------------------------------------------------------------------------- /code/zoom_net/minor/init_zoom_net.m: -------------------------------------------------------------------------------- 1 | function conf= init_zoom_net(conf) 2 | % -------------------------------------------------------- 3 | % Zoom Network 4 | % Copyright (c) 2017, Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % -------------------------------------------------------- 7 | 8 | % adjust the configuration 9 | % || prepare anchors 10 | if conf.multi_depth 11 | m_level = 3; 12 | conf.anchors = proposal_generate_anchors_multi(... 13 | 'base_size', conf.base_size, ... 14 | 'scales', conf.anchor_scale, ... 15 | 'ratios', conf.ratios); 16 | 17 | else 18 | m_level = 1; 19 | conf.anchors{1} = proposal_generate_anchors(... 20 | 'base_size', conf.base_size, ... 21 | 'scales', conf.anchor_scale, ... 22 | 'ratios', conf.ratios ... 23 | ); 24 | end 25 | 26 | if ~conf.check_certain_scale 27 | output_map_cache = sprintf('data/output_map_min%d_max%d_everScale.mat', ... 28 | conf.min_size, conf.max_size); 29 | else 30 | output_map_cache = sprintf('data/output_map_min%d_max%d_certScale.mat', ... 31 | conf.min_size, conf.max_size); 32 | end 33 | 34 | % || traversal search on possible output size of the network 35 | try 36 | ld = load(output_map_cache); 37 | conf.output_width_map = ld.output_width_map; 38 | conf.output_height_map = ld.output_height_map; 39 | if conf.check_certain_scale 40 | conf.certain_scale = ld.certain_scale; 41 | end 42 | clear ld; 43 | catch 44 | cprintf('blue', 'pre-calculating output size of the zoom network...\n'); 45 | gpu_id = conf.gpu_id(1); 46 | solver_file = 'model/zoom/bn/base/solver_deploy_check.prototxt'; 47 | 48 | if conf.check_certain_scale 49 | % for zoom network (hourglass) structure 50 | [conf.output_width_map, conf.output_height_map, conf.certain_scale] = ... 51 | proposal_calc_output_size_certainScale(conf, ... 52 | solver_file, gpu_id, length(conf.rpn_feat_stride)); 53 | % save the file for future use 54 | output_width_map = conf.output_width_map; 55 | output_height_map = conf.output_height_map; 56 | certain_scale = conf.certain_scale; 57 | save(output_map_cache, 'output_width_map', 'output_height_map', 'certain_scale'); 58 | else 59 | assert(m_level==1); 60 | output_name = 'inception_5b/output'; 61 | for i = 1:m_level 62 | [conf.output_width_map{i}, conf.output_height_map{i}] = ... 63 | proposal_calc_output_size(conf, ... 64 | solver_file, gpu_id, output_name, i); 65 | end 66 | output_width_map = conf.output_width_map; 67 | output_height_map = conf.output_height_map; 68 | save(output_map_cache, 'output_width_map', 'output_height_map'); 69 | end 70 | end 71 | 72 | if strcmp(conf.mode, 'train') 73 | assert(conf.fg_thresh > conf.gray_hi); 74 | assert(conf.gray_hi > conf.gray_lo); 75 | assert(conf.gray_lo > conf.bg_thresh_hi); 76 | end 77 | if strcmp(conf.mode, 'test') 78 | conf.chunk_mode = true; 79 | try 80 | conf.total_chunk; 81 | conf.curr_chunk; 82 | catch 83 | conf.chunk_mode = false; 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /code/zoom_net/minor/proposal_calc_output_size.m: -------------------------------------------------------------------------------- 1 | function [output_width_map, output_height_map] = ... 2 | proposal_calc_output_size(conf, test_solver_def_file, gpu_id, ... 3 | output_name, curr_level) 4 | % -------------------------------------------------------- 5 | % Faster R-CNN 6 | % Copyright (c) 2015, Shaoqing Ren 7 | % Licensed under The MIT License [see LICENSE for details] 8 | % -------------------------------------------------------- 9 | 10 | % init caffe net using Solver 11 | caffe_solver = caffe.Solver(test_solver_def_file, gpu_id); 12 | caffe_solver.set_phase('test'); 13 | 14 | input = conf.min_size : conf.max_size; 15 | output_w = nan(size(input)); 16 | output_h = nan(size(input)); 17 | fix_size = 100; 18 | 19 | for i = 1:length(input) 20 | 21 | s = input(i); 22 | im_blob = single(zeros(s, fix_size, 3, 1)); 23 | net_inputs = {{im_blob}}; 24 | 25 | % Reshape net's input blobs 26 | caffe_solver.reshape_as_input(net_inputs); 27 | caffe_solver.forward(net_inputs); 28 | 29 | cls_score = caffe_solver.nets{1}.blobs(output_name).get_data(); 30 | output_w(i) = size(cls_score, 1); 31 | output_h(i) = output_w(i); 32 | tic_toc_print('level m=%d, %d/%d,\t\tinput_hw, (%d(fake) x %d),\t\toutput_hw,(%d x %d)\n', ... 33 | curr_level, i, length(input), fix_size, s, output_h(i), output_w(i)); 34 | end 35 | 36 | output_width_map = containers.Map(input, output_w); 37 | output_height_map = containers.Map(input, output_h); 38 | 39 | caffe.reset_all(); 40 | end 41 | -------------------------------------------------------------------------------- /code/zoom_net/minor/proposal_calc_output_size_certainScale.m: -------------------------------------------------------------------------------- 1 | function [output_width_map, output_height_map, certain_scale] = ... 2 | proposal_calc_output_size_certainScale(... 3 | conf, solver_def_file, gpu_id, end_level) 4 | % -------------------------------------------------------- 5 | % Zoom Network 6 | % Copyright (c) 2017, Hongyang Li 7 | % Licensed under The MIT License [see LICENSE for details] 8 | % -------------------------------------------------------- 9 | 10 | arch = 'bn_balance'; 11 | % this is the most customized part 12 | check_list_blob_name{1}{1} = 'inception_3b/output'; 13 | check_list_blob_name{1}{2} = 'inception_3c_mirror_upsample'; 14 | check_list_blob_name{2}{1} = 'inception_4d/output'; 15 | check_list_blob_name{2}{2} = 'inception_4e_mirror_upsample'; 16 | check_list_blob_name{3}{1} = 'inception_5b/output'; 17 | 18 | if strcmp(arch, 'bn') 19 | 20 | check_list_blob_name{3}{2} = 'inception_d2_parallel/output'; 21 | check_list_blob_name{3}{3} = 'inception_d3_parallel/output'; 22 | 23 | elseif strcmp(arch, 'bn_balance') || strcmp(arch, 'bn_roi_followUp') 24 | 25 | check_list_blob_name{3}{2} = 'inception_d2_para/output'; 26 | 27 | else 28 | error('unknown network structure'); 29 | end 30 | 31 | certain_scale = []; 32 | % caffe_log_file_base = fullfile('debug_'); 33 | % caffe.init_log(caffe_log_file_base); 34 | % solver_def_file = [solver_def_file(1:end-9) '_check.prototxt']; 35 | % init caffe net using Solver 36 | caffe_solver = caffe.Solver(solver_def_file, gpu_id); 37 | caffe_solver.set_phase('test'); 38 | 39 | output_w = cell(end_level, 1); output_h = cell(end_level, 1); 40 | input = conf.min_size : conf.max_size; 41 | for kk = 1:end_level, output_w{kk} = nan(size(input)); output_h{kk} = nan(size(input)); end 42 | % for the purpose of saving memory 43 | fix_size = 128; 44 | 45 | fprintf('\nchecking range: %d - %d ...\n', input(1), input(end)); 46 | 47 | for i = 1:length(input) 48 | 49 | curr_size = input(i); 50 | im_blob = single(zeros(curr_size, fix_size, 3, 1)); 51 | net_inputs = {{im_blob}}; 52 | 53 | % Reshape net's input blobs 54 | caffe_solver.reshape_as_input(net_inputs); 55 | caffe_solver.forward(net_inputs); 56 | 57 | USE_CURR_SIZE = true; 58 | for kk = 1:end_level 59 | check_var = []; 60 | for check_blob_id = 1:length(check_list_blob_name{kk}) 61 | output_name = check_list_blob_name{kk}{check_blob_id}; 62 | spatial_size = caffe_solver.nets{1}.blobs(output_name).get_data(); 63 | check_var = [check_var size(spatial_size, 1)]; 64 | end 65 | if sum(gradient(check_var)) ~= 0 66 | USE_CURR_SIZE = false; 67 | break; 68 | else 69 | output_w{kk}(i) = check_var(1); 70 | output_h{kk}(i) = check_var(1); 71 | end 72 | end 73 | 74 | if ~USE_CURR_SIZE 75 | % fprintf('\tsize %d is skipped ...\n', curr_size); 76 | else 77 | certain_scale = [certain_scale curr_size]; 78 | fprintf('\tsize %d is saved ...\n', curr_size); 79 | end 80 | end 81 | 82 | for kk = 1:end_level 83 | output_width_map{kk} = containers.Map(input, output_w{kk}); 84 | output_height_map{kk} = containers.Map(input, output_h{kk}); 85 | end 86 | caffe.reset_all(); 87 | end 88 | -------------------------------------------------------------------------------- /code/zoom_net/minor/proposal_generate_anchors.m: -------------------------------------------------------------------------------- 1 | function anchors = proposal_generate_anchors(varargin) 2 | % anchors = proposal_generate_anchors(cache_name, varargin) 3 | % -------------------------------------------------------- 4 | % Faster R-CNN 5 | % Copyright (c) 2015, Shaoqing Ren 6 | % Licensed under The MIT License [see LICENSE for details] 7 | % -------------------------------------------------------- 8 | 9 | ip = inputParser; 10 | % the size of the base anchor 11 | ip.addParameter('base_size', 16, @isscalar); 12 | % ratio list of anchors 13 | ip.addParameter('ratios', [0.5, 1, 2], @ismatrix); 14 | % scale list of anchors 15 | ip.addParameter('scales', 2.^(3:5), @ismatrix); 16 | ip.parse(varargin{:}); 17 | opts = ip.Results; 18 | 19 | base_anchor = [1, 1, opts.base_size, opts.base_size]; 20 | ratio_anchors = ratio_jitter(base_anchor, opts.ratios); 21 | anchors = cellfun(@(x) scale_jitter(x, opts.scales), num2cell(ratio_anchors, 2), 'UniformOutput', false); 22 | anchors = cat(1, anchors{:}); 23 | 24 | end 25 | 26 | function anchors = ratio_jitter(anchor, ratios) 27 | ratios = ratios(:); 28 | 29 | w = anchor(3) - anchor(1) + 1; 30 | h = anchor(4) - anchor(2) + 1; 31 | x_ctr = anchor(1) + (w - 1) / 2; 32 | y_ctr = anchor(2) + (h - 1) / 2; 33 | size = w * h; 34 | 35 | size_ratios = size ./ ratios; 36 | ws = round(sqrt(size_ratios)); 37 | hs = round(ws .* ratios); 38 | 39 | anchors = [x_ctr - (ws - 1) / 2, y_ctr - (hs - 1) / 2, x_ctr + (ws - 1) / 2, y_ctr + (hs - 1) / 2]; 40 | end 41 | 42 | function anchors = scale_jitter(anchor, scales) 43 | scales = scales(:); 44 | 45 | w = anchor(3) - anchor(1) + 1; 46 | h = anchor(4) - anchor(2) + 1; 47 | x_ctr = anchor(1) + (w - 1) / 2; 48 | y_ctr = anchor(2) + (h - 1) / 2; 49 | 50 | ws = w * scales; 51 | hs = h * scales; 52 | 53 | anchors = [x_ctr - (ws - 1) / 2, y_ctr - (hs - 1) / 2, x_ctr + (ws - 1) / 2, y_ctr + (hs - 1) / 2]; 54 | end 55 | 56 | -------------------------------------------------------------------------------- /code/zoom_net/minor/proposal_generate_anchors_multi.m: -------------------------------------------------------------------------------- 1 | function anchors = proposal_generate_anchors_multi(varargin) 2 | % -------------------------------------------------------- 3 | % Zoom Network 4 | % Copyright (c) 2017, Hongyang Li 5 | % Licensed under The MIT License [see LICENSE for details] 6 | % -------------------------------------------------------- 7 | 8 | ip = inputParser; 9 | % the size of the base anchor 10 | ip.addParameter('base_size', 16*sqrt(2), @isscalar); 11 | % ratio list of anchors 12 | ip.addParameter('ratios', [0.5, 1, 2], @ismatrix); 13 | % scale list of anchors 14 | ip.addParameter('scales', 2.^(0:5), @ismatrix); 15 | ip.parse(varargin{:}); 16 | opts = ip.Results; 17 | scales = opts.scales; 18 | 19 | base_anchor = [1, 1, opts.base_size, opts.base_size]; 20 | ratio_anchors = ratio_jitter(base_anchor, opts.ratios); 21 | 22 | % 3 is the level number 23 | anchors = cell(3, 1); 24 | interval = length(scales)/3; 25 | for i = 1:3 26 | window = (1 + (i-1)*interval) : (interval + (i-1)*interval); 27 | out = cellfun(@(x) scale_jitter(x, scales(window)), ... 28 | num2cell(ratio_anchors, 2), 'UniformOutput', false); 29 | anchors{i} = cat(1, out{:}); 30 | end 31 | 32 | end 33 | 34 | function anchors = ratio_jitter(anchor, ratios) 35 | ratios = ratios(:); 36 | 37 | w = anchor(3) - anchor(1) + 1; 38 | h = anchor(4) - anchor(2) + 1; 39 | x_ctr = anchor(1) + (w - 1) / 2; 40 | y_ctr = anchor(2) + (h - 1) / 2; 41 | size = w * h; 42 | 43 | size_ratios = size ./ ratios; 44 | ws = round(sqrt(size_ratios)); 45 | hs = round(ws .* ratios); 46 | 47 | anchors = [x_ctr - (ws - 1) / 2, y_ctr - (hs - 1) / 2, x_ctr + (ws - 1) / 2, y_ctr + (hs - 1) / 2]; 48 | end 49 | 50 | function anchors = scale_jitter(anchor, scales) 51 | scales = scales(:); 52 | 53 | w = anchor(3) - anchor(1) + 1; 54 | h = anchor(4) - anchor(2) + 1; 55 | x_ctr = anchor(1) + (w - 1) / 2; 56 | y_ctr = anchor(2) + (h - 1) / 2; 57 | 58 | ws = w * scales; 59 | hs = h * scales; 60 | 61 | anchors = [x_ctr - (ws - 1) / 2, y_ctr - (hs - 1) / 2, x_ctr + (ws - 1) / 2, y_ctr + (hs - 1) / 2]; 62 | end 63 | 64 | -------------------------------------------------------------------------------- /code/zoom_net/minor/proposal_locate_anchors.m: -------------------------------------------------------------------------------- 1 | function anchors = proposal_locate_anchors(... 2 | conf, im_size_resize, feature_map_size) 3 | % refactored by Hongyang, generate anchors for each scale PER image 4 | % update: 'im_size' is the resized image 5 | % 6 | % train: 'proposal_generate_minibatch_on_the_fly.m' 7 | % test: 'proposal_im_detect.m' 8 | % for train, the input argument is the first two, and for test, all three 9 | % input arguments are provided. 10 | 11 | if ~exist('feature_map_size', 'var') 12 | feature_map_size = []; 13 | end 14 | 15 | anchors = proposal_locate_anchors_single_scale(... 16 | im_size_resize, conf, feature_map_size); 17 | 18 | end 19 | 20 | function anchors = proposal_locate_anchors_single_scale(... 21 | im_size_resize, conf, feature_map_size) 22 | 23 | curr_level = conf.temp_curr_level; 24 | 25 | if isempty(feature_map_size) 26 | 27 | output_size = cell2mat([conf.output_height_map{curr_level}.values({im_size_resize(1)}), ... 28 | conf.output_width_map{curr_level}.values({im_size_resize(2)})]); 29 | else 30 | output_size = feature_map_size; 31 | end 32 | 33 | shift_x = (0:(output_size(2)-1)) * conf.rpn_feat_stride(curr_level); 34 | shift_y = (0:(output_size(1)-1)) * conf.rpn_feat_stride(curr_level); 35 | [shift_x, shift_y] = meshgrid(shift_x, shift_y); 36 | 37 | % concat anchors as [channel, height, width], where channel is the fastest dimension. 38 | anchors = reshape(bsxfun(@plus, permute(conf.anchors{curr_level}, [1, 3, 2]), ... 39 | permute([shift_x(:), shift_y(:), shift_x(:), shift_y(:)], [3, 1, 2])), [], 4); 40 | 41 | % equals to 42 | % anchors = arrayfun(@(x, y) single(bsxfun(@plus, conf.anchors, [x, y, x, y])), ... 43 | % shift_x, shift_y, 'UniformOutput', false); 44 | % anchors = reshape(anchors, [], 1); 45 | % anchors = cat(1, anchors{:}); 46 | 47 | end -------------------------------------------------------------------------------- /code/zoom_net/process_test_output.m: -------------------------------------------------------------------------------- 1 | function [curr_level_output, inter_output] = process_test_output(conf, curGPU_info) 2 | % curr_level_output is of size [anchor_num x 5] on a given level and scale 3 | inter_output = []; 4 | curr_level = conf.temp_curr_level; 5 | output_blob = curGPU_info.output_blob; 6 | ori_im_size = curGPU_info.ori_im_size; 7 | scaled_im_size = curGPU_info.scaled_im_size; 8 | blob_match_template = @(x) (strcmp(extractfield(output_blob, 'blob_name'), x)); 9 | 10 | if conf.roi_followup 11 | 12 | % 'roi_bbox_pred1' 13 | box_deltas = output_blob(blob_match_template(sprintf('roi_bbox_pred%d', curr_level))).data(5:8, :)'; 14 | % 'roi_cls_prob1' 15 | scores = output_blob(blob_match_template(sprintf('roi_cls_prob%d', curr_level))).data(2, :)'; 16 | 17 | boxes = conf.temp_raw_rescale_rois; 18 | pred_boxes = fast_rcnn_bbox_transform_inv(boxes, box_deltas); 19 | % scale back 20 | pred_boxes = bsxfun(@times, pred_boxes - 1, ... 21 | ([ori_im_size(2), ori_im_size(1), ori_im_size(2), ori_im_size(1)] - 1) ./ ... 22 | ([scaled_im_size(2), scaled_im_size(1), scaled_im_size(2), scaled_im_size(1)] - 1)) + 1; 23 | pred_boxes = clip_boxes(pred_boxes, ori_im_size(2), ori_im_size(1)); 24 | curr_level_output = [pred_boxes scores]; 25 | 26 | else 27 | 28 | % 'proposal_bbox_pred1' 29 | box_deltas = output_blob(blob_match_template(sprintf('proposal_bbox_pred%d', curr_level))).data; 30 | % 'proposal_cls_prob1' 31 | scores = output_blob(blob_match_template(sprintf('proposal_cls_prob%d', curr_level))).data(:, :, 2); 32 | scores = reshape(scores, size(box_deltas, 1), size(box_deltas, 2), []); 33 | curr_level_output = further_process_output(... 34 | conf, box_deltas, scores, scaled_im_size, ori_im_size); 35 | end 36 | 37 | 38 | if length(output_blob) == 12 39 | % means there are intermediate supervision results 40 | box_deltas_mi = output_blob(blob_match_template(sprintf('proposal_bbox_pred%d_mi', curr_level))).data; 41 | % 'proposal_cls_prob1' 42 | scores_mi = output_blob(blob_match_template(sprintf('proposal_cls_prob%d_mi', curr_level))).data(:, :, 2); 43 | scores_mi = reshape(scores_mi, size(box_deltas_mi, 1), size(box_deltas_mi, 2), []); 44 | inter_output = further_process_output(... 45 | conf, box_deltas_mi, scores_mi, scaled_im_size, ori_im_size); 46 | end 47 | 48 | end 49 | 50 | function output = further_process_output(conf, box_deltas, scores, scaled_im_size, ori_im_size) 51 | %% box_deltas 52 | featuremap_size = [size(box_deltas, 2), size(box_deltas, 1)]; 53 | % permute from [width, height, channel] to [channel, height, width], 54 | % where channel is the fastest dimension 55 | box_deltas = permute(box_deltas, [3, 2, 1]); 56 | box_deltas = reshape(box_deltas, 4, [])'; 57 | % disp(scaled_im_size); 58 | % disp(featuremap_size); 59 | 60 | anchors = proposal_locate_anchors(conf, scaled_im_size, featuremap_size); 61 | pred_boxes = fast_rcnn_bbox_transform_inv(anchors, box_deltas); 62 | % scale back 63 | pred_boxes = bsxfun(@times, pred_boxes - 1, ... 64 | ([ori_im_size(2), ori_im_size(1), ori_im_size(2), ori_im_size(1)] - 1) ./ ... 65 | ([scaled_im_size(2), scaled_im_size(1), scaled_im_size(2), scaled_im_size(1)] - 1)) + 1; 66 | pred_boxes = clip_boxes(pred_boxes, ori_im_size(2), ori_im_size(1)); 67 | 68 | %% scores 69 | scores = permute(scores, [3, 2, 1]); 70 | scores = scores(:); 71 | 72 | % drop too small boxes 73 | [pred_boxes, scores] = filter_boxes(conf.test.min_box_size, pred_boxes, scores); 74 | [scores, scores_ind] = sort(scores, 'descend'); 75 | pred_boxes = pred_boxes(scores_ind, :); 76 | % size: anchor_num x 5 77 | output = [pred_boxes, scores]; 78 | 79 | end 80 | 81 | function [boxes, scores] = filter_boxes(min_box_size, boxes, scores) 82 | widths = boxes(:, 3) - boxes(:, 1) + 1; 83 | heights = boxes(:, 4) - boxes(:, 2) + 1; 84 | 85 | valid_ind = widths >= min_box_size & heights >= min_box_size; 86 | boxes = boxes(valid_ind, :); 87 | scores = scores(valid_ind, :); 88 | end 89 | 90 | function boxes = clip_boxes(boxes, im_width, im_height) 91 | % x1 >= 1 & <= im_width 92 | boxes(:, 1:4:end) = max(min(boxes(:, 1:4:end), im_width), 1); 93 | % y1 >= 1 & <= im_height 94 | boxes(:, 2:4:end) = max(min(boxes(:, 2:4:end), im_height), 1); 95 | % x2 >= 1 & <= im_width 96 | boxes(:, 3:4:end) = max(min(boxes(:, 3:4:end), im_width), 1); 97 | % y2 >= 1 & <= im_height 98 | boxes(:, 4:4:end) = max(min(boxes(:, 4:4:end), im_height), 1); 99 | end -------------------------------------------------------------------------------- /code/zoom_net/rpn_fetch_data.m: -------------------------------------------------------------------------------- 1 | function [net_inputs, all_rois_blob, image_size] = ... 2 | rpn_fetch_data(conf, imdb_info_required) 3 | % -------------------------------------------------------- 4 | % Zoom Network 5 | % Copyright (c) 2017, Hongyang Li 6 | % Licensed under The MIT License [see LICENSE for details] 7 | % -------------------------------------------------------- 8 | 9 | gpu_num = length(conf.gpu_id); 10 | assert(gpu_num == length(imdb_info_required)); 11 | net_inputs = cell(gpu_num, 1); 12 | all_rois_blob = cell(gpu_num, 1); 13 | image_size = cell(gpu_num, 1); 14 | empty_gt = false; 15 | 16 | for i = 1:length(conf.gpu_id) 17 | % loop for each gpu card 18 | conf.temp_which_gpu = i; 19 | 20 | % check if the image has empty boxes (due to various reasons) 21 | if strcmp(conf.dataset, 'coco') 22 | % update the field 'roidb_merge' for coco 23 | [imdb_info_required{i}.roidb_merge, empty_gt] = ... 24 | collect_coco_gt(conf.COCO.cocoApi, imdb_info_required{i}.im_id); 25 | else 26 | % for imagenet, imagenet_3k 27 | if isempty(imdb_info_required{i}.roidb_merge.boxes), empty_gt = true; end 28 | end 29 | 30 | if ~empty_gt 31 | if ~isempty(conf.PASS.recursive_rpn_box) 32 | curr_recursive_rpn_box = conf.PASS.recursive_rpn_box{i}; 33 | else 34 | curr_recursive_rpn_box = []; 35 | end 36 | [net_inputs{i}, ~, ~, all_rois_blob{i}, image_size{i}] = ... 37 | proposal_get_minibatch(conf, imdb_info_required{i}, curr_recursive_rpn_box); 38 | else 39 | net_inputs{i} = []; 40 | end 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /experiment/boost_main.m: -------------------------------------------------------------------------------- 1 | en = fitensemble(); 2 | -------------------------------------------------------------------------------- /experiment/deploy/E02_imagenet_3k_test.m: -------------------------------------------------------------------------------- 1 | % Object proposals using deep models 2 | % Author: Hongyang Li 3 | % Affiliation: Chinese Univ. of Hong Kong 4 | % Date: Jan 17, 2017 5 | % Email: yangli@ee.cuhk.edu.hk 6 | % Origin(model_id): D17b_roi_coco 7 | 8 | close all; 9 | clear; 10 | caffe.reset_all; 11 | 12 | %% configure: dataset, model, params 13 | % || essential setup in each experiment, for other parameters, see 'init_rpn.m' 14 | % dataset options: coco, imagenet, pascal 15 | conf.dataset = 'imagenet_3k'; 16 | % will create 'train' and 'test' sub-folders 17 | conf.model_id = 'E02_imagenet_3k'; 18 | conf.debug = false; 19 | conf.draw_boxes = false; 20 | % make sure total_chunk is less or equal than the number of GPUs 21 | conf.test.total_chunk = 4; 22 | conf.test.curr_chunk = 1; 23 | conf.gpu_id = conf.test.curr_chunk - 1; 24 | 25 | % || default setting 26 | [conf, dataset] = init_rpn('test', conf); 27 | % located in the 'model/zoom' folder 28 | model.solver_file = 'bn/set_8_balance_3cls_coco/solver_deploy'; 29 | model.image_mean = conf.image_mean; 30 | % will find the model under 'output/[conf.model_id]/train/[model.iter_name].caffemodel' 31 | model.iter_name = 'iter_50000'; 32 | % || optional parameters 33 | 34 | 35 | %% train zoom network 36 | conf = orderfields(conf); 37 | cprintf('blue', '\nBegin - Phase 1 Zoom Network TEST ...\n'); 38 | model.recall = zoom_test(... 39 | 'trained_model_folder', conf.data.train_key, ... 40 | 'iter_name', conf.test.which_iter, ... 41 | 'model', model, ... 42 | 'imdb', dataset.imdb_test, ... 43 | 'roidb', dataset.roidb_test, ... 44 | 'test_res_folder_suffix', conf.test.res_folder_suffix, ... 45 | 'debug', conf.debug, ... 46 | 'conf', conf); 47 | cprintf('blue', '\nDone - Phase 1 Zoom Network TEST ...\n'); 48 | exit; 49 | -------------------------------------------------------------------------------- /experiment/deploy/E02_imagenet_3k_train.m: -------------------------------------------------------------------------------- 1 | % Object proposals using deep models 2 | % Author: Hongyang Li 3 | % Affiliation: Chinese Univ. of Hong Kong 4 | % Date: Jan 17, 2017 5 | % Email: yangli@ee.cuhk.edu.hk 6 | % Origin(model_id): D17b_roi_coco 7 | 8 | close all; 9 | clear; 10 | caffe.reset_all; 11 | 12 | %% configure: dataset, model, params 13 | % || essential setup in each experiment, for other parameters, see 'init_rpn.m' 14 | % dataset options: coco, imagenet, pascal 15 | conf.dataset = 'imagenet_3k'; 16 | % conf.dataset = 'coco'; 17 | % will create 'train' and 'test' sub-folders 18 | % conf.model_id = 'E02_imagenet_3k'; 19 | conf.model_id = 'E02_imagenet_3k_resume'; 20 | conf.debug = false; 21 | conf.draw_boxes = false; 22 | % || default setting 23 | [conf, dataset] = init_rpn('train', conf); 24 | % located in the 'model/zoom' folder 25 | % model.solver_file = 'bn/set_8_balance_3cls_coco/solver_train'; 26 | model.solver_file = 'bn/set_8_balance_3cls_coco/solver_train_resume'; 27 | model.init_net_file = conf.init_net_file; 28 | 29 | % || optional parameters 30 | conf.gpu_id = 0:3; 31 | conf.rpn_max_size = 1000; 32 | conf.save_interval = 5000; 33 | conf.loss_bbox_weight = [10 10 5]; 34 | conf.init_net_file = fullfile(pwd, ... 35 | 'output', 'E02_imagenet_3k_train', 'train', 'iter_50000.caffemodel'); 36 | conf.rng_seed = 2; % in resume we generate a different series of samples 37 | 38 | %% train zoom network 39 | conf = orderfields(conf); 40 | cprintf('blue', '\nBegin - Phase 1 Zoom Network TRAINING ...\n'); 41 | model.trained_caffemodel = zoom_train(... 42 | 'conf', conf, ... 43 | 'imdb_train', dataset.imdb_train, ... 44 | 'roidb_train', dataset.roidb_train, ... 45 | 'solver', model.solver_file , ... 46 | 'init_net_file', model.init_net_file); 47 | cprintf('blue', '\nDone - Phase 1 Zoom Network TRAINING ...\n'); 48 | exit; 49 | -------------------------------------------------------------------------------- /experiment/deploy/F01_baseline_voc.m: -------------------------------------------------------------------------------- 1 | % Object proposals using deep models 2 | % Author: Hongyang Li 3 | % Affiliation: Chinese Univ. of Hong Kong 4 | % Date: Jan 17, 2017 5 | % Email: yangli@ee.cuhk.edu.hk 6 | % Origin(model_id): D17b_roi_coco 7 | 8 | 9 | % adjust the model mannually during training 10 | close all; 11 | clear; 12 | caffe.reset_all; 13 | 14 | %% configure: dataset, model, params 15 | % || essential setup in each experiment, for other parameters, see 'init_rpn.m' 16 | % dataset options: coco, imagenet, pascal 17 | conf.dataset = 'voc'; 18 | % will create 'train' and 'test' sub-folders 19 | conf.model_id = mfilename(); 20 | manual_train_suffix = '_drop_lr2'; 21 | trained_from_suffix = '_drop_lr1'; 22 | conf.model_id = [mfilename() manual_train_suffix]; 23 | conf.debug = false; 24 | conf.draw_boxes = false; 25 | % || default setting 26 | [conf, dataset] = default_config('train', conf); 27 | 28 | % || optional parameters 29 | conf.gpu_id = 0; %3; 30 | conf.rpn_max_size = 1000; 31 | conf.save_interval = 5000; 32 | conf.add_gray_cls = false; 33 | conf.multi_depth = false; 34 | conf.check_certain_scale = false; 35 | conf.fg_thresh = 0.51; 36 | conf.batch_size = 300; 37 | % anchor 38 | conf.rpn_feat_stride = 32; 39 | conf.base_size = 8; 40 | conf.liuyu.range = [72 128]; 41 | conf.anchor_scale = [8 16]; 42 | conf.ratios = [0.5, 1, 2]; 43 | conf.loss_cls_weight = 1; 44 | conf.loss_bbox_weight = 1; 45 | 46 | conf= init_zoom_net(conf); 47 | % located in the 'model/zoom' folder 48 | model.solver_file = 'bn/baseline/solver_train'; 49 | % model.init_net_file = conf.init_net_file; 50 | model.init_net_file = fullfile(pwd, 'output', ... 51 | [mfilename() trained_from_suffix], 'train', ... 52 | 'iter_50000.caffemodel'); 53 | 54 | %% train zoom network 55 | conf = orderfields(conf); 56 | cprintf('blue', '\nBegin - Phase 1 Zoom Network TRAINING ...\n'); 57 | zoom_train(... 58 | 'conf', conf, ... 59 | 'solver', model.solver_file , ... 60 | 'init_net_file', model.init_net_file); 61 | cprintf('blue', '\nDone - Phase 1 Zoom Network TRAINING ...\n'); 62 | exit; 63 | -------------------------------------------------------------------------------- /experiment/deploy/F03_voc_hg.m: -------------------------------------------------------------------------------- 1 | % Object proposals using deep models 2 | % Author: Hongyang Li 3 | % Affiliation: Chinese Univ. of Hong Kong 4 | % Date: Jan 17, 2017 5 | % Email: yangli@ee.cuhk.edu.hk 6 | % Origin(model_id): D17b_roi_coco 7 | 8 | close all; 9 | clear; 10 | caffe.reset_all; 11 | 12 | %% first things first: init 13 | % will create 'train' and 'test' sub-folders 14 | conf.model_id = mfilename(); 15 | conf.dataset = 'voc'; 16 | conf.debug = true; %false; 17 | conf.draw_boxes = false; 18 | conf = default_config('train', conf); 19 | 20 | % || optional parameters 21 | conf.gpu_id = 0; 22 | conf.rpn_max_size = 800; 23 | conf.save_interval = 5000; 24 | conf.add_gray_cls = true; %false; 25 | conf.multi_depth = true; %false; 26 | conf.check_certain_scale = true; %false; % hg structure 27 | conf.fg_thresh = 0.51; 28 | conf.batch_size = 300; 29 | % anchor 30 | conf.rpn_feat_stride = [8, 16, 32]; 31 | conf.base_size = 8; 32 | conf.liuyu.range = [72 128]; 33 | conf.anchor_scale = 2.^(0:5); % default 34 | conf.ratios = [0.25, 0.5, 1, 2, 3]; 35 | conf.loss_cls_weight = [1 1 1]; 36 | conf.loss_bbox_weight = [1 1 1]; 37 | % init 38 | conf.init_mirror_layer = false; 39 | 40 | conf= init_zoom_net(conf); 41 | % located in the 'model/zoom' folder 42 | model.solver_file = 'bn/set_8_balance_3cls_voc/solver_train_auto'; 43 | model.init_net_file = conf.init_net_file; 44 | model.solverstate = ''; %'iter_5'; 45 | 46 | %% train zoom network 47 | conf = orderfields(conf); 48 | cprintf('blue', '\nBegin - Phase 1 Zoom Network TRAINING ...\n'); 49 | zoom_train(... 50 | 'conf', conf, ... 51 | 'solverstate', model.solverstate, ... 52 | 'solver', model.solver_file , ... 53 | 'init_net_file', model.init_net_file); 54 | cprintf('blue', '\nDone - Phase 1 Zoom Network TRAINING ...\n'); 55 | exit; 56 | -------------------------------------------------------------------------------- /experiment/evaluate.m: -------------------------------------------------------------------------------- 1 | function evaluate() 2 | % plot average recall and precision 3 | 4 | close all; clear; 5 | eval.top_k = [10, 100, 300, 500, 700, 1000, 1500, 2000]; 6 | eval.ov = 0.5 : 0.05 : 0.95; 7 | eval.eval_size = true; 8 | eval.scale_size = [32, 96]; 9 | eval.scale_name = {'small', 'medium', 'large'}; 10 | 11 | %% 12 | dataset = 'voc'; 13 | 14 | folder_name{1} = 'F01_baseline_test'; 15 | box_source{1} = fullfile(pwd, 'output', 'F01_baseline_voc', ... 16 | 'test', 'iter_50000', 'nms_0.60'); 17 | if strcmp(dataset, 'voc') 18 | imdb_info = get_voc_info('test'); 19 | end 20 | 21 | %% 22 | for method_iter = 1:length(folder_name) % each method 23 | 24 | save_dir = fullfile('output/evaluate', dataset, folder_name{method_iter}); 25 | mkdir_if_missing(save_dir); 26 | % cell [im_num x 2], first is boxes, second is image name 27 | boxes = find_and_merge_box(box_source{method_iter}); 28 | 29 | [recall, recall_size] = compute_rec_pre(imdb_info, boxes, eval); 30 | save(fullfile(save_dir, 'rec_pre.mat'), 'recall', 'recall_size'); 31 | % TODO: draw figure 32 | end 33 | end 34 | 35 | function merge_boxes = find_and_merge_box(box_folder, box_name) 36 | 37 | if nargin < 2, box_name = 'aboxes'; end 38 | 39 | box_file = dir([box_folder '/*.mat']); 40 | box_file = extractfield(box_file, 'name')'; 41 | ind = cellfun(@(x) strcmp(x(1:5), 'merge'), box_file); 42 | box_file = box_file(~ind); 43 | 44 | if exist(fullfile(box_folder, sprintf('merge_%d.mat', length(box_file))), 'file') 45 | ld = load(fullfile(box_folder, sprintf('merge_%d.mat', length(box_file)))); 46 | merge_boxes = ld.merge_boxes; 47 | else 48 | merge_boxes = cell(length(box_file), 2); 49 | for i = 1:length(box_file) 50 | ld = load(fullfile(box_folder, box_file{i})); 51 | merge_boxes{i, 1} = ld.(box_name); 52 | merge_boxes{i, 2} = box_file{i}(1:end-4); 53 | end 54 | save(fullfile(box_folder, sprintf('merge_%d.mat', length(box_file))), 'merge_boxes'); 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /experiment/merge_split_json_file.m: -------------------------------------------------------------------------------- 1 | clear; 2 | 3 | % root = '../externalBox/data_I_want_coco/deepmask-coco-val-bbox/deepMask'; 4 | root = '../externalBox/data_I_want_coco/sharpmask-coco-val-bbox/sharpMask2'; 5 | save_path = [root '/../sharpMask_final']; 6 | file_dir = dir([root '/*.json']); 7 | 8 | addpath(genpath('./data/datasets/coco/coco_eval')); 9 | coco = CocoApi('./data/datasets/coco/annotations/instances_minival2014.json'); 10 | test_im_list = extractfield(coco.data.images, 'file_name')'; 11 | test_im_list = cellfun(@(x) x(1:end-4), test_im_list, 'uniformoutput', false); 12 | test_im_id = extractfield(coco.data.images, 'id')'; 13 | 14 | content = cell(length(test_im_list), 1); 15 | %% 16 | log_down_useful_info = cell(length(file_dir), 1); 17 | parfor i = 1:length(file_dir) 18 | 19 | curr_file = loadjson([root '/' file_dir(i).name], ... 20 | 'SimplifyCell', 1, 'FastArrayParser', 1, 'showprogress', 0)'; 21 | 22 | im_id_list = extractfield(curr_file, 'image_id')'; 23 | im_id_pool = unique(im_id_list); 24 | 25 | cnt = 0; 26 | curr_file_useful_info = cell(1); 27 | for j = 1:length(im_id_pool) 28 | 29 | if sum(im_id_pool(j)==test_im_id) > 0 30 | cnt = cnt+1; 31 | curr_file_useful_info{cnt,1} = curr_file(im_id_list == im_id_pool(j)); 32 | end 33 | end 34 | log_down_useful_info{i} = curr_file_useful_info; 35 | end 36 | 37 | %% 38 | all_useful = cat(1, log_down_useful_info{:}); 39 | for i = 1:length(all_useful) 40 | 41 | curr_struct = all_useful{i}; 42 | curr_im_id = curr_struct(1).image_id; 43 | boxes = reshape(extractfield(curr_struct, 'bbox'), 4, [])'; 44 | boxes = [boxes(:, 1) boxes(:, 2) ... 45 | (boxes(:, 1)+boxes(:, 3)) (boxes(:, 2)+boxes(:, 4))]; 46 | scores = extractfield(curr_struct, 'score')'; 47 | 48 | content{curr_im_id==test_im_id} = cat(1, ... 49 | content{curr_im_id==test_im_id}, [boxes, scores]); 50 | end 51 | 52 | %% save 53 | mkdir_if_missing(save_path); 54 | for i = 1:length(content) 55 | boxes = content{i}; 56 | if isempty(boxes) 57 | error('%d is empty\n', i); 58 | end 59 | boxes = boxes(sort(boxes(:, end), 'descend'), :); 60 | save([save_path '/' test_im_list{i} '.mat'], 'boxes'); 61 | end -------------------------------------------------------------------------------- /experiment/merge_train_val_from_bj1_faster_rcnn.m: -------------------------------------------------------------------------------- 1 | % merge imagenet train/val of D16a 2 | 3 | which_set = 'val'; %'train'; % 'val'; 4 | 5 | ld = load('./data/imdb/train_val_list.mat'); 6 | if strcmp(which_set, 'train') 7 | 8 | image_ids = cellfun(@(x) x(21:end-5), ... 9 | ld.train_list, 'uniformoutput', false); 10 | save_name = 'solo_regress_train.mat'; 11 | 12 | elseif strcmp(which_set, 'val') 13 | 14 | image_ids = cellfun(@(x) x(21:end-5), ... 15 | ld.val_list, 'uniformoutput', false); 16 | save_name = 'solo_regress_val.mat'; 17 | end 18 | 19 | total_num = length(image_ids); 20 | box_result(total_num).name = ''; 21 | box_result(total_num).box = []; 22 | top_k = 1000; 23 | root = './output/rpn/D16a_roi_s31'; 24 | 25 | non_exist_list = []; 26 | cnt = 0; 27 | val_search_space{1} = 'ilsvrc14_val2'; 28 | val_search_space{2} = 'train_liuyu_addition'; 29 | val_search_space{3} = 'val_liuyu_addition'; 30 | 31 | str_template = @(x) sprintf('%s/iter_160000_noDense_test/nms_0.50/split', x); 32 | 33 | %% 34 | % first things first, check if all files exist! 35 | for i = 1:total_num 36 | 37 | curr_name = image_ids{i}; 38 | 39 | if curr_name(1) == 't', curr_name = [curr_name(7:end) '.mat']; end 40 | if curr_name(1) == 'v', curr_name = [curr_name(5:end) '.mat']; end 41 | 42 | if strcmp(curr_name(1:16), 'ILSVRC2013_train') 43 | 44 | file_name = fullfile(root, str_template('train_liuyu_addition'), curr_name); 45 | if ~exist(file_name, 'file'), cnt = cnt+1; non_exist_list{cnt} = curr_name; end 46 | 47 | elseif strcmp(curr_name(1:16), 'ILSVRC2014_train') 48 | 49 | file_name = fullfile(root, str_template('ilsvrc14_train14'), curr_name); 50 | if ~exist(file_name, 'file'), cnt = cnt+1; non_exist_list{cnt} = curr_name; end 51 | 52 | % could be train/val 53 | elseif strcmp(curr_name(1:14), 'ILSVRC2012_val') || strcmp(curr_name(1:14), 'ILSVRC2013_val') 54 | 55 | find_it = false; 56 | for kk = 1:length(val_search_space) 57 | file_name = fullfile(root, str_template(val_search_space{kk}), curr_name); 58 | if exist(file_name, 'file'), find_it = true; break; end 59 | end 60 | if ~find_it, cnt = cnt+1; non_exist_list{cnt} = curr_name; end 61 | else 62 | error('unknown name format'); 63 | end 64 | end 65 | 66 | if ~isempty(non_exist_list) 67 | %disp(non_exist_list); 68 | fprintf('find %d non-existant files!\n', length(non_exist_list)); 69 | fprintf('will ignore them and merge now...\n'); 70 | %keyboard; 71 | else 72 | disp('all files exist! begin to merge them!'); 73 | end 74 | 75 | %% 76 | for i = 1:total_num 77 | 78 | origin_name = image_ids{i}; 79 | curr_name = origin_name; 80 | 81 | if curr_name(1) == 't', curr_name = [curr_name(7:end) '.mat']; end 82 | if curr_name(1) == 'v', curr_name = [curr_name(5:end) '.mat']; end 83 | 84 | if strcmp(curr_name(1:16), 'ILSVRC2013_train') 85 | 86 | file_name = fullfile(root, str_template('train_liuyu_addition'), curr_name); 87 | 88 | elseif strcmp(curr_name(1:16), 'ILSVRC2014_train') 89 | 90 | file_name = fullfile(root, str_template('ilsvrc14_train14'), curr_name); 91 | 92 | % could be train/val 93 | elseif strcmp(curr_name(1:14), 'ILSVRC2012_val') || strcmp(curr_name(1:14), 'ILSVRC2013_val') 94 | 95 | for kk = 1:length(val_search_space) 96 | file_name = fullfile(root, str_template(val_search_space{kk}), curr_name); 97 | if exist(file_name, 'file'), break; end 98 | end 99 | end 100 | 101 | try 102 | ld = load(file_name); 103 | try 104 | boxes_temp = ld.raw_boxes_roi; 105 | out = process_regression_result([], boxes_temp, 'naive_2_nms7'); 106 | boxes = out{1}; 107 | catch 108 | boxes = ld.aboxes; 109 | end 110 | catch 111 | boxes = [1 1 10 10]; 112 | end 113 | box_result(i).name = [origin_name '.mat']; 114 | box_result(i).box = single(boxes(1:min(top_k, size(boxes, 1)), 1:4)); 115 | end 116 | 117 | save(save_name, 'box_result', '-v7.3'); 118 | exit(); 119 | %========================================================== 120 | % %mat_file = dir('./train_*.mat'); 121 | % mat_file = dir('./val_*.mat'); 122 | % 123 | % %total_num = 175129; 124 | % total_num = 9917; 125 | % box_result(total_num).name = ''; 126 | % box_result(total_num).box = []; 127 | % check_ = zeros(total_num, 1); 128 | % 129 | % for i = 1:length(mat_file) 130 | % 131 | % ld = load(['./' mat_file(i).name]); 132 | % curr_box = ld.box_result; 133 | % temp = sscanf(mat_file(i).name, 'val_ck%d_absInd_%d_%d_total%d.mat'); 134 | % %temp = sscanf(mat_file(i).name, 'train_ck%d_absInd_%d_%d_total%d.mat'); 135 | % start_id = temp(2); 136 | % end_id = temp(3); 137 | % box_result(start_id:end_id) = curr_box; 138 | % check_(start_id:end_id) = 1; 139 | % end 140 | % 141 | % if ~all(check_) 142 | % warning('some entries are empty!'); 143 | % end 144 | % 145 | % %save('./ss_train.mat', 'box_result', '-v7.3'); 146 | % save('./ss_val.mat', 'box_result', '-v7.3'); 147 | -------------------------------------------------------------------------------- /experiment/test/F01_baseline_voc_test.m: -------------------------------------------------------------------------------- 1 | % Object proposals using deep models 2 | % Author: Hongyang Li 3 | % Affiliation: Chinese Univ. of Hong Kong 4 | % Date: Jan 17, 2017 5 | % Email: yangli@ee.cuhk.edu.hk 6 | % Origin(model_id): D17b_roi_coco 7 | 8 | 9 | % adjust the model mannually during training 10 | close all; 11 | clear; 12 | caffe.reset_all; 13 | 14 | %% configure: dataset, model, params 15 | conf.dataset = 'voc'; 16 | % will create 'train' and 'test' sub-folders 17 | conf.model_id = mfilename(); 18 | conf.debug = false; 19 | conf.draw_boxes = false; 20 | conf = default_config('test', conf); 21 | 22 | conf.total_chunk = 2; 23 | conf.curr_chunk = 2; 24 | % || optional parameters 25 | conf.gpu_id = 1; 26 | conf.add_gray_cls = false; 27 | conf.multi_depth = false; 28 | conf.check_certain_scale = false; 29 | conf.fg_thresh = 0.51; 30 | % anchor 31 | conf.rpn_feat_stride = 32; 32 | conf.base_size = 8; 33 | conf.liuyu.range = [72 128]; 34 | conf.anchor_scale = [8 16]; 35 | conf.ratios = [0.5, 1, 2]; 36 | 37 | conf= init_zoom_net(conf); 38 | % located in the 'model/zoom' folder 39 | root = pwd; 40 | model.solver_file = 'bn/baseline/solver_deploy'; 41 | model.test_caffemodel = fullfile(root, 'output', ... 42 | 'F01_baseline_voc_drop_lr2', 'train', 'iter_50000.caffemodel'); 43 | 44 | %% test zoom network 45 | conf = orderfields(conf); 46 | cprintf('blue', '\nBegin - Phase 1 Zoom Network TESTING ...\n'); 47 | zoom_test(... 48 | 'conf', conf, ... 49 | 'solver', model.solver_file , ... 50 | 'test_model', model.test_caffemodel); 51 | cprintf('blue', '\nDone - Phase 1 Zoom Network TESTING ...\n'); 52 | exit; 53 | -------------------------------------------------------------------------------- /experiment/visualize_test.m: -------------------------------------------------------------------------------- 1 | clear; 2 | dataset = 'imagenet'; 3 | top_k = 300; 4 | ov = 0.5; 5 | 6 | coco_gt = []; gt_path = []; cat_book = []; 7 | if strcmp(dataset, 'imagenet') 8 | 9 | im_path = './data/datasets/ilsvrc14_det/ILSVRC2013_DET_val'; 10 | gt_path = './data/datasets/ilsvrc14_det/ILSVRC2013_DET_bbox_val'; 11 | addpath('./data/datasets/ilsvrc14_det/ILSVRC2014_devkit/evaluation'); 12 | addpath('./code/utils'); 13 | % ld = load('./data/datasets/ilsvrc14_det/ILSVRC2014_devkit/data/meta_det.mat'); 14 | % gt_info = ld.synsets_det; clear ld; 15 | use_coco = false; 16 | 17 | elseif strcmp(dataset, 'coco') 18 | 19 | addpath(genpath('./data/datasets/coco/coco_eval')); 20 | im_path = './data/datasets/coco/val2014'; 21 | coco_gt = CocoApi('./data/datasets/coco/annotations/instances_minival2014.json'); 22 | use_coco = true; 23 | cat_book = coco_gt.data.categories; 24 | end 25 | 26 | %% 27 | % test_split_folder = ... 28 | % 'D02_s31_noCrop_multiLoss/ilsvrc14_val2/final_multiLoss_multiScale_new/nms_0.50/split'; 29 | % test_split_folder = ... 30 | % 'D06_s31_hg_threeLoss/ilsvrc14_val2/iter_40000_multiLoss_multiScale/nms_0.50/split'; 31 | % test_split_folder = ... 32 | % 'D06_s170_hg_threeLoss/ilsvrc14_val2/iter_132500_multiLoss_multiScale/nms_0.50/split'; 33 | % test_split_folder = ... 34 | % '/home/hongyang/Desktop/test_res_sep_29/92.x_res_D02/nms_0.50/split'; 35 | % test_split_folder = ... 36 | % '/home/hongyang/Desktop/test_res_sep_29_30/D06_s170/nms_0.50/split'; 37 | % test_split_folder = ... 38 | % 'D12_s170_dense/ilsvrc14_val2/final_dense_test/nms_0.50/split'; 39 | % test_split_folder = ... 40 | % '/home/hongyang/Desktop/test_res_sep_29_30/D10_s31/nms_0.50/split'; 41 | % test_split_folder = ... 42 | % 'D14b_s170_2hg/ilsvrc14_val2/iter_157500_dense_test_local_debug_4loss/nms_0.50/split'; 43 | % % coco results 44 | % test_split_folder = ... 45 | % 'D15a_coco/coco_val/iter_70000_dense_test/nms_0.50/split'; 46 | % % roi-followup results 47 | % test_split_folder = ... 48 | % 'D16a_roi/ilsvrc14_val2/iter_160000_noDense_test/nms_0.50/split'; 49 | 50 | % to show in the paper 51 | % test_split_folder = '~/Desktop/analyze_to_paper/run_simple_forward/d16a'; 52 | test_split_folder = '~/Desktop/analyze_to_paper/run_simple_forward/d15a'; 53 | 54 | % if filled in, we will output those results in the test_folder based on 55 | % the designated list from wish list. 56 | which_list_folder = ''; 57 | %which_list_folder = 'D06_s170_hg_threeLoss/ilsvrc14_val2/iter_132500_multiLoss_multiScale/nms_0.50/split'; 58 | 59 | roi_followup = false; %true; 60 | % mode = 'free_browse'; 61 | mode = 'full_examine'; % will save the results 62 | 63 | %% 64 | if strcmp(mode, 'full_examine') 65 | success_folder = fullfile(fileparts(test_split_folder), 'success'); 66 | mkdir_if_missing(success_folder); 67 | fail_folder = fullfile(fileparts(test_split_folder), 'fail'); 68 | mkdir_if_missing(fail_folder); 69 | end 70 | 71 | %% detemine load_box_folder and check_dir 72 | mat_dir = dir(['./output/rpn/' test_split_folder '/*.mat']); 73 | if size(mat_dir, 1) == 0 74 | mat_dir = dir([test_split_folder '/*.mat']); 75 | load_box_folder = test_split_folder; 76 | else 77 | load_box_folder = ['./output/rpn/' test_split_folder]; 78 | end 79 | if size(mat_dir, 1) == 0 80 | error('fuck'); 81 | end 82 | 83 | if ~isempty(which_list_folder) 84 | wish_list_dir = dir(['./output/rpn/' which_list_folder '/*.mat']); 85 | check_dir = wish_list_dir; 86 | else 87 | check_dir = mat_dir; 88 | end 89 | 90 | %% 91 | catch_total = 0; 92 | inst_total = 0; 93 | for hehe = 1:length(check_dir) 94 | 95 | close all; 96 | if isempty(which_list_folder) 97 | if strcmp(mode, 'free_browse') 98 | curr_im_name = mat_dir(randi(length(mat_dir), 1)).name(1:end-4); 99 | else 100 | curr_im_name = mat_dir(hehe).name(1:end-4); 101 | end 102 | else 103 | if strcmp(mode, 'free_browse') 104 | curr_im_name = wish_list_dir(randi(length(wish_list_dir), 1)).name(1:end-4); 105 | else 106 | curr_im_name = wish_list_dir(hehe).name(1:end-4); 107 | end 108 | end 109 | 110 | if strcmp(mode, 'free_browse'), 111 | f = figure('visible', 'on'); 112 | else 113 | % f = figure('visible', 'off', 'units', 'normalized', 'position', [0 0 .2 .2]); 114 | % f = figure('visible', 'off'); 115 | f = figure('visible', 'on'); 116 | end 117 | 118 | ld = load([load_box_folder '/' curr_im_name '.mat']); 119 | if roi_followup 120 | proposals_ori = ld; 121 | else 122 | proposals_ori = ld.aboxes; 123 | % boxes_temp = ld.raw_boxes_roi; 124 | % out = process_regression_result([], boxes_temp, 'naive_2_nms7'); 125 | % proposals_ori = out{1}; 126 | end 127 | [catch_total, inst_total, gt_obj_fail] = visual_anchor_test( ... 128 | im_path, curr_im_name, proposals_ori, use_coco, coco_gt, gt_path, ... 129 | catch_total, inst_total, roi_followup, cat_book); 130 | 131 | if strcmp(mode, 'full_examine') 132 | if isempty(gt_obj_fail) 133 | print(fullfile(success_folder, [curr_im_name '.pdf']), '-dpdf', '-r0'); 134 | else 135 | print(fullfile(fail_folder, [curr_im_name '.png']), '-dpng', '-r0'); 136 | end 137 | end 138 | if strcmp(mode, 'free_browse'), keyboard; end 139 | end 140 | 141 | if strcmp(mode, 'full_examine') 142 | fprintf('\naverage recall: %.3f\n', catch_total/inst_total); 143 | end -------------------------------------------------------------------------------- /model/pretrain/bn_vgg19/solver.txt: -------------------------------------------------------------------------------- 1 | net: "models/bn_inception/train_val.txt" 2 | test_iter: 125 3 | test_interval: 2000 4 | test_initialization: true 5 | display: 20 6 | average_loss: 20 7 | base_lr: 0.35 8 | lr_policy: "exp10" 9 | stepsize: 220000 10 | gamma: 0.1 11 | max_iter: 900000 12 | momentum: 0.9 13 | weight_decay: 0.0001 14 | snapshot: 10000 15 | snapshot_prefix: "/data1/imagenet/snapshot/bn_inception" 16 | solver_mode: GPU 17 | 18 | #device_id: [0,1,2,4,5,6,7,8,9,10,11,12,13,14] 19 | #iter_size: 4 20 | richness: 20 21 | -------------------------------------------------------------------------------- /model/zoom/bn/base/solver_deploy_check.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/zoom/bn/base/deploy_check.prototxt" 2 | 3 | display: 20 4 | snapshot: 0 5 | -------------------------------------------------------------------------------- /model/zoom/bn/baseline/solver_deploy.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/zoom/bn/baseline/deploy.prototxt" 2 | 3 | display: 20 4 | snapshot: 0 5 | -------------------------------------------------------------------------------- /model/zoom/bn/baseline/solver_train.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/zoom/bn/baseline/train.prototxt" 2 | 3 | display: 20 4 | average_loss: 100 5 | 6 | #clip_gradients: 10 7 | lr_policy: "multistep" # 'step' crushes 8 | #base_lr: 0.0001 # 0-6w 9 | #base_lr: 0.00005 # pick 6w 10 | base_lr: 0.000025 # pick 5w from above 11 | # almost useless if trained manually 12 | gamma: 0.5 13 | stepvalue: 200000 14 | stepvalue: 300000 15 | max_iter: 400000 16 | 17 | momentum: 0.9 18 | weight_decay: 0.0005 19 | #debug_info: true 20 | snapshot: 0 21 | -------------------------------------------------------------------------------- /model/zoom/bn/baseline/solver_train_auto.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/zoom/bn/baseline/train.prototxt" 2 | 3 | display: 20 4 | average_loss: 100 5 | 6 | #clip_gradients: 10 7 | lr_policy: "multistep" # 'step' crushes 8 | base_lr: 0.0001 9 | gamma: 0.5 10 | stepvalue: 50000 11 | stepvalue: 80000 12 | max_iter: 100000 13 | 14 | momentum: 0.9 15 | weight_decay: 0.0005 16 | #debug_info: true 17 | snapshot: 0 18 | -------------------------------------------------------------------------------- /model/zoom/bn/baseline_single/solver_train_auto.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/zoom/bn/baseline_single/train.prototxt" 2 | 3 | display: 20 4 | average_loss: 100 5 | 6 | #clip_gradients: 10 7 | lr_policy: "multistep" # 'step' crushes 8 | base_lr: 0.0001 9 | gamma: 0.5 10 | stepvalue: 50000 11 | stepvalue: 80000 12 | max_iter: 100000 13 | 14 | momentum: 0.9 15 | weight_decay: 0.0005 16 | #debug_info: true 17 | snapshot: 0 18 | -------------------------------------------------------------------------------- /model/zoom/bn/set_8_balance_3cls_voc/10anchors_3level: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hli2020/zoom_network/a59f1c6b14cdbcf6124692bde4315ee8ab8bc961/model/zoom/bn/set_8_balance_3cls_voc/10anchors_3level -------------------------------------------------------------------------------- /model/zoom/bn/set_8_balance_3cls_voc/solver_deploy.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/rpn/bn/set_8_balance_3cls/deploy.prototxt" 2 | 3 | display: 20 4 | snapshot: 0 5 | -------------------------------------------------------------------------------- /model/zoom/bn/set_8_balance_3cls_voc/solver_train_auto.prototxt: -------------------------------------------------------------------------------- 1 | train_net: "./model/zoom/bn/set_8_balance_3cls_voc/train.prototxt" 2 | 3 | display: 20 4 | average_loss: 100 5 | 6 | base_lr: 0.0001 7 | lr_policy: "multistep" 8 | gamma: 0.5 9 | max_iter: 100000 10 | stepvalue: 50000 11 | stepvalue: 80000 12 | 13 | momentum: 0.9 14 | weight_decay: 0.0005 15 | 16 | snapshot: 0 17 | -------------------------------------------------------------------------------- /startup.m: -------------------------------------------------------------------------------- 1 | function startup() 2 | %STARTUP file for the project object proposals using deep models 3 | % Author: Hongyang Li 4 | % Affiliation: Chinese Univ. of Hong Kong 5 | % Date: August, 2016 6 | % Email: yangli@ee.cuhk.edu.hk 7 | % Refactored from: Shaoqing Ren, Yu Liu. 8 | curdir = fileparts(mfilename('fullpath')); 9 | addpath(genpath(fullfile(curdir, 'code'))); 10 | addpath(genpath(fullfile(curdir, 'experiment'))); 11 | 12 | mkdir_if_missing(fullfile(curdir, 'code', 'external')); 13 | mkdir_if_missing(fullfile(curdir, 'data', 'datasets')); 14 | 15 | mkdir_if_missing(fullfile(curdir, 'output', 'dot_out_file')); 16 | mkdir_if_missing(fullfile(curdir, 'experiment', 'deploy')); 17 | 18 | if ~exist('nms_mex', 'file') 19 | try 20 | fprintf('Compiling nms_mex\n'); 21 | 22 | mex -outdir code/nms ... 23 | -largeArrayDims ... 24 | code/nms/nms_mex.cpp ... 25 | -output nms_mex; 26 | catch exception 27 | fprintf('Error message %s\n', getReport(exception)); 28 | end 29 | end 30 | if ~exist('nms_gpu_mex', 'file') 31 | try 32 | fprintf('Compiling nms_gpu_mex\n'); 33 | addpath(fullfile(pwd, 'code', 'nms')); 34 | nvmex('code/nms/nms_gpu_mex.cu', 'code/nms'); 35 | delete('nms_gpu_mex.o'); 36 | catch exception 37 | fprintf('Error message %s\n', getReport(exception)); 38 | end 39 | end 40 | 41 | caffe_path = fullfile(curdir, 'code', 'external', 'caffe', 'matlab'); 42 | if exist(caffe_path, 'dir') == 0 43 | error('matcaffe is missing from external/caffe/matlab; See README.md'); 44 | end 45 | addpath(genpath(caffe_path)); 46 | caffe.reset_all(); 47 | caffe.set_mode_gpu(); 48 | clc; 49 | 50 | fprintf('caffe version: (%s), cvpr17 startup done!\n', caffe.version); 51 | 52 | % TODO: some compilation code here (nms, external box extraction, etc) 53 | 54 | --------------------------------------------------------------------------------