├── .gitignore ├── LICENSE ├── README.md ├── caffe_models ├── deploy.prototxt ├── fetch_model.sh └── imagenet_mean.npy ├── data └── detection_results │ ├── bbox_mat_filelist.txt │ └── rcnn_bbox_reg_pruned │ ├── aeroplane_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── bicycle_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── boat_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── bottle_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── bus_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── car_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── chair_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── diningtable_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── motorbike_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── sofa_pruned_boxes_voc_2012_val_bbox_reg.mat │ ├── train_pruned_boxes_voc_2012_val_bbox_reg.mat │ └── tvmonitor_pruned_boxes_voc_2012_val_bbox_reg.mat ├── datasets ├── get_pascal3d.sh ├── get_shapenet.sh └── get_sun2012pascalformat.sh ├── demo_render ├── .gitignore ├── README.md ├── ref_output │ ├── demo_images │ │ └── chair001 │ │ │ └── demo_img.png │ ├── demo_images_cropped │ │ └── chair001 │ │ │ └── demo_img.png │ └── demo_images_cropped_bkg_overlaid │ │ └── chair001 │ │ └── demo_img.jpg ├── render_class_view.py ├── run_demo.py ├── sample_bkg_images │ ├── filelist.txt │ ├── sun_admehzzcyrwqeagf.jpg │ ├── sun_amxqyvcaerikvqep.jpg │ ├── sun_amyacsvlywqnpmum.jpg │ ├── sun_amyamgmyudixgkeu.jpg │ ├── sun_amyaojhhpfkypfki.jpg │ ├── sun_amydkgquihpzayht.jpg │ ├── sun_amyhazfgaoclbgqs.jpg │ ├── sun_amymtdfzotooyham.jpg │ ├── sun_amynimbbnwqwejeg.jpg │ ├── sun_amyqdfkizefupfta.jpg │ ├── sun_amyqrurobufixjqr.jpg │ ├── sun_amyrciusrihbhswi.jpg │ ├── sun_amyuvmazodqhkrin.jpg │ ├── sun_amyvdsxkokkyxnft.jpg │ ├── sun_amywfwnlavdpohzn.jpg │ ├── sun_amywncoshhwkcvek.jpg │ ├── sun_amyxaanrovbdsxnk.jpg │ └── sun_aruegippndskcujm.jpg ├── sample_model │ ├── images │ │ ├── texture0.jpg │ │ └── texture1.jpg │ ├── model.mtl │ ├── model.obj │ └── model_source.txt ├── sample_model2 │ ├── model.mtl │ ├── model.obj │ └── model_source.txt ├── sample_truncations.txt └── sample_viewpoints.txt ├── demo_view ├── .gitignore ├── README.md ├── aeroplane_image.jpg ├── chair_image.jpg ├── ref_output │ ├── aeroplane_in_estimated_view.png │ └── est-view.txt ├── run_demo.py ├── run_demo_topk.py ├── run_visualize_3dview.py └── run_visualize_3dview_topk.py ├── global_variables.py.example ├── render_pipeline ├── README.md ├── blank.blend ├── crop_gray.m ├── crop_images.m ├── kde │ ├── get_voc12train_truncation_stats.m │ ├── get_voc12train_view_stats.m │ ├── matlab_kde_package │ │ ├── Contents.m │ │ ├── README.txt │ │ ├── adjustBW.dll │ │ ├── adjustBW.m │ │ ├── adjustPoints.dll │ │ ├── adjustPoints.m │ │ ├── adjustWeights.dll │ │ ├── adjustWeights.m │ │ ├── condition.m │ │ ├── covar.m │ │ ├── display.m │ │ ├── double_kde.m │ │ ├── encode.m │ │ ├── entropy.m │ │ ├── entropyGrad.m │ │ ├── evalAvgLogL.m │ │ ├── evalFGT.m │ │ ├── evalIFGT.m │ │ ├── evaluate.m │ │ ├── examples │ │ │ ├── demo_kde_1.m │ │ │ ├── demo_kde_2.m │ │ │ ├── demo_kde_3.m │ │ │ └── demo_regress.m │ │ ├── findBWCrit.m │ │ ├── getBW.m │ │ ├── getDim.m │ │ ├── getNeff.m │ │ ├── getNpts.m │ │ ├── getPoints.m │ │ ├── getType.m │ │ ├── getWeights.m │ │ ├── gram.m │ │ ├── hist.m │ │ ├── ise.m │ │ ├── joinTrees.m │ │ ├── kde.m │ │ ├── klGrad.m │ │ ├── kld.m │ │ ├── knn.dll │ │ ├── knn.m │ │ ├── ksize.m │ │ ├── license.gpl │ │ ├── llGrad.dll │ │ ├── llGrad.m │ │ ├── llHess.m │ │ ├── marginal.m │ │ ├── max.m │ │ ├── maxlogerr.m │ │ ├── mean.m │ │ ├── mex │ │ │ ├── BallTree.cpp │ │ │ ├── BallTreeDensity.cpp │ │ │ ├── DualTree.cpp │ │ │ ├── adjustBW.cpp │ │ │ ├── adjustPoints.cpp │ │ │ ├── adjustWeights.cpp │ │ │ ├── cpp │ │ │ │ ├── BallTree.h │ │ │ │ ├── BallTreeClass.cc │ │ │ │ ├── BallTreeDensity.h │ │ │ │ ├── BallTreeDensityClass.cc │ │ │ │ ├── README.txt │ │ │ │ └── kernels.h │ │ │ ├── entropyGradISE.cpp │ │ │ ├── entropyGradRS.cpp │ │ │ ├── iseEpsilon.cpp │ │ │ ├── klGradRS.cpp │ │ │ ├── knn.cpp │ │ │ ├── llGrad.cpp │ │ │ ├── makemex.m │ │ │ ├── maketmp.m │ │ │ ├── prodSampleEpsilon.cpp │ │ │ ├── prodSampleExact.cpp │ │ │ ├── prodSampleGibbs.cpp │ │ │ ├── prodSampleGibbs1.cpp │ │ │ ├── prodSampleGibbs2.cpp │ │ │ ├── prodSampleGibbsMS.cpp │ │ │ ├── prodSampleGibbsMS1.cpp │ │ │ ├── prodSampleGibbsMS2.cpp │ │ │ └── reduceSolve.cpp │ │ ├── miGrad.m │ │ ├── modes.m │ │ ├── plot.m │ │ ├── private │ │ │ ├── DualTree.m │ │ │ ├── entropyDist.m │ │ │ ├── entropyGradDist.m │ │ │ ├── golden.m │ │ │ ├── iqr.m │ │ │ ├── ksizeCalcUseful.m │ │ │ ├── ksizeHall.m │ │ │ ├── ksizeLSCV.m │ │ │ ├── ksizeMSP.m │ │ │ ├── ksizeROT.m │ │ │ ├── prodSampleImportGauss.m │ │ │ ├── prodSampleImportMix.m │ │ │ ├── prodSampleImportPair.m │ │ │ ├── randKernel.m │ │ │ ├── reduceKD.m │ │ │ ├── reduceKD2.m │ │ │ └── reduceSolveM.m │ │ ├── productApprox.m │ │ ├── productExact.m │ │ ├── quantize.m │ │ ├── reduce.m │ │ ├── resample.m │ │ ├── rescale.m │ │ └── sample.m │ ├── run_sampling.m │ ├── sample_truncations.m │ ├── sample_viewpoints.m │ └── setup_path.m ├── overlay_background.m ├── rdir.m ├── render_helper.py ├── render_model_views.py ├── run_crop.py ├── run_overlay.py └── run_render.py ├── setup.py ├── train ├── imagenet_mean.binaryproto ├── solver.prototxt.example └── train_val.prototxt.example └── view_estimation ├── .gitignore ├── README.md ├── box_overlap.m ├── caffe_utils.py ├── combine_bbox_view.m ├── compute_recall_precision_accuracy_3dview.m ├── compute_recall_precision_accuracy_azimuth.m ├── compute_vp_acc_mederror.m ├── data_prep_helper.py ├── evaluation_helper.py ├── extract_records.m ├── jitter_imcrop.m ├── prepare_testing_data.py ├── prepare_training_data.py ├── prepare_voc12_imgs.m ├── prepare_voc12val_det_imgs.m ├── ref_evaluation_results ├── acc_mederr_results.txt └── avp_nv_results.txt ├── run_evaluation.py ├── test_det.m └── test_gt.m /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.m~ 3 | *.mat 4 | *.mex* 5 | *.dll 6 | *.caffemodel 7 | *.solverstate 8 | global_variables.m 9 | global_variables.py 10 | data/syn_images* 11 | data/view_* 12 | data/truncation_* 13 | data/real_images 14 | data/tmp* 15 | data/real_lmdbs 16 | data/syn_lmdbs 17 | datasets/pascal3d 18 | datasets/shapenetcore 19 | datasets/sun2012pascalformat 20 | caffe_models/*.zip 21 | *deformed* 22 | experiments 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Render for CNN 2 | 3 | Copyright (c) 2015, Geometric Computation Group of Stanford University 4 | All rights reserved. 5 | 6 | MIT License 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a 9 | copy of this software and associated documentation files (the "Software"), 10 | to deal in the Software without restriction, including without limitation 11 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | and/or sell copies of the Software, and to permit persons to whom the 13 | Software is furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /caffe_models/deploy.prototxt: -------------------------------------------------------------------------------- 1 | name: "RCNN_Fine_Tune" 2 | input: "data" 3 | input_shape { 4 | dim: 1 5 | dim: 3 6 | dim: 227 7 | dim: 227 8 | } 9 | layer { 10 | name: "conv1" 11 | type: "Convolution" 12 | bottom: "data" 13 | top: "conv1" 14 | convolution_param { 15 | num_output: 96 16 | kernel_size: 11 17 | stride: 4 18 | } 19 | } 20 | layer { 21 | name: "relu1" 22 | type: "ReLU" 23 | bottom: "conv1" 24 | top: "conv1" 25 | } 26 | layer { 27 | name: "pool1" 28 | type: "Pooling" 29 | bottom: "conv1" 30 | top: "pool1" 31 | pooling_param { 32 | pool: MAX 33 | kernel_size: 3 34 | stride: 2 35 | } 36 | } 37 | layer { 38 | name: "norm1" 39 | type: "LRN" 40 | bottom: "pool1" 41 | top: "norm1" 42 | lrn_param { 43 | local_size: 5 44 | alpha: 0.0001 45 | beta: 0.75 46 | } 47 | } 48 | layer { 49 | name: "conv2" 50 | type: "Convolution" 51 | bottom: "norm1" 52 | top: "conv2" 53 | convolution_param { 54 | num_output: 256 55 | pad: 2 56 | kernel_size: 5 57 | group: 2 58 | } 59 | } 60 | layer { 61 | name: "relu2" 62 | type: "ReLU" 63 | bottom: "conv2" 64 | top: "conv2" 65 | } 66 | layer { 67 | name: "pool2" 68 | type: "Pooling" 69 | bottom: "conv2" 70 | top: "pool2" 71 | pooling_param { 72 | pool: MAX 73 | kernel_size: 3 74 | stride: 2 75 | } 76 | } 77 | layer { 78 | name: "norm2" 79 | type: "LRN" 80 | bottom: "pool2" 81 | top: "norm2" 82 | lrn_param { 83 | local_size: 5 84 | alpha: 0.0001 85 | beta: 0.75 86 | } 87 | } 88 | layer { 89 | name: "conv3" 90 | type: "Convolution" 91 | bottom: "norm2" 92 | top: "conv3" 93 | convolution_param { 94 | num_output: 384 95 | pad: 1 96 | kernel_size: 3 97 | } 98 | } 99 | layer { 100 | name: "relu3" 101 | type: "ReLU" 102 | bottom: "conv3" 103 | top: "conv3" 104 | } 105 | layer { 106 | name: "conv4" 107 | type: "Convolution" 108 | bottom: "conv3" 109 | top: "conv4" 110 | convolution_param { 111 | num_output: 384 112 | pad: 1 113 | kernel_size: 3 114 | group: 2 115 | } 116 | } 117 | layer { 118 | name: "relu4" 119 | type: "ReLU" 120 | bottom: "conv4" 121 | top: "conv4" 122 | } 123 | layer { 124 | name: "conv5" 125 | type: "Convolution" 126 | bottom: "conv4" 127 | top: "conv5" 128 | convolution_param { 129 | num_output: 256 130 | pad: 1 131 | kernel_size: 3 132 | group: 2 133 | } 134 | } 135 | layer { 136 | name: "relu5" 137 | type: "ReLU" 138 | bottom: "conv5" 139 | top: "conv5" 140 | } 141 | layer { 142 | name: "pool5" 143 | type: "Pooling" 144 | bottom: "conv5" 145 | top: "pool5" 146 | pooling_param { 147 | pool: MAX 148 | kernel_size: 3 149 | stride: 2 150 | } 151 | } 152 | layer { 153 | name: "fc6" 154 | type: "InnerProduct" 155 | bottom: "pool5" 156 | top: "fc6" 157 | inner_product_param { 158 | num_output: 4096 159 | } 160 | } 161 | layer { 162 | name: "relu6" 163 | type: "ReLU" 164 | bottom: "fc6" 165 | top: "fc6" 166 | } 167 | layer { 168 | name: "drop6" 169 | type: "Dropout" 170 | bottom: "fc6" 171 | top: "fc6" 172 | dropout_param { 173 | dropout_ratio: 0.5 174 | } 175 | } 176 | layer { 177 | name: "fc7" 178 | type: "InnerProduct" 179 | bottom: "fc6" 180 | top: "fc7" 181 | inner_product_param { 182 | num_output: 4096 183 | } 184 | } 185 | layer { 186 | name: "relu7" 187 | type: "ReLU" 188 | bottom: "fc7" 189 | top: "fc7" 190 | } 191 | layer { 192 | name: "drop7" 193 | type: "Dropout" 194 | bottom: "fc7" 195 | top: "fc7" 196 | dropout_param { 197 | dropout_ratio: 0.5 198 | } 199 | } 200 | 201 | 202 | layer { 203 | name: "fc-azimuth" 204 | type: "InnerProduct" 205 | bottom: "fc7" 206 | top: "fc-azimuth" 207 | inner_product_param { 208 | num_output: 4320 209 | } 210 | } 211 | layer { 212 | name: "fc-elevation" 213 | type: "InnerProduct" 214 | bottom: "fc7" 215 | top: "fc-elevation" 216 | inner_product_param { 217 | num_output: 4320 218 | } 219 | } 220 | layer { 221 | name: "fc-tilt" 222 | type: "InnerProduct" 223 | bottom: "fc7" 224 | top: "fc-tilt" 225 | inner_product_param { 226 | num_output: 4320 227 | } 228 | } 229 | 230 | -------------------------------------------------------------------------------- /caffe_models/fetch_model.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # This script downloads pretrained caffe model 3 | 4 | DIR="$( cd "$(dirname "$0")" ; pwd -P )" 5 | cd $DIR 6 | 7 | FILE=render4cnn-release1-caffe-model.zip 8 | MODEL_FILE=render4cnn_3dview.caffemodel 9 | CHECKSUM=6d690d19f13795bf6f197131895e95bc 10 | 11 | if [ -f $MODEL_FILE ]; then 12 | echo "File already exists. Checking md5..." 13 | os=`uname -s` 14 | if [ "$os" = "Linux" ]; then 15 | checksum=`md5sum $MODEL_FILE | awk '{ print $1 }'` 16 | elif [ "$os" = "Darwin" ]; then 17 | checksum=`cat $MODEL_FILE | md5` 18 | fi 19 | if [ "$checksum" = "$CHECKSUM" ]; then 20 | echo "Model checksum is correct. No need to download." 21 | exit 0 22 | else 23 | echo "Model checksum is incorrect. Need to download again." 24 | fi 25 | fi 26 | 27 | echo "Downloading precomputed viewpoint estimation caffe model (390MB)..." 28 | 29 | wget https://shapenet.cs.stanford.edu/media/$FILE 30 | 31 | echo "Unzipping..." 32 | 33 | unzip $FILE 34 | rm $FILE 35 | 36 | echo "Done. Please run this command again to verify that checksum = $CHECKSUM." 37 | -------------------------------------------------------------------------------- /caffe_models/imagenet_mean.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/caffe_models/imagenet_mean.npy -------------------------------------------------------------------------------- /data/detection_results/bbox_mat_filelist.txt: -------------------------------------------------------------------------------- 1 | rcnn_bbox_reg_pruned/aeroplane_pruned_boxes_voc_2012_val_bbox_reg.mat 2 | rcnn_bbox_reg_pruned/bicycle_pruned_boxes_voc_2012_val_bbox_reg.mat 3 | rcnn_bbox_reg_pruned/boat_pruned_boxes_voc_2012_val_bbox_reg.mat 4 | rcnn_bbox_reg_pruned/bottle_pruned_boxes_voc_2012_val_bbox_reg.mat 5 | rcnn_bbox_reg_pruned/bus_pruned_boxes_voc_2012_val_bbox_reg.mat 6 | rcnn_bbox_reg_pruned/car_pruned_boxes_voc_2012_val_bbox_reg.mat 7 | rcnn_bbox_reg_pruned/chair_pruned_boxes_voc_2012_val_bbox_reg.mat 8 | rcnn_bbox_reg_pruned/diningtable_pruned_boxes_voc_2012_val_bbox_reg.mat 9 | rcnn_bbox_reg_pruned/motorbike_pruned_boxes_voc_2012_val_bbox_reg.mat 10 | rcnn_bbox_reg_pruned/sofa_pruned_boxes_voc_2012_val_bbox_reg.mat 11 | rcnn_bbox_reg_pruned/train_pruned_boxes_voc_2012_val_bbox_reg.mat 12 | rcnn_bbox_reg_pruned/tvmonitor_pruned_boxes_voc_2012_val_bbox_reg.mat 13 | -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/aeroplane_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/aeroplane_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/bicycle_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/bicycle_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/boat_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/boat_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/bottle_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/bottle_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/bus_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/bus_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/car_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/car_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/chair_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/chair_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/diningtable_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/diningtable_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/motorbike_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/motorbike_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/sofa_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/sofa_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/train_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/train_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /data/detection_results/rcnn_bbox_reg_pruned/tvmonitor_pruned_boxes_voc_2012_val_bbox_reg.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/data/detection_results/rcnn_bbox_reg_pruned/tvmonitor_pruned_boxes_voc_2012_val_bbox_reg.mat -------------------------------------------------------------------------------- /datasets/get_pascal3d.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # This script downloads the PASCAL3D+ (release 1.1) data and unzips it. 3 | 4 | # do not change this name 5 | dataset_dir="pascal3d" 6 | 7 | # if you have already had the same version of dataset, you can 8 | # create soft link like this: 9 | # >> ln -s pascal3d 10 | 11 | DIR="$( cd "$(dirname "$0")" ; pwd -P )" 12 | cd $DIR 13 | 14 | echo "Downloading..." 15 | 16 | wget ftp://cs.stanford.edu/cs/cvgl/PASCAL3D+_release1.1.zip 17 | 18 | echo "Unzipping..." 19 | 20 | mkdir $dataset_dir 21 | unzip PASCAL3D+_release1.1.zip && rm -f PASCAL3D+_release1.1.zip 22 | mv PASCAL3D+_release1.1/* $dataset_dir && rm -rf PASCAL3D+_release1.1 23 | 24 | echo "Done." 25 | -------------------------------------------------------------------------------- /datasets/get_shapenet.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # This script downloads the ShapeNet data and unzips it. 3 | 4 | # do not change this name 5 | dataset_dir="shapenetcore" 6 | zip_file="ShapeNetCore.v1.zip" 7 | 8 | # if you have already had the same version of dataset, you can 9 | # create soft link like this: 10 | # >> ln -s shapenetcore 11 | 12 | DIR="$( cd "$(dirname "$0")" ; pwd -P )" 13 | cd $DIR 14 | 15 | if [ -f $zip_file ]; 16 | then 17 | echo "Good. you already have the zip file downloaded." 18 | else 19 | echo "Please visit http://shapenet.cs.stanford.edu to request ShapeNet data and then put the zip file in this folder and then run this script again.." 20 | fi 21 | 22 | echo "Unzipping..." 23 | 24 | mkdir $dataset_dir 25 | unzip ShapeNetCore.v1.zip && rm -f ShapeNetCore.v1.zip 26 | mv ShapeNetCore.v1/* $dataset_dir && rm -rf ShapeNetCore.v1 27 | cd $dataset_dir 28 | for zipfile in `ls *.zip`; do unzip $zipfile; done 29 | cd .. 30 | 31 | echo "Done." 32 | -------------------------------------------------------------------------------- /datasets/get_sun2012pascalformat.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # This script downloads the SUN2012 data and unzips it. 3 | 4 | # do not change this name 5 | dataset_dir="sun2012pascalformat" 6 | 7 | # if you have already had the same version of dataset, you can 8 | # create soft link like this: 9 | # >> ln -s sun2012pascalformat 10 | 11 | DIR="$( cd "$(dirname "$0")" ; pwd -P )" 12 | cd $DIR 13 | 14 | echo "Downloading..." 15 | 16 | wget http://groups.csail.mit.edu/vision/SUN/releases/SUN2012pascalformat.tar.gz 17 | 18 | echo "Unzipping..." 19 | 20 | mkdir $dataset_dir 21 | tar -zxvf SUN2012pascalformat.tar.gz && rm -f SUN2012pascalformat.tar.gz 22 | mv SUN2012pascalformat/* $dataset_dir && rm -rf SUN2012pascalformat 23 | 24 | ls JPEGImages > filelist.txt 25 | 26 | echo "Done." 27 | -------------------------------------------------------------------------------- /demo_render/.gitignore: -------------------------------------------------------------------------------- 1 | demo_images* 2 | -------------------------------------------------------------------------------- /demo_render/README.md: -------------------------------------------------------------------------------- 1 | Render for CNN: image synthesis pipeline demo 2 | 3 | python run_demo.py 4 | 5 | reference output images are in `ref_output`. 6 | -------------------------------------------------------------------------------- /demo_render/ref_output/demo_images/chair001/demo_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/ref_output/demo_images/chair001/demo_img.png -------------------------------------------------------------------------------- /demo_render/ref_output/demo_images_cropped/chair001/demo_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/ref_output/demo_images_cropped/chair001/demo_img.png -------------------------------------------------------------------------------- /demo_render/ref_output/demo_images_cropped_bkg_overlaid/chair001/demo_img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/ref_output/demo_images_cropped_bkg_overlaid/chair001/demo_img.jpg -------------------------------------------------------------------------------- /demo_render/render_class_view.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os.path as osp 4 | import sys 5 | import argparse 6 | import os, tempfile, glob, shutil 7 | 8 | BASE_DIR = osp.dirname(__file__) 9 | sys.path.append(osp.join(BASE_DIR,'../')) 10 | from global_variables import * 11 | 12 | 13 | parser = argparse.ArgumentParser(description='Render Model Images of a certain class and view') 14 | parser.add_argument('-m', '--model_file', help='CAD Model obj filename', default=osp.join(BASE_DIR,'sample_model/model.obj')) 15 | parser.add_argument('-a', '--azimuth', default='45') 16 | parser.add_argument('-e', '--elevation', default='20') 17 | parser.add_argument('-t', '--tilt', default='0') 18 | parser.add_argument('-d', '--distance', default='2.0') 19 | parser.add_argument('-o', '--output_img', help='Output img filename.', default=osp.join(BASE_DIR, 'demo_img.png')) 20 | args = parser.parse_args() 21 | 22 | blank_file = osp.join(g_blank_blend_file_path) 23 | render_code = osp.join(g_render4cnn_root_folder, 'render_pipeline/render_model_views.py') 24 | 25 | # MK TEMP DIR 26 | temp_dirname = tempfile.mkdtemp() 27 | view_file = osp.join(temp_dirname, 'view.txt') 28 | view_fout = open(view_file,'w') 29 | view_fout.write(' '.join([args.azimuth, args.elevation, args.tilt, args.distance])) 30 | view_fout.close() 31 | 32 | try: 33 | render_cmd = '%s %s --background --python %s -- %s %s %s %s %s' % (g_blender_executable_path, blank_file, render_code, args.model_file, 'xxx', 'xxx', view_file, temp_dirname) 34 | print render_cmd 35 | os.system(render_cmd) 36 | imgs = glob.glob(temp_dirname+'/*.png') 37 | shutil.move(imgs[0], args.output_img) 38 | except: 39 | print('render failed. render_cmd: %s' % (render_cmd)) 40 | 41 | # CLEAN UP 42 | shutil.rmtree(temp_dirname) 43 | -------------------------------------------------------------------------------- /demo_render/run_demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | ''' 4 | RENDERING PIPELINE DEMO 5 | run it several times to see random images with different lighting conditions, 6 | viewpoints, truncations and backgrounds. 7 | ''' 8 | 9 | import os 10 | import sys 11 | from PIL import Image 12 | import random 13 | from datetime import datetime 14 | random.seed(datetime.now()) 15 | 16 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 17 | sys.path.append(BASE_DIR) 18 | sys.path.append(os.path.join(BASE_DIR,'../')) 19 | from global_variables import * 20 | 21 | # set debug mode 22 | debug_mode = 1 23 | 24 | if debug_mode: 25 | io_redirect = '' 26 | else: 27 | io_redirect = ' > /dev/null 2>&1' 28 | 29 | # ------------------------------------------- 30 | # RENDER 31 | # ------------------------------------------- 32 | 33 | # set filepath 34 | syn_images_folder = os.path.join(BASE_DIR, 'demo_images') 35 | model_name = 'chair001' 36 | image_name = 'demo_img.png' 37 | if not os.path.exists(syn_images_folder): 38 | os.mkdir(syn_images_folder) 39 | os.mkdir(os.path.join(syn_images_folder, model_name)) 40 | viewpoint_samples_file = os.path.join(BASE_DIR, 'sample_viewpoints.txt') 41 | viewpoint_samples = [[float(x) for x in line.rstrip().split(' ')] for line in open(viewpoint_samples_file,'r')] 42 | 43 | # run code 44 | v = random.choice(viewpoint_samples) 45 | print ">> Selected view: ", v 46 | python_cmd = 'python %s -a %s -e %s -t %s -d %s -o %s' % (os.path.join(BASE_DIR, 'render_class_view.py'), 47 | str(v[0]), str(v[1]), str(v[2]), str(v[3]), os.path.join(syn_images_folder, model_name, image_name)) 48 | print ">> Running rendering command: \n \t %s" % (python_cmd) 49 | os.system('%s %s' % (python_cmd, io_redirect)) 50 | 51 | # show result 52 | print(">> Displaying rendered image ...") 53 | im = Image.open(os.path.join(syn_images_folder, model_name, image_name)) 54 | im.show() 55 | 56 | 57 | # ------------------------------------------- 58 | # CROP 59 | # ------------------------------------------- 60 | 61 | # set filepath 62 | bkg_folder = os.path.join(BASE_DIR, 'sample_bkg_images') 63 | bkg_filelist = os.path.join(bkg_folder, 'filelist.txt') 64 | syn_images_cropped_folder = os.path.join(BASE_DIR, 'demo_images_cropped') 65 | truncation_samples_file = os.path.join(BASE_DIR, 'sample_truncations.txt') 66 | 67 | # run matlab code 68 | matlab_cmd = "addpath('%s'); crop_images('%s','%s','%s',1);" % (os.path.join(g_render4cnn_root_folder, 'render_pipeline'), syn_images_folder, syn_images_cropped_folder, truncation_samples_file) 69 | print ">> Starting MATLAB ... to run cropping command: \n \t %s" % matlab_cmd 70 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;" %s' % (g_matlab_executable_path, matlab_cmd, io_redirect)) 71 | 72 | # show result 73 | print(">> Displaying cropped image ...") 74 | im = Image.open(os.path.join(syn_images_cropped_folder, model_name, image_name)) 75 | im.show() 76 | 77 | 78 | # ------------------------------------------- 79 | # OVERLAY BACKGROUND 80 | # ------------------------------------------- 81 | 82 | # set filepath 83 | syn_images_cropped_bkg_overlaid_folder = os.path.join(BASE_DIR, 'demo_images_cropped_bkg_overlaid') 84 | 85 | # run code 86 | matlab_cmd = "addpath('%s'); overlay_background('%s','%s','%s', '%s', %f, 1);" % (os.path.join(g_render4cnn_root_folder, 'render_pipeline'), syn_images_cropped_folder, syn_images_cropped_bkg_overlaid_folder, bkg_filelist, bkg_folder, 1.0) 87 | print ">> Starting MATLAB ... to run background overlaying command: \n \t %s" % matlab_cmd 88 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;" %s' % (g_matlab_executable_path, matlab_cmd, io_redirect)) 89 | 90 | # show result 91 | print("Displaying background overlaid image ...") 92 | im = Image.open(os.path.join(syn_images_cropped_bkg_overlaid_folder, model_name, image_name.replace('.png', '.jpg'))) 93 | im.show() 94 | -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/filelist.txt: -------------------------------------------------------------------------------- 1 | sun_admehzzcyrwqeagf.jpg 2 | sun_amxqyvcaerikvqep.jpg 3 | sun_amyacsvlywqnpmum.jpg 4 | sun_amyamgmyudixgkeu.jpg 5 | sun_amyaojhhpfkypfki.jpg 6 | sun_amydkgquihpzayht.jpg 7 | sun_amyhazfgaoclbgqs.jpg 8 | sun_amymtdfzotooyham.jpg 9 | sun_amynimbbnwqwejeg.jpg 10 | sun_amyqdfkizefupfta.jpg 11 | sun_amyqrurobufixjqr.jpg 12 | sun_amyrciusrihbhswi.jpg 13 | sun_amyuvmazodqhkrin.jpg 14 | sun_amyvdsxkokkyxnft.jpg 15 | sun_amywfwnlavdpohzn.jpg 16 | sun_amywncoshhwkcvek.jpg 17 | sun_amyxaanrovbdsxnk.jpg 18 | sun_aruegippndskcujm.jpg 19 | -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_admehzzcyrwqeagf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_admehzzcyrwqeagf.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amxqyvcaerikvqep.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amxqyvcaerikvqep.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyacsvlywqnpmum.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyacsvlywqnpmum.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyamgmyudixgkeu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyamgmyudixgkeu.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyaojhhpfkypfki.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyaojhhpfkypfki.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amydkgquihpzayht.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amydkgquihpzayht.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyhazfgaoclbgqs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyhazfgaoclbgqs.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amymtdfzotooyham.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amymtdfzotooyham.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amynimbbnwqwejeg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amynimbbnwqwejeg.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyqdfkizefupfta.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyqdfkizefupfta.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyqrurobufixjqr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyqrurobufixjqr.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyrciusrihbhswi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyrciusrihbhswi.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyuvmazodqhkrin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyuvmazodqhkrin.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyvdsxkokkyxnft.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyvdsxkokkyxnft.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amywfwnlavdpohzn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amywfwnlavdpohzn.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amywncoshhwkcvek.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amywncoshhwkcvek.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_amyxaanrovbdsxnk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_amyxaanrovbdsxnk.jpg -------------------------------------------------------------------------------- /demo_render/sample_bkg_images/sun_aruegippndskcujm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_bkg_images/sun_aruegippndskcujm.jpg -------------------------------------------------------------------------------- /demo_render/sample_model/images/texture0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_model/images/texture0.jpg -------------------------------------------------------------------------------- /demo_render/sample_model/images/texture1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_render/sample_model/images/texture1.jpg -------------------------------------------------------------------------------- /demo_render/sample_model/model.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'blank.blend' 2 | # Material Count: 3 3 | 4 | newmtl material_0_1_8 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ni -1.000000 10 | d 1.000000 11 | illum 2 12 | map_Kd ./images/texture0.jpg 13 | 14 | newmtl material_1_24 15 | Ns 96.078431 16 | Ka 0.000000 0.000000 0.000000 17 | Kd 0.800000 0.800000 0.800000 18 | Ks 0.500000 0.500000 0.500000 19 | Ni -1.000000 20 | d 1.000000 21 | illum 2 22 | 23 | newmtl material_2_2_8 24 | Ns 96.078431 25 | Ka 0.000000 0.000000 0.000000 26 | Kd 0.640000 0.640000 0.640000 27 | Ks 0.500000 0.500000 0.500000 28 | Ni -1.000000 29 | d 1.000000 30 | illum 2 31 | map_Kd ./images/texture1.jpg 32 | -------------------------------------------------------------------------------- /demo_render/sample_model/model_source.txt: -------------------------------------------------------------------------------- 1 | shapenetcore/03001627/21bfb150cfc23accb01c58badc8bbc39 2 | -------------------------------------------------------------------------------- /demo_render/sample_model2/model.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'blank.blend' 2 | # Material Count: 10 3 | 4 | newmtl material_0_24 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.000000 0.097255 0.398431 8 | Ks 0.500000 0.500000 0.500000 9 | Ni -1.000000 10 | d 1.000000 11 | illum 2 12 | 13 | newmtl material_1_24 14 | Ns 96.078431 15 | Ka 0.000000 0.000000 0.000000 16 | Kd 0.109804 0.109804 0.109804 17 | Ks 0.500000 0.500000 0.500000 18 | Ni -1.000000 19 | d 1.000000 20 | illum 2 21 | 22 | newmtl material_2_24 23 | Ns 96.078431 24 | Ka 0.000000 0.000000 0.000000 25 | Kd 0.800000 0.800000 0.800000 26 | Ks 0.500000 0.500000 0.500000 27 | Ni -1.000000 28 | d 1.000000 29 | illum 2 30 | 31 | newmtl material_3_24 32 | Ns 96.078431 33 | Ka 0.000000 0.000000 0.000000 34 | Kd 0.800000 0.800000 0.800000 35 | Ks 0.500000 0.500000 0.500000 36 | Ni -1.000000 37 | d 1.000000 38 | illum 2 39 | 40 | newmtl material_4_24 41 | Ns 96.078431 42 | Ka 0.000000 0.000000 0.000000 43 | Kd 0.800000 0.000000 0.000000 44 | Ks 0.500000 0.500000 0.500000 45 | Ni -1.000000 46 | d 1.000000 47 | illum 2 48 | 49 | newmtl material_5_24 50 | Ns 96.078431 51 | Ka 0.000000 0.000000 0.000000 52 | Kd 0.401569 0.401569 0.401569 53 | Ks 0.500000 0.500000 0.500000 54 | Ni -1.000000 55 | d 1.000000 56 | illum 2 57 | 58 | newmtl material_6_24 59 | Ns 96.078431 60 | Ka 0.000000 0.000000 0.000000 61 | Kd 0.000000 0.000000 0.000000 62 | Ks 0.500000 0.500000 0.500000 63 | Ni -1.000000 64 | d 1.000000 65 | illum 2 66 | 67 | newmtl material_7_24 68 | Ns 96.078431 69 | Ka 0.000000 0.000000 0.000000 70 | Kd 0.602353 0.602353 0.602353 71 | Ks 0.500000 0.500000 0.500000 72 | Ni -1.000000 73 | d 1.000000 74 | illum 2 75 | 76 | newmtl material_8_24 77 | Ns 96.078431 78 | Ka 0.000000 0.000000 0.000000 79 | Kd 0.621177 0.621177 0.621177 80 | Ks 0.500000 0.500000 0.500000 81 | Ni -1.000000 82 | d 1.000000 83 | illum 2 84 | 85 | newmtl material_9_24 86 | Ns 96.078431 87 | Ka 0.000000 0.000000 0.000000 88 | Kd 0.000000 0.263530 0.445490 89 | Ks 0.500000 0.500000 0.500000 90 | Ni -1.000000 91 | d 1.000000 92 | illum 2 93 | -------------------------------------------------------------------------------- /demo_render/sample_model2/model_source.txt: -------------------------------------------------------------------------------- 1 | shapenetcore/02691156/1caa02b831cccff090baeef8ba5b93e5 2 | -------------------------------------------------------------------------------- /demo_render/sample_truncations.txt: -------------------------------------------------------------------------------- 1 | 0 0.2 0 0 2 | 0.2 0 0 0 3 | 0 0 0 -0.3 4 | 0 0 0.2 0 5 | -------------------------------------------------------------------------------- /demo_render/sample_viewpoints.txt: -------------------------------------------------------------------------------- 1 | 45 20 0 2.0 2 | 120 40 3 2.5 3 | 0 10 0 3 4 | 240 25 2 2.4 5 | -------------------------------------------------------------------------------- /demo_view/.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.log 3 | *.png 4 | -------------------------------------------------------------------------------- /demo_view/README.md: -------------------------------------------------------------------------------- 1 | Render for CNN: demo of usages of the off-the-shelf viewpoint estiamtor on images of objects in PASCAL3D+ classes. 2 | 3 | python run_demo.py 4 | 5 | To visualize the viewpoint by rendering an object in the estimated viewpoint: 6 | 7 | python run_visualize_3dview.py 8 | 9 | reference results (estimated view and rendered image of an object in that view) are in `ref_output`. 10 | 11 | *NOTE:* You can change input image filename in `run_demo.py` and CAD model path in `run_visualize_3dview.py` to run demo on different image of other object in PASCAL3D_ classes. For batch processing, you would create a list of image filenames and a list of their class indices (can be acquired by `g_shape_names.index()`) and use the `viewpoint` function as in `run_demo.py`. 12 | -------------------------------------------------------------------------------- /demo_view/aeroplane_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_view/aeroplane_image.jpg -------------------------------------------------------------------------------- /demo_view/chair_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_view/chair_image.jpg -------------------------------------------------------------------------------- /demo_view/ref_output/aeroplane_in_estimated_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/demo_view/ref_output/aeroplane_in_estimated_view.png -------------------------------------------------------------------------------- /demo_view/ref_output/est-view.txt: -------------------------------------------------------------------------------- 1 | 228 11 8 2 | -------------------------------------------------------------------------------- /demo_view/run_demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import argparse 7 | 8 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 9 | sys.path.append(BASE_DIR) 10 | sys.path.append(os.path.dirname(BASE_DIR)) 11 | from global_variables import * 12 | sys.path.append(os.path.join(g_render4cnn_root_folder, 'view_estimation')) 13 | from evaluation_helper import viewpoint 14 | 15 | if __name__ == '__main__': 16 | 17 | img_filenames = [os.path.join(BASE_DIR, 'aeroplane_image.jpg')] 18 | class_idxs = [g_shape_names.index('aeroplane')] 19 | output_result_file = os.path.join(BASE_DIR, 'est-view.txt') 20 | 21 | if not os.path.exists(output_result_file): 22 | viewpoint(img_filenames, class_idxs, output_result_file) 23 | 24 | 25 | # display result by rendering an image of estimated viewpoint 26 | estimated_viewpoints = [[float(x) for x in line.rstrip().split(' ')] for line in open(output_result_file,'r')] 27 | v = estimated_viewpoints[0] 28 | print "Estimated view: ", v 29 | -------------------------------------------------------------------------------- /demo_view/run_demo_topk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import argparse 7 | 8 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 9 | sys.path.append(BASE_DIR) 10 | sys.path.append(os.path.dirname(BASE_DIR)) 11 | from global_variables import * 12 | sys.path.append(os.path.join(g_render4cnn_root_folder, 'view_estimation')) 13 | from evaluation_helper import viewpoint_topk 14 | 15 | if __name__ == '__main__': 16 | 17 | #img_filenames = [os.path.join(BASE_DIR, 'aeroplane_image.jpg')] 18 | #class_idxs = [g_shape_names.index('aeroplane')] 19 | img_filenames = [os.path.join(BASE_DIR, 'chair_image.jpg')] 20 | class_idxs = [g_shape_names.index('chair')] 21 | output_result_file = os.path.join(BASE_DIR, 'est-view-topk.txt') 22 | topk = 2 23 | 24 | if not os.path.exists(output_result_file): 25 | viewpoint_topk(img_filenames, class_idxs, topk, output_result_file) 26 | 27 | 28 | # display result by rendering an image of estimated viewpoint 29 | estimated_viewpoints = [[float(x) for x in line.rstrip().split(' ')] for line in open(output_result_file,'r')] 30 | v = estimated_viewpoints[0] 31 | topk = len(v)/4 32 | print("Estimated views and confidence: ") 33 | for k in range(topk): 34 | a,e,t,c = v[4*k : 4*k+4] 35 | print('rank:%d, confidence:%f, azimuth:%d, elevation:%d, tilt:%d' % (k+1, c, a, e, t)) 36 | -------------------------------------------------------------------------------- /demo_view/run_visualize_3dview.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import argparse 7 | from PIL import Image 8 | 9 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 10 | sys.path.append(BASE_DIR) 11 | sys.path.append(os.path.dirname(BASE_DIR)) 12 | from global_variables import * 13 | sys.path.append(os.path.join(g_render4cnn_root_folder, 'render_pipeline')) 14 | 15 | if __name__ == '__main__': 16 | 17 | img_filenames = [os.path.join(BASE_DIR, 'aeroplane_image.jpg')] 18 | class_idxs = [g_shape_names.index('aeroplane')] 19 | output_result_file = os.path.join(BASE_DIR, 'est-view.txt') 20 | 21 | # display result by rendering an image of estimated viewpoint 22 | estimated_viewpoints = [[float(x) for x in line.rstrip().split(' ')] for line in open(output_result_file,'r')] 23 | v = estimated_viewpoints[0] 24 | print "Estimated view: ", v 25 | 26 | # Change the model.obj file to render images of a diferrent model/category 27 | mdoel_obj_file = os.path.join(g_render4cnn_root_folder, 'demo_render', 'sample_model2', 'model.obj') 28 | output_image = os.path.join(BASE_DIR, 'aeroplane_in_estimated_view.png') 29 | io_redirect = '' #' > /dev/null 2>&1' 30 | 31 | python_cmd = 'python %s -m %s -a %s -e %s -t %s -d %s -o %s' % (os.path.join(g_render4cnn_root_folder, 'demo_render', 'render_class_view.py'), 32 | mdoel_obj_file, str(v[0]), str(v[1]), str(v[2]), str(1.0), output_image) 33 | print ">> Running rendering command: \n \t %s" % (python_cmd) 34 | os.system('%s %s' % (python_cmd, io_redirect)) 35 | 36 | 37 | print("Show both original aeroplane photo and rendered aeroplane in estimated view:") 38 | im1 = Image.open(img_filenames[0]) 39 | im2 = Image.open(output_image) 40 | bbox = im2.getbbox() 41 | im2 = im2.crop(bbox) 42 | 43 | im1.show() 44 | im2.show() 45 | -------------------------------------------------------------------------------- /demo_view/run_visualize_3dview_topk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import argparse 7 | from PIL import Image 8 | from PIL import ImageDraw 9 | 10 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 11 | sys.path.append(BASE_DIR) 12 | sys.path.append(os.path.dirname(BASE_DIR)) 13 | from global_variables import * 14 | sys.path.append(os.path.join(g_render4cnn_root_folder, 'render_pipeline')) 15 | 16 | if __name__ == '__main__': 17 | 18 | # Feel free to change input image file, result file, and model obj file for rendering 19 | 20 | # -------------------------------- 21 | #### CHANGE BEG #### 22 | output_result_file = os.path.join(BASE_DIR, 'est-view-topk.txt') 23 | model_obj_file = os.path.join(g_render4cnn_root_folder, 'demo_render', 'sample_model', 'model.obj') 24 | original_image_file = os.path.join(BASE_DIR, 'chair_image.jpg') 25 | rendered_image_file_prefix = os.path.join(BASE_DIR, 'chair_in_estimated_view') 26 | io_redirect = '' #' > /dev/null 2>&1' 27 | #### CHANGE END #### 28 | # -------------------------------- 29 | 30 | 31 | # Display estimated viewpoints that are read from result file 32 | # suppress tilt for chairs 33 | estimated_viewpoints = [[float(x) for x in line.rstrip().split(' ')] for line in open(output_result_file,'r')] 34 | v = estimated_viewpoints[0] 35 | topk = len(v)/4 36 | print("Estimated views and confidence: ") 37 | for k in range(topk): 38 | a,e,t,c = v[4*k : 4*k+4] 39 | print('rank:%d, confidence:%f, azimuth:%d, elevation:%d' % (k+1, c, a, e)) 40 | 41 | # Render images in estimated views 42 | for k in range(topk): 43 | a,e = v[4*k : 4*k+2] 44 | python_cmd = 'python %s -m %s -a %s -e %s -t %s -d %s -o %s' % (os.path.join(g_render4cnn_root_folder, 'demo_render', 'render_class_view.py'), 45 | model_obj_file, str(a), str(e), str(0), str(2.0), rendered_image_file_prefix+str(k)+'.png') 46 | print ">> Running rendering command: \n \t %s" % (python_cmd) 47 | os.system('%s %s' % (python_cmd, io_redirect)) 48 | 49 | 50 | print("Show both original aeroplane photo and rendered aeroplane in estimated view:") 51 | im1 = Image.open(original_image_file) 52 | im2s = [] 53 | for k in range(topk): 54 | im2 = Image.open(rendered_image_file_prefix+str(k)+'.png') 55 | bbox = im2.getbbox() 56 | im2 = im2.crop(bbox) 57 | draw = ImageDraw.Draw(im2) 58 | draw.text((0,0), 'rank: %d, confidence: %f\nazimuth=%f, elevation=%f' % (k+1, v[4*k+3], v[4*k], v[4*k+1]), (0,255,0)) 59 | im2s.append(im2) 60 | 61 | im1.show() 62 | for k in range(topk): 63 | im2s[k].show() 64 | -------------------------------------------------------------------------------- /render_pipeline/README.md: -------------------------------------------------------------------------------- 1 | Render for CNN: the rendering pipeline 2 | 3 | Three stages: 4 | - Render synthetic images of objects through overfit-resistant rendering, see `render_model_views.py` 5 | - Crop images according to statistics learnt from KDE on real images, see `crop_gray.m` 6 | - Overlay background to the cropped images, see `overlay_background.m` 7 | 8 | kde/: use kernel density estimation to get statistics of viewpoint and truncation patterns 9 | 10 | see `../demo_render` for a small scale demo of the render4cnn pipeline 11 | -------------------------------------------------------------------------------- /render_pipeline/blank.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/render_pipeline/blank.blend -------------------------------------------------------------------------------- /render_pipeline/crop_gray.m: -------------------------------------------------------------------------------- 1 | % crop according to truncationParam 2 | function [I, top, bottom, left, right] = crop_gray(I, bgColor, truncationParam) 3 | 4 | % get boundaries of object 5 | [nr, nc] = size(I); 6 | colsum = sum(I == bgColor, 1) ~= nr; 7 | rowsum = sum(I == bgColor, 2) ~= nc; 8 | 9 | left = find(colsum, 1, 'first'); 10 | if left == 0 11 | left = 1; 12 | end 13 | right = find(colsum, 1, 'last'); 14 | if right == 0 15 | right = length(colsum); 16 | end 17 | top = find(rowsum, 1, 'first'); 18 | if top == 0 19 | top = 1; 20 | end 21 | bottom = find(rowsum, 1, 'last'); 22 | if bottom == 0 23 | bottom = length(rowsum); 24 | end 25 | 26 | width = right - left + 1; 27 | height = bottom - top + 1; 28 | 29 | % strecth 30 | dx1 = width * truncationParam(1); % left 31 | dx2 = width * truncationParam(2); % right 32 | dy1 = height * truncationParam(3); % top 33 | dy2 = height * truncationParam(4); % bottom 34 | 35 | leftnew = max([1, left + dx1]); 36 | leftnew = min([leftnew, nc]); 37 | rightnew = max([1, right + dx2]); 38 | rightnew = min([rightnew, nc]); 39 | if leftnew > rightnew 40 | leftnew = left; 41 | rightnew = right; 42 | end 43 | 44 | topnew = max([1, top + dy1]); 45 | topnew = min([topnew, nr]); 46 | bottomnew = max([1, bottom + dy2]); 47 | bottomnew = min([bottomnew, nr]); 48 | if topnew > bottomnew 49 | topnew = top; 50 | bottomnew = bottom; 51 | end 52 | 53 | left = round(leftnew); right = round(rightnew); 54 | top = round(topnew); bottom = round(bottomnew); 55 | I = I(top:bottom, left:right, :); 56 | -------------------------------------------------------------------------------- /render_pipeline/crop_images.m: -------------------------------------------------------------------------------- 1 | function crop_images(src_folder, dst_folder, truncation_distr_file, single_thread) 2 | 3 | if nargin < 4 4 | single_thread = 0; 5 | end 6 | if single_thread 7 | num_workers = 0; 8 | else 9 | num_workers = 24; 10 | end 11 | 12 | image_files = rdir(fullfile(src_folder,'*/*.png')); 13 | image_num = length(image_files); 14 | fprintf('%d images in total.\n', image_num); 15 | if image_num == 0 16 | return; 17 | end 18 | rng('shuffle'); 19 | truncationParameters = importdata(truncation_distr_file); 20 | truncationParametersSub = truncationParameters(randi([1,length(truncationParameters)],1,image_num),:); 21 | 22 | fprintf('Start croping at time %s...it takes for a while!!\n', datestr(now, 'HH:MM:SS')); 23 | report_num = 80; 24 | fprintf([repmat('.',1,report_num) '\n\n']); 25 | report_step = floor((image_num+report_num-1)/report_num); 26 | t_begin = clock; 27 | %for i = 1:image_num 28 | parfor(i = 1:image_num, num_workers) 29 | src_image_file = image_files(i).name; 30 | try 31 | [I, ~, alpha] = imread(src_image_file); 32 | catch 33 | fprintf('Failed to read %s\n', src_image_file); 34 | end 35 | 36 | [alpha, top, bottom, left, right] = crop_gray(alpha, 0, truncationParametersSub(i,:)); 37 | I = I(top:bottom, left:right, :); 38 | 39 | if numel(I) == 0 40 | fprintf('Failed to crop %s (empty image after crop)\n', src_image_file); 41 | else 42 | dst_image_file = strrep(src_image_file, src_folder, dst_folder); 43 | [dst_image_file_folder, ~, ~] = fileparts(dst_image_file); 44 | if ~exist(dst_image_file_folder, 'dir') 45 | mkdir(dst_image_file_folder); 46 | end 47 | imwrite(I, dst_image_file, 'png', 'Alpha', alpha); 48 | end 49 | 50 | if mod(i, report_step) == 0 51 | fprintf('\b|\n'); 52 | end 53 | end 54 | t_end = clock; 55 | fprintf('%f seconds spent on cropping!\n', etime(t_end, t_begin)); 56 | end 57 | -------------------------------------------------------------------------------- /render_pipeline/kde/get_voc12train_view_stats.m: -------------------------------------------------------------------------------- 1 | function [azimuths, elevations, distances] = get_voc12train_view_stats(cls, visualize) 2 | 3 | if nargin < 2 4 | visualize = 0; 5 | end 6 | 7 | setup_path; 8 | 9 | ids = textread(sprintf(VOCopts.imgsetpath, 'train'), '%s'); 10 | M = numel(ids); 11 | 12 | azimuths = []; 13 | elevations = []; 14 | distances = []; 15 | tilts = []; 16 | 17 | for i = 1:M 18 | if mod(i,100) == 0 19 | fprintf('%s: %d/%d\n',cls,i,M); 20 | end 21 | 22 | filename = fullfile(PASCAL3D_DIR, 'Annotations', sprintf('%s_pascal/%s.mat', cls, ids{i})); 23 | if ~exist(filename,'file') 24 | continue; 25 | end 26 | anno = load(filename); 27 | objects = anno.record.objects; 28 | for k = 1:length(objects) 29 | obj = objects(k); 30 | if ~isempty(obj.viewpoint) && strcmp(obj.class,cls) 31 | try 32 | azimuths = [azimuths obj.viewpoint.azimuth]; 33 | elevations = [elevations obj.viewpoint.elevation]; 34 | tilts = [tilts obj.viewpoint.theta]; 35 | distances = [distances obj.viewpoint.distance]; 36 | catch 37 | end 38 | end 39 | % if obj.truncated==0 && obj.occluded==0 && obj.difficult==0 && strcmp(obj.class,cls) 40 | % azimuths = [azimuths obj.viewpoint.azimuth]; 41 | % elevations = [elevations obj.viewpoint.elevation]; 42 | % distances = [distances obj.viewpoint.distance]; 43 | % %easy_chairs{cnt} = struct('idx',i,'img',ids{i},'object',objects(k)); 44 | % cnt = cnt + 1; 45 | % end 46 | end 47 | end 48 | 49 | mkdir(g_view_statistics_folder); 50 | save(fullfile(g_view_statistics_folder, [cls,'_viewpoint_stats']), 'azimuths', 'elevations', 'tilts', 'distances'); 51 | 52 | if visualize 53 | figure, 54 | subplot(2,2,1), hist(azimuths), title([cls ' azimuth']); 55 | subplot(2,2,2), hist(elevations), title([cls ' elevation']); 56 | subplot(2,2,3), hist(tilts), title([cls ' tilt']); 57 | subplot(2,2,4), hist(distances), title([cls ' distance']); 58 | end 59 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/adjustBW.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/render_pipeline/kde/matlab_kde_package/adjustBW.dll -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/adjustBW.m: -------------------------------------------------------------------------------- 1 | function adjustBWs(npd,s) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % adjustBWs(Pold,BW) -- change the bandwidths in NPD to S, which is 5 | % either an (Ndims x 1) vector or an (Ndims x Npts) matrix. You 6 | % cannot change a kde with uniform bandwidths to one with variable 7 | % bandwidths or vice versa. 8 | % 9 | % see also: kde, getBW, getPoints, adjustPoints, getWeights, adjustWeights 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 13 | 14 | %#mex 15 | error(['MEX-file kde/adjustBWs not found -- please recompile if ' ... 16 | 'necessary']); 17 | 18 | 19 | %function p = adjustBW(npd,s) 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | % 22 | % Pnew = adjustBW(Pold,BW) -- make a new KDE from Pold with bandwidth BW 23 | % 24 | % see also: kde, getBW, getPoints, adjustPoints, getWeights, adjustWeights 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | 27 | % p = kde(getPoints(npd),s,getWeights(npd),getType(npd)); 28 | 29 | 30 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/adjustPoints.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/render_pipeline/kde/matlab_kde_package/adjustPoints.dll -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/adjustPoints.m: -------------------------------------------------------------------------------- 1 | function adjustPoints(kde, delta) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % adjustPoints(kde, delta) -- shift the points of kde by 'delta' 5 | % delta should be [Ndim x Npts] 6 | % 7 | % -- note: kde is altered by reference through mex. 8 | % 9 | % see also: kde, getPoints, getBW, adjustBW, getWeights, adjustWeights 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11 | 12 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 13 | 14 | %#mex 15 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/adjustWeights.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/render_pipeline/kde/matlab_kde_package/adjustWeights.dll -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/adjustWeights.m: -------------------------------------------------------------------------------- 1 | function adjustWeights(npd,w) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % adjustWeights(Pold,W) -- Change the weights of NPD to W, a (1 x 5 | % Npts) vector. 6 | % 7 | % see also: getWeights, getPoints, adjustPoints, getBW, adjustBW, kde 8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 | 10 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 11 | 12 | %#mex 13 | error(['MEX-file kde/adjustWeights not found -- please recompile if ' ... 14 | 'necessary']); 15 | 16 | 17 | %function p = adjustWeights(npd,w) 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | % 20 | % Pnew = adjustWeights(Pold,W) -- create a new density from Pold with weights W 21 | % 22 | % see also: getWeights, getPoints, adjustPoints, getBW, adjustBW, kde 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | % bw = .1; 25 | % if (size(kde.bandwidth,2)>2*kde.N), bw = getBW(npd,1:getNpts(npd)); 26 | % else bw = getBW(npd,1); end; 27 | % p = kde(getPoints(npd),bw,w,getType(npd)); 28 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/condition.m: -------------------------------------------------------------------------------- 1 | function p = condition(dens,ind,A) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % condition(P,i,A) -- find the conditional distr. P( x(~i) | x(i) = A(i)) 5 | % P is a KDE, i is a dimension index (e.g. [2,3]) and A 6 | % is an [Ndim x 1] double 7 | % 8 | % see also: kde 9 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10 | 11 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 12 | 13 | if (size(dens.bandwidth,2)>2*dens.N), % variable BW case is complicated: 14 | wNew = zeros(1,getNpts(dens)); 15 | for i=1:getNpts(dens), 16 | ktmp = kde(getPoints(dens,i),getBW(dens,i),1,getType(dens)); 17 | wNew(i) = evaluate(marginal(ktmp,ind),A(ind),0); 18 | end; 19 | else 20 | bw = getBW(dens,1); 21 | wNew = evaluate( kde(A(ind),bw(ind),1,getType(dens)) , marginal(dens,ind) , 0); 22 | end; 23 | % wNew = wNew ./ sum(wNew); 24 | wNew = wNew .* getWeights(dens); 25 | pts = getPoints(dens); 26 | if (size(dens.bandwidth,2)>2*dens.N), bw = getBW(dens,1:getNpts(dens)); 27 | else bw = getBW(dens,1); end; 28 | newInd = setdiff([1:getDim(dens)],ind); 29 | p = kde(pts(newInd,:),bw(newInd,:),wNew,getType(dens)); 30 | 31 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/covar.m: -------------------------------------------------------------------------------- 1 | function cov = covar(dens,noBiasFlag) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % covar(dens [,noBiasFlag]) -- returns the variance of a given KDE 4 | % 5 | % if noBiasFlag = 1, this is the variance of the kernel locations themselves 6 | % Otherwise, it is the covariance of the density estimate (ie smoothed by the BW). 7 | % 8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 | 10 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 11 | 12 | if (nargin < 2) noBiasFlag = 0; end; 13 | if (noBiasFlag) 14 | cov = var(getPoints(dens)',getWeights(dens)')'; 15 | else 16 | switch(dens.type), 17 | case 0, cov = dens.bandwidth(:,1); % Gaussian: store variances. 18 | case 1, cov = .2 * dens.bandwidth(:,1).^2; % Epanetch BW -> variance 19 | case 2, cov = 2 * dens.bandwidth(:,1).^2; % Laplacian BW -> variance 20 | end; 21 | end; 22 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/display.m: -------------------------------------------------------------------------------- 1 | function display(kde) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % display(kde) -- print out whatever stuff is useful about a kernel density 5 | % estimate. 6 | % 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | if(numel(kde) > 1) 12 | [r c] = size(kde); 13 | disp(['kde array: ' num2str(r) '-by-' num2str(c)]); 14 | return 15 | end 16 | 17 | typeStr = 'Unknown'; 18 | if (kde.type == 0) typeStr = 'Gaussian'; end; 19 | if (kde.type == 1) typeStr = 'Epanetchnikov'; end; 20 | if (kde.type == 2) typeStr = 'Laplacian'; end; 21 | 22 | if (size(kde.bandwidth,2)>2*kde.N), bwType = 'variable'; 23 | else bwType = 'uniform'; end; 24 | 25 | disp(['Kernel Density Estimate (tree based): ']); 26 | disp([' ',num2str(kde.D),' dimensional; ',num2str(kde.N),' points in density']); 27 | disp([' made of ',typeStr,' kernels with ',bwType,' size.']); 28 | 29 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/double_kde.m: -------------------------------------------------------------------------------- 1 | function d = double(npd) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % double(kde) -- evaluates true (1) if the kde is non-empty 5 | % 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | if (npd.N > 0) d = 1; % return 1 if the density exists 11 | else d = 0; end; 12 | 13 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/encode.m: -------------------------------------------------------------------------------- 1 | function C = encode(p,R) 2 | % 3 | % Compute vector of transmit costs for each stage of the KD-tree 4 | % 5 | 6 | N = getNpts(p); bw = getBW(p,1); 7 | if (size(p.bandwidth,2) > 2*N) 8 | error('Encoding of variable bandwidths not yet supported...'); 9 | end; 10 | if (any( abs(getWeights(p) - 1/N) > 2*eps )) 11 | error('Encoding of variable weights not yet supported...'); 12 | end; 13 | C = zeros(1,2*N); C(1) = 2*getDim(p)*R; % Root node... 14 | 15 | for i=1:N-1, % calc costs of splitting each node; 1/2 cost to each side 16 | if (~isLeaf(i,N)) 17 | mu0 = p.means(:,i); % get means of parent, children 18 | mu1 = p.means(:, double(p.leftch(i))+1); 19 | mu2 = p.means(:, double(p.rightch(i))+1); 20 | sig0= sqrt( p.bandwidth(:,i) ); % and bw's of parent, children 21 | sig1= sqrt( p.bandwidth(:,double(p.leftch(i))+1) ); 22 | sig2= sqrt( p.bandwidth(:,double(p.rightch(i))+1) ); 23 | sig0UB = sqrt(max( sig0.^2 - bw.^2, 2^-R)); % don't round down too far... 24 | 25 | [tmp,splitDim] = max( sig0UB ); % which dimension are we splitting on... 26 | %[tmp,splitDim2] = max( abs(mu0-mu1) + abs(mu0-mu2) ); 27 | %if (splitDim ~= splitDim2) warning('Disagreement?'); end; 28 | 29 | % COMPUTE COST OF SENDING MEANS 30 | muMax = max(mu1,mu2); sigDiff = sig0.^2 - (mu1.^2 + mu2.^2 - mu0.^2); 31 | for j=splitDim, 32 | costMu = gauss( muMax(j), mu0(j), sig0UB(j).^2 ,1,R ); 33 | end; 34 | for j = [1:splitDim-1,splitDim+1:getDim(p)]; 35 | costMu = costMu + gauss2( mu1(j), mu0(j), 1*sig0UB(j).^2 ,1,R ); 36 | end; 37 | 38 | % COMPUTE COST OF SENDING VARIANCES 39 | if (isLeaf(p.leftch(i),N) && isLeaf(p.rightch(i),N)), costSig = 0; costMu = 0; 40 | elseif (isLeaf(p.leftch(i),N) || isLeaf(p.rightch(i),N)), costSig = 0; 41 | else 42 | for j=splitDim, 43 | costSig = gauss2( sig1(j).^2 , sig0(j).^2/2, sig0(j).^2/4, 1, R); 44 | end; 45 | for j = [1:splitDim-1,splitDim+1:getDim(p)] 46 | costSig = costSig + gauss2( sig1(j).^2 , sig0(j).^2, sig0(j).^2/2, 1, R); 47 | end; 48 | end; 49 | 50 | %[costMu,costSig] 51 | C(double(p.leftch(i))+1) = .5 * (C(i) + costMu + costSig); 52 | C(double(p.rightch(i))+1) = .5 * (C(i) + costMu + costSig); 53 | end; 54 | end; 55 | 56 | function v = gauss(x,mu,sig2,sigOut2,R) % SIMPLE 1-SIDED GAUSSIAN 57 | v = R-log2( 2*1/sqrt(2*pi*sig2) .* exp(-(x-mu).^2 ./(2*sig2)) ); 58 | 59 | %function v = gauss(x,mu,sig2,sigOut2,R) % 1-SIDED W/ OUTLIER PROCESS 60 | % v = R-log2( 2*1/sqrt(2*pi*sig2) .* exp(-(x-mu).^2 ./(2*sig2)) ); + ... 61 | % 1/sqrt(2*pi*sig2) .* exp(-(x-mu).^2 ./(2*sigOut2)) ); 62 | 63 | function v = gauss2(x,mu,sig2,sigOut2,R) % SIMPLE 2-SIDED GAUSSIAN 64 | v = R-log2( 1/sqrt(2*pi*sig2) .* exp(-(x-mu).^2 ./(2*sig2)) ); 65 | 66 | %function v = gauss2(x,mu,sig2,sigOut2,R) % 2-SIDED W/ OUTLIER PROCESS 67 | % v = R-log2( 1/sqrt(2*pi*sig2) .* exp(-(x-mu).^2 ./(2*sig2)) + ... 68 | % 1/sqrt(2*pi*sig2) .* exp(-(x-mu).^2 ./(2*sigOut2)) ); 69 | 70 | function b = isLeaf(ind,N) 71 | ind = double(ind); 72 | if (ind <= 0 || ind > 2*N) b = 0; 73 | elseif (ind <= N-1) b = 0; 74 | else b = 1; 75 | end; 76 | 77 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/entropy.m: -------------------------------------------------------------------------------- 1 | function H = entropy(x,type,varargin) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % Entropy(x,'lvout') -- Calculate a resubstitution entropy estimate for a KDE 5 | % 'lvout' uses a leave-one-out density estimate 6 | % An error tolerance may be specified by Tol (see evalAvgLogL) 7 | % 8 | % see also: evalAvgLogL, evaluate 9 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10 | 11 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 12 | 13 | % H = -evalAvgLogL(x,x,varargin{:}); 14 | 15 | if (nargin < 2) type = 'rs'; end; 16 | if (strcmp(type,'lvout')), type='rs'; varargin={'lvout',varargin{:}}; end; 17 | 18 | switch (type), 19 | case {'rs','lln'}, H = -evalAvgLogL(x,x,varargin{:}); 20 | case 'rand', N = varargin{1}; 21 | ptsE = sample(p1,N); pE = kde(ptsE,1); 22 | KLD = evalAvgLogL(p1,pE) - evalAvgLogL(p2,pE); 23 | case 'unscent', 24 | D = getDim(x); N = getNpts(x); 25 | ptsE = getPoints(x); wts = getWeights(x); 26 | ptsE = repmat(ptsE,[1,2*D+1]); % make 2*dim copies of each point 27 | wts = repmat(wts,[1,2*D+1]); % (and its weight) 28 | bw = getBW(x,1:N); 29 | for i=1:D 30 | ptsE(i,(i-1)*N+(1:N)) = ptsE(i,(i-1)*N+(1:N)) + bw(i,:); 31 | ptsE(i,(2*i-1)*N+(1:N)) = ptsE(i,(2*i-1)*N+(1:N)) - bw(i,:); 32 | end; 33 | pE = kde(ptsE,1,wts); 34 | H = -evalAvgLogL(x,pE); 35 | case 'dist', H=entropyDist(x); 36 | otherwise, error('Unknown entropy estimate method ''type'''); 37 | end; 38 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/entropyGrad.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % 3 | % err = entropyGrad(npd,estType) 4 | % Compute gradient of an entropy estimate for the npde 5 | % 6 | % entType is one of: 7 | % ISE : integrated squared error from uniform estimate 8 | % RS,LLN : law of large numbers resubstitution estimate 9 | % KL,dist : nearest-neighbor distance based estimate 10 | % 11 | % see also: kde, miGrad, klGrad, adjustPoints 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 | 14 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 15 | 16 | function err=entropyGrad(npd,entType) 17 | if (nargin < 2), entType = 'ISE'; end; 18 | switch (upper(entType)) 19 | case 'ISE', err = entropyGradISE(npd); 20 | case {'RS','LLN'}, [err1,err2]=llGrad(npd,npd,0,1e-3,1e-2); 21 | err = -(err1+err2); 22 | % err = entropyGradRS(npd); 23 | case {'KL','DIST'}, err = entropyGradDist(npd); 24 | end; 25 | 26 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/evalAvgLogL.m: -------------------------------------------------------------------------------- 1 | function ll = evalAvgLogL(dens,at,varargin) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % evalAvgLogL(P,Q [,...]) -- evaluate the mean log-likelihood of the KDE P 5 | % at points Q ([Ndim x Npts] double or KDE) 6 | % Optional flags are the same as evaluate 7 | % See also: evaluate 8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 | 10 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 11 | 12 | if (isa(at,'kde')) 13 | L = evaluate(dens,at,varargin{:}); 14 | W = getWeights(at); 15 | ind = find(L==0); 16 | if (any(W(ind))) ll=-inf; 17 | else 18 | L(ind) = 1; 19 | ll = (log(L)*W'); 20 | end; 21 | else 22 | L = evaluate(dens,at,varargin{:}); 23 | if (length(find(L==0))) 24 | ll = inf; 25 | else 26 | ll = mean(log(L)); 27 | end; 28 | end; 29 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/evaluate.m: -------------------------------------------------------------------------------- 1 | function p = evaluate(dens,pos,varargin) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % EVALUATE Evaluate the likelihood of a density estimate at given locations 5 | % 6 | % EVALUATE(X,Y [,...]) returns a vector of the likelihood of the points Y under 7 | % the density estimate X, to a percent error tolerance Tol 8 | % Y may be [Ndim x Npoints] doubles or another KDE 9 | % Optional arguments: 10 | % 'lvout' -- leave-one-out, used: evaluate(X,X,'lvout') 11 | % Tol -- evaluate up to percent error tolerance Tol (default 1e-3) 12 | % Specify zero for an exact calculation. 13 | % 14 | % 15 | % See: Gray & Moore, "Very Fast Multivariate Kernel Density Estimation using 16 | % via Computational Geometry", in Proceedings, Joint Stat. Meeting 2003 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | 19 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 20 | 21 | lvFlag = 0; errTol = 1e-3; 22 | for i=1:nargin-2, 23 | if (strcmp(varargin{i},'lvout')) lvFlag=1; end; 24 | if (isa(varargin{i},'double')) errTol = varargin{i}; end; 25 | end; 26 | 27 | if (isa(pos,'kde')) posKDE = pos; dim = getDim(pos); 28 | else posKDE = BallTree(pos,ones(1,size(pos,2))/size(pos,2)); dim = size(pos,1); 29 | end; 30 | 31 | if (getDim(dens)~= dim) error('X and Y must have the same dimension'); end; 32 | 33 | if (lvFlag) p = DualTree(dens,errTol); 34 | else p = DualTree(dens,posKDE,errTol); 35 | end; 36 | 37 | 38 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/examples/demo_kde_1.m: -------------------------------------------------------------------------------- 1 | % Simple Example #1 -- construction, BW choice, plotting 2 | % 3 | % 4 | fprintf('KDE Example #1 : 1D density estimate with various kernels, auto BW choices\n'); 5 | 6 | p = kde([.1,.45,.55,.8],.08); % create a mixture of 4 gaussians for testing 7 | x = sample(p,1000); % and generate samples 8 | 9 | figure(1); hold off; 10 | plot(p,'r-'); hold on; 11 | plot(kde(x,'rot'),'b-'); fprintf('.'); 12 | plot(kde(x,'lcv'),'b--'); fprintf('.'); 13 | plot(kde(x,'hall'),'b:'); fprintf('.'); 14 | plot(kde(x,'rot',ones(1,1000),'Epan'),'g-'); fprintf('.'); % Quadratic kernel instead 15 | plot(kde(x,'lcv',ones(1,1000),'Epan'),'g--'); fprintf('.'); 16 | plot(kde(x,'hsjm',ones(1,1000),'Epan'),'g:'); fprintf('.\n'); 17 | 18 | legend('Original','Gauss Kernel, ROT','Gauss Kernel LCV','Gauss Kernel HSJM',... 19 | 'Epan Kernel ROT','Epan Kernel LCV','Epan Kernel HSJM'); 20 | 21 | 22 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/examples/demo_kde_2.m: -------------------------------------------------------------------------------- 1 | % Simple Example #2 -- MI estimates, joinTrees, etc 2 | % 3 | % 4 | fprintf('KDE Example #2 : MI estimates, etc\n'); 5 | 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | fprintf('Jointly Gaussian with MI = %f (nits)\n',-log(.7)); 8 | x = randn(2,1000); 9 | y = [1,.7;.7,1]^.5 * x; 10 | p = kde(y,'rot'); 11 | p1 = marginal(p,[1]); 12 | p2 = marginal(p,[2]); 13 | % MI(a,b) = H(a) + H(b) - H(a,b) 14 | MI_est = entropy(p1)+entropy(p2)-entropy(p); 15 | fprintf(' MI_est = %f (nits)\n',MI_est); 16 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | fprintf('Discrete Class Conditionals with MI ~ %f (nits)\n',log(2)); 19 | x1 = .1*randn(1,200)+.9; 20 | x2 = .1*randn(1,200)+.1; 21 | p1 = kde(x1,'rot'); 22 | p2 = kde(x2,'rot'); 23 | p = joinTrees(p1,p2); 24 | % MI = H(joint) - \sum p(class i) * H(x|class i) 25 | MI_est = entropy(p) - ... 26 | (getNpts(p1)./getNpts(p))*entropy(p1) -... 27 | (getNpts(p2)./getNpts(p))*entropy(p2); 28 | fprintf(' MI_est = %f (nits)\n',MI_est); 29 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/examples/demo_kde_3.m: -------------------------------------------------------------------------------- 1 | % Simple Example #3 -- products of gaussian mixtures 2 | % 3 | % 4 | fprintf('KDE Example #3 : Product sampling methods (single, anecdotal run)\n'); 5 | rand('state',0); 6 | randn('state',0); 7 | 8 | p = kde([.1,.45,.55,.8],.05); % create a mixture of 4 gaussians for testing 9 | q = kde([.25,.35,.7,.75],.05); % and another 10 | p = ksize(resample(p,100),'rot'); 11 | q = ksize(resample(q,150),'rot'); fprintf('.'); 12 | pd = hist(p,100,[1],[0,1]); 13 | qd = hist(q,100,[1],[0,1]); 14 | 15 | %pEx = productExact(p,{p,q},{},{}); fprintf('.'); 16 | pEx = pd.*qd; pEx = 100*pEx./sum(pEx); 17 | dummy = kde(rand(1,200),1); % placeholder for productApprox call 18 | pSm = productApprox(dummy,{p,q},{},{},'exact'); fprintf('.'); 19 | pEp = productApprox(dummy,{p,q},{},{},'epsilon',1e-3); fprintf('.'); 20 | pGi = productApprox(dummy,{p,q},{},{},'gibbs1',100); fprintf('.'); 21 | pGM = productApprox(dummy,{p,q},{},{},'gibbsMS1',5); fprintf('.\n'); 22 | 23 | figure(1); hold off; 24 | plot(linspace(0,1,100),pEx,'r-'); 25 | hold on; 26 | plot(pSm,'k-'); 27 | plot(pEp,'g-'); 28 | plot(pGi,'c-'); 29 | plot(pGM,'b-'); 30 | 31 | legend('Discretized','Exact Sampling','Epsilon-Exact','Gibbs1','GibbsMS1'); 32 | 33 | 34 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/examples/demo_regress.m: -------------------------------------------------------------------------------- 1 | % Simple Example #3 -- products of gaussian mixtures 2 | % 3 | % 4 | fprintf('Example: Kernel Regression with KDE toolbox\n'); 5 | rand('state',0); 6 | randn('state',0); 7 | 8 | x = rand(1,200); 9 | y = sin(2*pi*x) + .05*randn(1,200); 10 | bwType = {'rot','lcv','local'}; color = ['g','r','m']; 11 | plot(x,y,'bo'); 12 | for j=1:length(bwType) 13 | px = kde(x,bwType{j}); bwx = getBW(px,1); 14 | p = kde([x;y],[bwx;0]); 15 | xx = 0:.01:1; yy = 0*xx; 16 | for i=1:length(xx) 17 | yy(i) = mean(condition(p,1,[xx(i);0])); 18 | end; 19 | hold on; tmp=plot(xx,yy,[color(j),'-']); set(tmp,'LineWidth',2); hold off; 20 | end; 21 | legend('Samples','ROT kernel size','Likelihd X-Val','Local L. X-val'); 22 | 23 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/findBWCrit.m: -------------------------------------------------------------------------------- 1 | function BW=findBWCrit(p,Nmodes) 2 | % BW = findBWCrit(p,Nmodes) 3 | % find Silverman's "Critical Bandwidth" -- min BW s.t. the number of modes 4 | % is less than or equal to Nmodes (can be a vector) 5 | % 6 | 7 | if (p.type ~= 0) warning('Poorly defined operation for non-Gaussian KDEs'); end; 8 | 9 | q = kde(p); % Copy p & get max requested # of nodes 10 | Nmodes = sort(Nmodes); 11 | BW = zeros(getDim(q),length(Nmodes)); 12 | 13 | % Find crit BW of nMax 14 | minm = min(sqrt(sum( (2*q.ranges(:,1:q.N-1)).^2 ,1)),[],2); 15 | minm = max(minm,1e-6); 16 | adjustBW(q,minm*ones(getDim(q),1)); % gotta be bigger than this 17 | m = modes(q); 18 | 19 | for i=length(Nmodes):-1:1 20 | Nm = Nmodes(i); 21 | stepsize = 2; 22 | while (stepsize > 1.001) 23 | adjustBW(q, getBW(q,1) * stepsize); 24 | m2 = modes(q,m); 25 | if (size(m2,2) > Nm), m = m2; % if still OK, keep going, else back off & slow 26 | else adjustBW(q, getBW(q,1)/stepsize); stepsize = .9*stepsize; end; 27 | end; 28 | BW(:,i) = getBW(q,1); 29 | end; 30 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getBW.m: -------------------------------------------------------------------------------- 1 | function s = getBW(dens,ind) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getBW(P,i) -- returns the [Nd x 1] std dev. (kernel size) associated with 4 | % index i in the nonparametric density estimate P 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | 7 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 8 | 9 | if (nargin < 2) ind=1:dens.N; end; 10 | s = zeros(dens.D,dens.N); 11 | s(:,double(dens.perm(dens.N + (1:dens.N)))+1) = dens.bandwidth(:,dens.N + (1:dens.N)); 12 | s = s(:,ind); 13 | if (dens.type == 0) s = sqrt( s ); end; % stddev for gaussian 14 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getDim.m: -------------------------------------------------------------------------------- 1 | function D = getDim(npd) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getDim(kde) -- returns the # of dimensions of the kernel density estimate 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | 6 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 7 | 8 | D = npd.D; 9 | 10 | 11 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getNeff.m: -------------------------------------------------------------------------------- 1 | function Neff = getNeff(dens) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getNeff(P) 4 | % returns an estimate of Neff, the 'effective' number of points in the NPDE 5 | % (= sum(1/weights^2) ) 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | Neff = 1/sum(getWeights(dens).^2); 11 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getNpts.m: -------------------------------------------------------------------------------- 1 | function N = getNpts(npd) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getNpts(kde) -- return the number of kernels in the density estimate 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | 6 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 7 | 8 | N = npd.N; 9 | 10 | 11 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getPoints.m: -------------------------------------------------------------------------------- 1 | function pts = getPoints(dens,ind) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getPoints(P,ind) 4 | % returns the [Nd x Np] points of the nonparametric density estimate P 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | 7 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 8 | 9 | if (nargin < 2) ind=1:dens.N; end; 10 | pts = zeros(dens.D,dens.N); 11 | pts(:,double(dens.perm(dens.N + (1:dens.N)))+1) = dens.centers(:,dens.N + (1:dens.N)); 12 | pts = pts(:,ind); 13 | % pts = dens.centers(:,dens.N + ind); 14 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getType.m: -------------------------------------------------------------------------------- 1 | function typeS = getType(dens) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getType(P) 4 | % return the kernel type of the kernel density estimate P 5 | % One of : 'Gaussian', 'Laplacian', 'Epanetchnikov' 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | switch(dens.type) 11 | case 0, typeS = 'Gaussian'; 12 | case 1, typeS = 'Epanetchnikov'; 13 | case 2, typeS = 'Laplacian'; 14 | end; 15 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/getWeights.m: -------------------------------------------------------------------------------- 1 | function wts = getWeights(dens,ind) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % getWeights(P,ind) 4 | % returns the weights of the nonparametric density estimate P's kernels 5 | % specified by ind. 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | if (nargin < 2) ind=1:dens.N; end; 11 | wts(double(dens.perm(dens.N + (1:dens.N)))+1) = dens.weights(dens.N + (1:dens.N)); 12 | wts = wts(:,ind); 13 | % wts = dens.weights(:,dens.N + ind); 14 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/gram.m: -------------------------------------------------------------------------------- 1 | function G = gram(p) 2 | % 3 | % Compute the Gram matrix of the kernel centers in p, under the distance metric determined 4 | % by the kernel sizes of the points; G(i,j) = (p_i*p_j')/bw_i 5 | % 6 | pts = getPoints(p); N = getNpts(p); d = getDim(p); 7 | G = zeros(N); 8 | for i=1:N 9 | dummy=pts(:,i:end)-repmat(pts(:,i),1,N-i+1); 10 | G(i:N,i) =-0.5*sum(dummy.^2 ./ getBW(p,i:N).^2 + log(getBW(p,i:N).^2) ,1)'; 11 | G(i,i:N) =-0.5*sum(dummy.^2 ./ repmat(getBW(p,i).^2,[1,N-i+1]) + repmat(log(getBW(p,i).^2) ,[1,N-i+1]) ,1); 12 | end 13 | G = exp(G) ./ (2*pi)^(d/2); 14 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/hist.m: -------------------------------------------------------------------------------- 1 | function [h,varargout] = hist(dens,N,dims,range) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % [H,X,Y] = hist(dens [,N][,dims][,range]) -- make a "histogram" of a KDE 5 | % 6 | % Discretizes the KDE by evaluating it at a number of bins (N). 7 | % For 1-D densities, H is the normalized density evaluated at X. 8 | % Usage: [Y,X] = hist(p,100); plot(X,Y); 9 | % For k-D densities, H is the [len(X) x len(Y)] normalized values 10 | % evaluated at every pair (X,Y). If only two values are returned, 11 | % the second will be the matrix of 2-D (X,Y) pairs; if three are 12 | % returned the latter two will be the vectors X and Y. 13 | % Usage: mesh(hist(p,100,[1,3])) 14 | % 15 | % see also: kde, plot 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | 18 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 19 | 20 | 21 | if (nargin < 4) range = []; end; 22 | if (nargin < 3) dims = [1,2]; end; 23 | if (nargin < 2) N = 200; end; 24 | 25 | if ((getDim(dens) == 1) || (length(dims)==1)), % 1-dimensional density estimate 26 | if (getDim(dens)>1) dens = marginal(dens,dims); end; 27 | if (~range) range = [min(getPoints(dens)),max(getPoints(dens))]; end; 28 | X = linspace(range(1),range(2),N(1)); 29 | h = evaluate(dens,X); 30 | % h = h / sum(h,2); 31 | if (nargout==2) varargout{1} = X; end; 32 | 33 | else % k-dimensional density estimate 34 | if (size(N) == 1) N = N*ones(1,length(dims)); end; 35 | if (length(range)==0) range = [min(getPoints(dens),[],2),max(getPoints(dens),[],2)]; end; 36 | X = linspace(range(dims(1),1),range(dims(1),2),N(1)); 37 | Y = linspace(range(dims(2),1),range(dims(2),2),N(2)); 38 | XY = [repmat(reshape(X,[1,N(1),1]),[1,1,N(2)]) ; 39 | repmat(reshape(Y,[1,1,N(2)]),[1,N(1),1]) ]; 40 | h = evaluate(marginal(dens,dims(1:2)),reshape(XY,[2,N(1)*N(2)])); 41 | 42 | % h = h / sum(h,2); 43 | h = reshape(h,[N(1),N(2)]); 44 | if (nargout==2) varargout{1} = XY; end; 45 | if (nargout==3) varargout{1} = X; varargout{2} = Y; end; 46 | end; 47 | 48 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/ise.m: -------------------------------------------------------------------------------- 1 | function v = ise(p,q,type) 2 | % 3 | % ise(p,q [,'type']) -- estimate the integrated squared error between 4 | % two densities p,q 5 | % type: 6 | % [double] -- use "epsilon-exact" product with this value for epsilon 7 | % 'p','q' -- use the samples at p (or at q) 8 | % 'pq' -- use both samples at p & q 9 | % 10 | if (nargin < 3) type = 0; end; 11 | if (isa(type,'double')) v = iseEpsilon(p,q,type); 12 | else 13 | switch type 14 | % Three different monte-carlo estimates (different proposals) 15 | case {'p'}, x = getPoints(p); quo = evaluate(p,x); 16 | v = mean( (evaluate(p,x) - evaluate(q,x)).^2 ./ quo); 17 | case {'q'}, x = getPoints(q); quo = evaluate(q,x); 18 | v = mean( (evaluate(p,x) - evaluate(q,x)).^2 ./ quo); 19 | case {'pq'},x = [getPoints(p),getPoints(q)]; quo = .5*(evaluate(p,x)+evaluate(q,x)); 20 | v = mean( (evaluate(p,x) - evaluate(q,x)).^2 ./ quo); 21 | % and one (possible) estimate from Mark Girolami 22 | case {'abs'}, eval1 = evaluate(p,p); eval2 = evaluate(q,p); 23 | if (min(eval2) == 0) v = inf; 24 | else v = getWeights(p) * (eval1 .* abs(log(eval1./eval2)))'; 25 | end; 26 | 27 | end; 28 | end; 29 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/kde.m: -------------------------------------------------------------------------------- 1 | function p = kde(points,ks,weights,typeS) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % kde(points,ksize[,weights][,type]) -- nonparametric density estimate of a pdf 5 | % 6 | % points is the [Ndim x Npoints] array of kernel locations 7 | % ksize may be a scalar, [Ndim x 1], [Ndim x Npoints], or 8 | % a string (for data-based methods; see @kde/ksize for allowed methods) 9 | % weights is [1 x Npoints] and need not be pre-normalized 10 | % type can be one of: 'Gaussian', 'Laplacian', 'Epanetchnikov' 11 | % (only 1st letter required) (Gaussian by default) 12 | % 13 | % See also: ksize, getPoints, getBW, getWeights, getType 14 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 15 | 16 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 17 | 18 | type = 0; 19 | kstype = []; 20 | if ((nargin == 1) & isa(points,'kde')) 21 | % CONSTRUCTOR FROM KDE-TYPE 22 | type = points.type; weights = getWeights(points); 23 | if (size(points.bandwidth,2)>2*points.N), ks = getBW(points,1:getNpts(points)); 24 | else ks = getBW(points,1); end; 25 | if (type == 0), ks = ks.^2; end; 26 | points = getPoints(points); 27 | elseif (nargin == 1) % ugh, needed for deserialization 28 | for i=1:numel(points) 29 | p(i) = class(points(i), 'kde'); 30 | end 31 | p = reshape(p, size(points)); 32 | return 33 | 34 | else if (nargin > 0) 35 | % CONSTRUCTOR FROM RAW DATA 36 | error(nargchk(2,4,nargin)); 37 | 38 | if (isa(ks,'char')) kstype = ks; ks =1; end; 39 | if (size(ks,1) == 1) ks = repmat(ks,[size(points,1),1]); end; 40 | 41 | if (nargin < 3) weights = ones(1,size(points,2)); end; 42 | if (isempty(weights)) weights = ones(1,size(points,2)); end; 43 | 44 | if (nargin < 4) typeS = 'g'; 45 | else typeS = lower(typeS); typeS = typeS(1); end; 46 | switch(typeS) 47 | case 'l', type = 2; 48 | case 'e', type = 1; 49 | case 'g', type = 0; ks = ks.^2; 50 | otherwise, error('Type must be one of (G)aussian, (L)aplacian, or (E)panetchnikov'); 51 | end; 52 | 53 | weights = weights/sum(weights); 54 | 55 | % Check matrix sizes: 56 | [D,N] = size(points); 57 | if any(size(weights)~=[1,N]) error('Weights must be [1xNpoints] (or empty)'); end; 58 | bwsize = size(ks); 59 | if (any(bwsize~=[1,1]) && any(bwsize~=[D,1]) && any(bwsize~=[D,N])) 60 | error('Bandwidth must be scalar, [Dx1], [DxN], or an automatic selection method'); 61 | end; 62 | 63 | else 64 | % EMPTY CONSTRUCTOR 65 | points = []; ks = []; weights = []; 66 | end; end; 67 | 68 | p = BallTreeDensity(points,weights,ks,type); 69 | % p = class(p,'kde'); 70 | 71 | if (length(kstype)) 72 | p = ksize(p,kstype); 73 | end; 74 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/klGrad.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % [err1,err2]=klGrad(dens1,dens2,estType) 3 | % Compute gradient of a KL-divergence estimate, D(dens1 || dens2); 4 | % estType is one of: 5 | % ise : integrated squared error from uniform estimate (not yet implemented) 6 | % rs,lln,means : law of large numbers resubstitution estimate; kld(p1,p2,'rs') 7 | % abs : abs(LLN); similar to above but minimizing kld(p1,p2,'abs') 8 | % KL,dist : nearest-neighbor distance based estimate (not yet implemented) 9 | % 10 | % see also: kde, miGrad, entropyGrad, adjustPoints 11 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12 | 13 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 14 | 15 | function [err1,err2]=klGrad(p1,p2,estType,respectTo) 16 | if (nargin < 3), estType = 'lvout'; end; 17 | if (nargin < 4), respectTo = 0; end; 18 | 19 | switch (lower(estType)) 20 | 21 | case 'lvout2', % deriv(D(p1||p2) - H(p1) - H(p2)) 22 | [dPLPdens, dPLPat] = llGrad(p1,respectTo,1e-3,1e-3); 23 | [dQLQdens, dQLQat] = llGrad(p2,respectTo,1e-3,1e-3); 24 | [dPLQdens, dPLQat] = llGrad(p2,p1,respectTo,1e-3,1e-3); 25 | 26 | %LP = evaluate(p1,p1,'lvout'); 27 | %LP20 = prctile(LP,20); 28 | %LQ = evaluate(p2,p2,'lvout'); 29 | %LQ20 = prctile(LQ,20); 30 | 31 | %errXX1(:,LP gradient of a resubstitution estimate of negentropy) 9 | % type: what to take gradient with respect to. 10 | % 0 = means, 1 = bw (variance), 2=weights 11 | % tolGrad is an acceptable error tolerance on the gradient values 12 | % tolEval is a *percent* tolerance on the evaluation done as a 13 | % subroutine in the calculation; it should be tight enough to allow 14 | % tolGrad to be achieved but beyond that, larger => faster. 15 | % 16 | % Specifically, using the resubstition estimate 17 | % \hat H = \sum_j v_j \log \sum_i w_i K(x_i - y_j) 18 | % The outputs are 19 | % err1(:,i) = \sum_j v_j 1/p(y_j) dp(y_j)/dx_i = E_y[ 1/p dp/dx_i ] 20 | % err2(:,j) = v_j 1/p(y_j) p'(y_j) 21 | % 22 | % Note: [err1,err2] = llGrad(p1, type [, tolGrad ,tolEval]) computes the leave- 23 | % one-out resub. estimate, similar to llGrad(p1,p1,type...) 24 | % 25 | % Some useful estimates which can be made using this function: 26 | % 27 | % ENTROPY GRADIENT 28 | % [err1, err2] = llGrad(p,p,1e-3,1e-3); 29 | % p -= (err1 + err2) moves p in the direction of increasing entropy 30 | % 31 | % KL-DIVERGENCE GRADIENT 32 | % [errXX1, errXX2] = llGrad(p1,p1,1e-3,1e-3); 33 | % [errXYY, errXYX] = llGrad(p2,p1,1e-3,1e-3); 34 | % err1 = (errXX1 + errXX2 - errXYX); 35 | % err2 = (-errXYY); 36 | % p1 += err1, p2 += err2 moves p1,p2 in the direction of increasing KLDiv 37 | % 38 | % See also: klGrad, miGrad, entropyGrad, adjustPoints 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 42 | 43 | %#mex 44 | error('MEX-file kde/llGrad not found -- please recompile if necessary'); 45 | 46 | % Incorrect: Mean shift corresponds to an estimate of 1/p(y) p'(y) where 47 | % p'(y) is computed using the Epan. kernel while p(y) is computed using 48 | % a uniform kernel with the same support. This does *not* correspond to 49 | % the derivative of log-likelihood for any KDE (that I know of) 50 | % 51 | % MEAN-SHIFT 52 | % For equal weight uniform bandwidth Epan. kernel densities, 53 | % the mean shift algorithm (Comaniciu '99) is given by 54 | % [err1, err2] = llGrad(p,p,1e-3,1e-3); 55 | % p += .5*getNpts(p)*getBW(p,1)^2 * err2 56 | % 57 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/llHess.m: -------------------------------------------------------------------------------- 1 | function Hessians = llHess(p1,p2,tolGrad,tolEval) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % H = llHess(p1, p2, tolGrad [,tolEval]) 5 | % 6 | % Compute the Hessian of the log-likelihood log(p1) eval'd at locations p2 7 | % p2 is a KDE or double matrix; H is (D x D x Npts) 8 | % tolGrad and tolEval are not used in the current implementation. 9 | % 10 | % See also: llGrad 11 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12 | 13 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 14 | 15 | % 16 | % Should probably be MEX'd, but I haven't gotten around to it yet. 17 | % 18 | 19 | if (isa(p2,'kde')), X2 = getPoints(p2); else X2 = p2; p2 = kde(X2,1); end; 20 | 21 | X1 = getPoints(p1); 22 | N = size(X1,2); M = size(X2,2); D = size(X1,1); 23 | 24 | Hessians = zeros(D,D,M); 25 | px = evaluate(p1,p2); 26 | [tmp, grad] = llGrad(p1,p2,0); 27 | BW = getBW(p1,1:N); wts = getWeights(p1); 28 | for m=1:M % for each point to evaluate at, 29 | x = X2(:,m); % rename for convenience 30 | Hessians(:,:,m) = -grad(:,m)*grad(:,m)'; % first term: outer prod. of gradients 31 | 32 | diff = X1 - repmat(x,[1,N]); 33 | HessAdd = zeros(D,D); % compute 2nd term of Hessian: 34 | if (p1.type == 0) % GAUSSIAN KERNEL 35 | K = (2*pi)^(D/2) * exp( - diff.^2 ./ 2 ./ BW.^2 ) ./ getBW(p1,1:N); 36 | Kp = - diff./BW.^2 .* K; 37 | Kpp= (-K./BW.^2) + (-diff./BW.^2 .* Kp); 38 | elseif (p1.type == 1) % EPANETCH. KERNEL 39 | K = 1./BW .* max( 1 - (diff./BW).^2 , 0); 40 | Kpp= -(K~=0) .* 2 ./ BW.^3; 41 | Kp = Kpp .* diff; 42 | elseif (p1.type == 2) % LAPLACIAN KERNEL 43 | K = 1./BW .* exp( - diff ./ BW ); 44 | Kp = - diff./BW .* K; 45 | Kpp= - K./BW + (-diff./BW .* Kp); 46 | end; 47 | for dim=1:D 48 | HessAdd(dim,dim) = (wts * (Kpp(dim,:) .* prod(K([1:dim-1,dim+1:D],:),1))'); 49 | for dim2=dim+1:D 50 | HessAdd(dim,dim2)= (wts * (Kp(dim,:).*Kp(dim2,:).*prod(K([1:dim-1,dim+1:dim2-1,dim2+1:D],:),1))'); 51 | HessAdd(dim2,dim) = HessAdd(dim,dim2); 52 | end;end; 53 | Hessians(:,:,m) = Hessians(:,:,m) + HessAdd ./ px(m); 54 | 55 | end; 56 | 57 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/marginal.m: -------------------------------------------------------------------------------- 1 | function p = marginal(dens,ind) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % p = marginal(p2,ind) -- find the marginal of a kde on the given indices 5 | % 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | pts = getPoints(dens); 11 | if (size(dens.bandwidth,2) > 2*dens.N) 12 | sig = getBW(dens,1:getNpts(dens)); % Many different BWs? 13 | else % Or all BWs the same 14 | sig = getBW(dens,1); 15 | end; 16 | wts = getWeights(dens); 17 | p = kde(pts(ind,:),sig(ind,:),wts,getType(dens)); 18 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/max.m: -------------------------------------------------------------------------------- 1 | function X = max(kde) 2 | % X = max(p) 3 | % A simple estimate of the maximal peak location of p; returns the kernel location 4 | % with the largest density estimate. 5 | % 6 | % See also: kde, mean, getPoints 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | L = evaluate(kde,getPoints(kde)); 11 | [mx,mxind] = max(L); 12 | X = getPoints(kde,mxind(1)); 13 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/maxlogerr.m: -------------------------------------------------------------------------------- 1 | function [maxVal,location] = logerr(p,q) 2 | % 3 | % modes = logerr(p,q) -- Find location of max. log-error between p&q 4 | % 5 | % 6 | % 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | start = [getPoints(p),getPoints(q)]; 11 | 12 | tol=1e-4; % set tolerance values etc. 13 | max_it=1000; 14 | minDistance = 1e-2; 15 | 16 | ppts = getPoints(p); pwts = getWeights(p); NptsP = size(ppts,2); pBW = getBW(p,1:NptsP); 17 | qpts = getPoints(q); qwts = getWeights(q); NptsQ = size(qpts,2); qBW = getBW(q,1:NptsQ); bwMin = min([pBW,qBW],[],2); 18 | Ndim = size(ppts,1); Nloc = size(start,2); 19 | modeList = []; vals = []; bwmin = min([min(min(pBW)),min(min(qBW))]); 20 | 21 | for m=1:Nloc % From each location given: 22 | x = start(:,m); % rename for convenience 23 | xTmp = x+inf; 24 | iter = 1; alpha = .1; dxprev = 0*x; 25 | 26 | % GRADIENT ASCENT TO FIND A MODE: 27 | while (tol < dist(x,xTmp,bwMin) && iter < max_it) % Iterate until convergence: 28 | pdiff = ppts - repmat(x,[1,NptsP]); % get distance from kernel centers 29 | qdiff = qpts - repmat(x,[1,NptsQ]); 30 | xTmp = x; % and compute the update: 31 | 32 | if (strcmp('GaussianGaussian',[getType(p),getType(q)])) 33 | Kp = prod(exp(-.5*(pdiff./pBW).^2)./pBW,1); 34 | Kq = prod(exp(-.5*(qdiff./qBW).^2)./qBW,1); 35 | px = pwts * Kp'; qx = qwts * Kq'; px = px + eps; qx = qx + eps; 36 | dx = (pdiff./ pBW.^2)*(pwts .* Kp)'./px - (qdiff./ qBW.^2)*(qwts .* Kq)'./qx; 37 | x = sign(log(px/qx)) * alpha * dx + x; 38 | else error('Sorry; KDE type(s) not implemented'); 39 | end; 40 | if (min(dx .* dxprev)>0) alpha = alpha ./ .9; else alpha = .5*alpha; end; 41 | if (alpha < 1e-3) iter = inf; end; 42 | dxprev = dx; 43 | 44 | iter = iter + 1; % increment and continue 45 | end 46 | 47 | % if (iter < max_it) 48 | modeList = [modeList,x]; % save all extremum 49 | vals = [vals,abs(log(px/qx))]; % and how extreme 50 | % end; 51 | end 52 | 53 | [vals,order] = sort(-vals); 54 | modeList = modeList(:,order); 55 | 56 | m = 1; % Remove any redundant modes: 57 | while (m < size(modeList,2)) % start with "best" modes and 58 | ind = [m+1:size(modeList,2)]; % work downwards: 59 | d = dist( modeList(:,ind), modeList(:,m+0*ind), bwMin(:,1+0*ind)); 60 | ok = find(d > minDistance); % remove any within minDistance 61 | modeList = modeList(:,[1:m,m+ok]); % of a better mode 62 | vals = vals(:,[1:m,m+ok]); 63 | m = m+1; 64 | end; 65 | maxVal = -vals(1); location = modeList(:,1); 66 | 67 | 68 | function d=dist(x,y,bw) 69 | d = sqrt( sum( ((x-y)./bw).^2 ,1)); 70 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mean.m: -------------------------------------------------------------------------------- 1 | function m = mean(dens) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % mean(dens) -- returns the mean of a given KDE 4 | % 5 | % See also: kde, covar, max 6 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | m = dens.means(:,1); 11 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/BallTree.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include "cpp/BallTree.h" 10 | #include "mex.h" 11 | 12 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 13 | { 14 | 15 | // check for the right number of arguments 16 | if(nrhs != 2) 17 | mexErrMsgTxt("Takes 2 input arguments"); 18 | if(nlhs != 1) 19 | mexErrMsgTxt("Outputs one result (a structure)"); 20 | 21 | // points, weights 22 | plhs[0] = BallTree::createInMatlab(prhs[0],prhs[1]); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/BallTreeDensity.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include "cpp/BallTreeDensity.h" 10 | #include "mex.h" 11 | 12 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 13 | { 14 | 15 | // check for the right number of arguments 16 | if((nrhs < 3)||(nrhs > 4)) 17 | mexErrMsgTxt("Takes 3-4 input arguments"); 18 | if(nlhs != 1) 19 | mexErrMsgTxt("Outputs one result (a structure)"); 20 | 21 | if (nrhs == 3) // points, weights, bandwidths 22 | plhs[0] = BallTreeDensity::createInMatlab(prhs[0],prhs[1],prhs[2]); 23 | else { // points, weights, bandwidths,type 24 | int ktype = (int) mxGetScalar(prhs[3]); 25 | plhs[0] = BallTreeDensity::createInMatlab(prhs[0],prhs[1],prhs[2],(BallTreeDensity::KernelType) ktype); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/DualTree.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include 10 | #include "mex.h" 11 | #include "cpp/BallTreeDensity.h" 12 | 13 | void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) 14 | { 15 | // verify arguments 16 | if (nrhs > 3 || nrhs < 2) 17 | mexErrMsgTxt("Takes 2-3 input arguments"); 18 | if (nlhs > 1) 19 | mexErrMsgTxt("Outputs 1 results"); 20 | 21 | BallTreeDensity densTree = BallTreeDensity(prhs[0]); 22 | if (nrhs == 3) { // REGULAR VERSION 23 | BallTree atTree = BallTree(prhs[1]); 24 | double maxErr= mxGetScalar(prhs[2]); 25 | plhs[0] = mxCreateDoubleMatrix(1,atTree.Npts(),mxREAL); // allocate return vals 26 | densTree.evaluate(atTree, mxGetPr(plhs[0]), maxErr); // and evaluate 27 | 28 | } else { // LEAVE-ONE-OUT VERSION 29 | double maxErr= mxGetScalar(prhs[1]); 30 | plhs[0] = mxCreateDoubleMatrix(1,densTree.Npts(),mxREAL); // allocate return vals 31 | densTree.evaluate(mxGetPr(plhs[0]), maxErr); // and evaluate 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/adjustBW.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include 10 | #include "mex.h" 11 | #include "cpp/BallTreeDensity.h" 12 | 13 | void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) 14 | { 15 | // verify arguments 16 | if (nrhs != 2) 17 | mexErrMsgTxt("Takes 2 input arguments"); 18 | if (nlhs != 0) 19 | mexErrMsgTxt("Outputs no results; modifies passed kde by reference."); 20 | 21 | BallTreeDensity densTree = BallTreeDensity(prhs[0]); 22 | int N = mxGetN(prhs[1]); 23 | int M = mxGetM(prhs[1]); 24 | 25 | if (N != densTree.Npts() && N != 1) 26 | mexErrMsgTxt("Wrong number of bandwidths"); 27 | if (M != densTree.Ndim()) 28 | mexErrMsgTxt("Wrong dimension for bandwidths"); 29 | 30 | double* newBWs = mxGetPr(prhs[1]); 31 | if(densTree.getType() == BallTreeDensity::Gaussian) { 32 | double *newBWtmp = newBWs; 33 | newBWs = new double[M*N]; 34 | for(BallTree::index i=0; i 10 | #include "mex.h" 11 | #include "cpp/BallTreeDensity.h" 12 | 13 | void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) 14 | { 15 | // verify arguments 16 | if (nrhs > 2 || nrhs < 2) 17 | mexErrMsgTxt("Takes 2 input arguments"); 18 | if (nlhs != 0) 19 | mexErrMsgTxt("Outputs no results; modifies passed kde by reference."); 20 | 21 | BallTreeDensity densTree = BallTreeDensity(prhs[0]); 22 | double* delta = (double*) mxGetData(prhs[1]); 23 | densTree.movePoints(delta); 24 | } 25 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/adjustWeights.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include 10 | #include "mex.h" 11 | #include "cpp/BallTreeDensity.h" 12 | 13 | void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) 14 | { 15 | // verify arguments 16 | if (nrhs != 2) 17 | mexErrMsgTxt("Takes 2 input arguments"); 18 | if (nlhs != 0) 19 | mexErrMsgTxt("Outputs no results; modifies passed kde by reference."); 20 | 21 | BallTreeDensity densTree = BallTreeDensity(prhs[0]); 22 | 23 | if (mxGetM(prhs[1]) != 1) 24 | mexErrMsgTxt("New weights must be a row vector"); 25 | if (mxGetN(prhs[1]) != densTree.Npts()) 26 | mexErrMsgTxt("Wrong number of weights"); 27 | 28 | double* newWeights = (double*) mxGetData(prhs[1]); 29 | densTree.changeWeights(newWeights); 30 | } 31 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/cpp/README.txt: -------------------------------------------------------------------------------- 1 | Very brief README on the BallTree and BallTreeDensity classes 2 | ============================================================= 3 | 4 | Really, these should be called "KDTree" classes, since we use bounding boxes 5 | rather than spheres (balls), but I've never changed the name. 6 | 7 | A KD-Tree is a heirarchical data structure for storing point sets, which 8 | caches statistics of subsets of the points to speed up computations. We 9 | are concerned with kernel density estimates, which have three components: 10 | locations (d-dimensional) 11 | bandwidths, assumed diagonal (d-dimensional) 12 | weights (1-dimensional) 13 | At each level of the tree, we cache statistics of a set S 14 | The weighted mean of all points in S 15 | The total weight of all points in S 16 | A bounding box containing all points of S, described by 17 | its center and half-width (in each dimension) 18 | "Bandwidth" info: 19 | The variance of a Gaussian approximation to the kernels in S 20 | The min. and max. BW of any kernel in S (if non-uniform BWs) 21 | All points in S are stored contiguously, and thus can be described by 22 | a lower & upper index in the leaf nodes of the tree 23 | Because they are now spatially contiguous, there is a permutation to 24 | restore their original ordering, which is stored in the structure. 25 | The left & right child nodes, typically each containing about half the 26 | points in S. For leaf nodes, "left" is a self-reference to the same 27 | node and "right" is NO_CHILD. 28 | 29 | The code itself uses branch-and-bound style computations to perform approximate 30 | and exact operations more efficiently. 31 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/entropyGradRS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mex.h" 3 | #define MEX 4 | #include "cpp/BallTreeDensity.h" 5 | 6 | double erf(double c) { // disabled for lack of windows erf f'n 7 | return 1.0; 8 | } 9 | 10 | const double pi = 3.141592653589; 11 | const double s2pi = .398942280401432; // = 1/sqrt(2*pi); 12 | const double s2 = 1.414213562373095; // = sqrt(2); 13 | 14 | void entGrad_Resub(const BallTreeDensity& dens, double* err); 15 | 16 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 17 | { 18 | const mxArray *cell; 19 | double *err; 20 | 21 | /********************************************************************* 22 | ** Verify arguments and initialize variables 23 | *********************************************************************/ 24 | 25 | if (nrhs != 1) 26 | mexErrMsgTxt("Takes 1 input arguments"); 27 | if (nlhs > 1) 28 | mexErrMsgTxt("Outputs 1 results"); 29 | 30 | if (!mxIsClass(prhs[0],"kde")) mexErrMsgTxt("Takes one KDE class variable"); 31 | 32 | BallTreeDensity dens = BallTreeDensity(prhs[0]); 33 | 34 | if (dens.getType() != BallTreeDensity::Gaussian) 35 | mexErrMsgTxt("Sorry -- only Gaussian kernels supported"); 36 | 37 | plhs[0] = mxCreateDoubleMatrix(dens.Ndim(),dens.Npts(),mxREAL); 38 | err = mxGetPr(plhs[0]); 39 | 40 | entGrad_Resub(dens,err); 41 | } 42 | 43 | void entGrad_Resub(const BallTreeDensity& dens, double* err1) { 44 | // Law-of-Large-Numbers Estimate of Entropy: 45 | // 46 | // for (j in #pts) { % Dij = delta Xi-Xj 47 | // for (k in #pts) { % Kij = kernel of j at i 48 | // Djk = (Xj-Xk)/(2*sig) % 49 | // Kjk = exp(- Djk^2 / (2*sig)) % K'ij = Kij*Dij 50 | // ERj = (Sum(K'jk,k)/Sum(Kjk,k)) % Error = Sum(K')/Sum(K) 51 | // 52 | 53 | BallTree::index i,j; 54 | unsigned long jj; 55 | unsigned int Ndim = dens.Ndim(); 56 | unsigned int k; 57 | double *Kprime = new double[Ndim]; 58 | 59 | for (j=dens.leafFirst(dens.root());j<=dens.leafLast(dens.root());j++) { 60 | double p = 0; 61 | double* err = err1 + Ndim*dens.getIndexOf(j); 62 | for (k=0;k 3 || nrhs < 2) 15 | mexErrMsgTxt("Takes 2 or 3 arguments"); 16 | if(nlhs > 2) 17 | mexErrMsgTxt("Outputs 2 or fewer results"); 18 | 19 | if(*mxGetPr(mxGetField(prhs[0], 0, "D")) != mxGetM(prhs[1])) 20 | mexErrMsgTxt("Search points have different number of dimensions from tree points."); 21 | 22 | mxArray *nns, *dists; 23 | BallTree::index *nn_array; 24 | 25 | BallTreeDensity findingIn = BallTreeDensity(prhs[0]); 26 | double *findingFrom = mxGetPr(prhs[1]); 27 | 28 | int k = 1; 29 | if(nrhs == 3) 30 | k = (int)mxGetScalar(prhs[2]); 31 | 32 | int N = mxGetN(prhs[1]); 33 | nns = mxCreateNumericMatrix(k, N, mxUINT32_CLASS, mxREAL); 34 | dists = mxCreateDoubleMatrix(1, N, mxREAL); 35 | nn_array = (BallTree::index *)mxGetData(nns); 36 | 37 | findingIn.kNearestNeighbors(nn_array, mxGetPr(dists), findingFrom, N, k); 38 | 39 | plhs[0] = nns; 40 | // convert to matlab indices 41 | for(BallTree::index i=0; i= 2) 46 | plhs[1] = dists; 47 | } 48 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/llGrad.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #include 9 | #include "mex.h" 10 | #define MEX 11 | #include "cpp/BallTreeDensity.h" 12 | 13 | const double pi = 3.141592653589; 14 | const double s2pi = .398942280401432; // = 1/sqrt(2*pi); 15 | const double s2 = 1.414213562373095; // = sqrt(2); 16 | 17 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 18 | { 19 | BallTreeDensity atTree, densTree; 20 | BallTreeDensity *target; 21 | double *gradD, *gradA; 22 | double tolGrad=1e-3, tolEval=1e-3; 23 | int Ndin; 24 | /********************************************************************* 25 | ** Verify arguments and initialize variables 26 | *********************************************************************/ 27 | 28 | if ((nrhs > 5)||(nrhs < 2)) 29 | mexErrMsgTxt("Takes 2-5 input arguments"); 30 | if (nlhs > 2) 31 | mexErrMsgTxt("Outputs 1-2 results"); 32 | 33 | if (!mxIsClass(prhs[0],"kde")) mexErrMsgTxt("Takes two KDE class variables"); 34 | densTree = BallTreeDensity(prhs[0]); 35 | 36 | if (!mxIsClass(prhs[1],"kde")) { 37 | if (!mxIsDouble(prhs[1]) || (mxGetN(prhs[1])!= 1 || mxGetM(prhs[1])!=1)) 38 | mexErrMsgTxt("Second argument must be a KDE or the gradient type (scalar double)."); 39 | Ndin = 1; target = &densTree; 40 | } else { 41 | atTree = BallTreeDensity(prhs[1]); 42 | Ndin = 2; target = &atTree; 43 | } 44 | 45 | if (nrhs < Ndin+1) mexErrMsgTxt("Requires gradient type argument (scalar)."); 46 | 47 | int Nrows = densTree.Ndim(); 48 | int gradWRTint = (int) mxGetScalar(prhs[Ndin]); 49 | BallTreeDensity::Gradient gradWRT = (BallTreeDensity::Gradient) gradWRTint; 50 | if(gradWRT == BallTreeDensity::WRTWeight) 51 | Nrows = 1; 52 | 53 | if (nrhs > Ndin+1) tolGrad = mxGetScalar(prhs[Ndin+1]); 54 | if (nrhs > Ndin+2) tolEval = mxGetScalar(prhs[Ndin+2]); 55 | 56 | plhs[0] = mxCreateDoubleMatrix(Nrows,densTree.Npts(),mxREAL); 57 | gradD = mxGetPr(plhs[0]); 58 | if (nlhs == 2) { 59 | plhs[1] = mxCreateDoubleMatrix(Nrows,target->Npts(),mxREAL); 60 | gradA = mxGetPr(plhs[1]); 61 | } else gradA = NULL; 62 | 63 | densTree.llGrad(*target,gradD,gradA,tolEval,tolGrad,gradWRT); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/makemex.m: -------------------------------------------------------------------------------- 1 | clear mex; 2 | 3 | %%%CONSTRUCTOR%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | if (exist('BallTree.cpp')) 5 | mex BallTree.cpp cpp/BallTreeClass.cc 6 | movefile(['BallTree.',mexext],'../private/'); 7 | end; 8 | 9 | if (exist('BallTreeDensity.cpp')) 10 | mex BallTreeDensity.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 11 | movefile(['BallTreeDensity.',mexext],'../private/'); 12 | end; 13 | 14 | if (exist('adjustPoints.cpp')) 15 | mex adjustPoints.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 16 | movefile(['adjustPoints.',mexext],'../'); 17 | end; 18 | 19 | if (exist('adjustWeights.cpp')) 20 | mex adjustWeights.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 21 | movefile(['adjustWeights.',mexext],'../'); 22 | end; 23 | 24 | if (exist('adjustBW.cpp')) 25 | mex adjustBW.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 26 | movefile(['adjustBW.',mexext],'../'); 27 | end; 28 | 29 | %%%EVALUATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | if (exist('evalDirect.cpp')) 31 | mex evalDirect.c 32 | movefile(['evalDirect.',mexext],'../private/'); 33 | end; 34 | 35 | if (exist('DualTree.cpp')) 36 | mex DualTree.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 37 | movefile(['DualTree.',mexext],'../private/'); 38 | end; 39 | 40 | %%%%PRODUCT SAMPLING%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 41 | if (exist('prodSampleGibbs1.cpp')) 42 | mex prodSampleGibbs1.cpp prodSampleGibbs.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 43 | movefile(['prodSampleGibbs1.',mexext],'../private/'); 44 | end; 45 | 46 | if (exist('prodSampleGibbs2.cpp')) 47 | mex prodSampleGibbs2.cpp prodSampleGibbs.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 48 | movefile(['prodSampleGibbs2.',mexext],'../private/'); 49 | end; 50 | 51 | if (exist('prodSampleGibbsMS1.cpp')) 52 | mex prodSampleGibbsMS1.cpp prodSampleGibbsMS.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 53 | movefile(['prodSampleGibbsMS1.',mexext],'../private/'); 54 | end; 55 | 56 | if (exist('prodSampleGibbsMS2.cpp')) 57 | mex prodSampleGibbsMS2.cpp prodSampleGibbsMS.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 58 | movefile(['prodSampleGibbsMS2.',mexext],'../private/'); 59 | end; 60 | 61 | if (exist('prodSampleEpsilon.cpp')) 62 | mex prodSampleEpsilon.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 63 | movefile(['prodSampleEpsilon.',mexext],'../private/'); 64 | end; 65 | 66 | if (exist('prodSampleExact.cpp')) 67 | mex prodSampleExact.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 68 | movefile(['prodSampleExact.',mexext],'../private/'); 69 | end; 70 | 71 | %%%%%ENTROPY,ISE,KL%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72 | 73 | if (exist('entropyGradISE.cpp')) 74 | mex entropyGradISE.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 75 | movefile(['entropyGradISE.',mexext],'../private/'); 76 | end; 77 | 78 | if (exist('llGrad.cpp')) 79 | mex llGrad.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 80 | movefile(['llGrad.',mexext],'../'); 81 | end; 82 | 83 | if (exist('iseEpsilon.cpp')) 84 | mex iseEpsilon.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 85 | movefile(['iseEpsilon.',mexext],'../private'); 86 | end; 87 | 88 | 89 | %%%%%%NEAREST NEIGHBORS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 90 | 91 | if (exist('knn.cpp')) 92 | mex knn.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 93 | movefile(['knn.',mexext],'..'); 94 | end; 95 | 96 | %%%%%REDUCED SET%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 97 | if (exist('reduceSolve.cpp')) 98 | mex reduceSolve.cpp 99 | movefile(['reduceSolve.',mexext],'../private'); 100 | end; 101 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/maketmp.m: -------------------------------------------------------------------------------- 1 | clear mex; 2 | 3 | if (0) 4 | %%%CONSTRUCTOR%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | if (exist('BallTree.cpp')) 6 | mex BallTree.cpp cpp/BallTreeClass.cc 7 | movefile(['BallTree.',mexext],'../private/'); 8 | end; 9 | 10 | if (exist('BallTreeDensity.cpp')) 11 | mex BallTreeDensity.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 12 | movefile(['BallTreeDensity.',mexext],'../private/'); 13 | end; 14 | 15 | %%%EVALUATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | if (exist('evalDirect.cpp')) 17 | mex evalDirect.c 18 | movefile(['evalDirect.',mexext],'../private/'); 19 | end; 20 | 21 | if (exist('DualTree.cpp')) 22 | mex DualTree.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 23 | movefile(['DualTree.',mexext],'../private/'); 24 | end; 25 | 26 | if (exist('llGrad.cpp')) 27 | mex llGrad.cpp cpp/BallTreeClass.cc cpp/BallTreeDensityClass.cc 28 | movefile(['llGrad.',mexext],'../'); 29 | end; 30 | 31 | end; 32 | 33 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/prodSampleGibbs1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include "mex.h" 10 | #include "cpp/BallTreeDensity.h" 11 | 12 | void gibbs1(unsigned int _Ndens, const BallTreeDensity* _trees, 13 | unsigned long Np, unsigned int Niter, 14 | double *_pts, BallTree::index *_ind, 15 | double *_randU, double* _randN); 16 | void gibbs2(unsigned int _Ndens, const BallTreeDensity* _trees, 17 | unsigned long Np, unsigned int Niter, 18 | double *_pts, BallTree::index *_ind, 19 | double *_randU, double* _randN); 20 | 21 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 22 | { 23 | mxArray **analyticFnParam; 24 | mxArray *aRandVec, *aRandVecN; 25 | mxArray *aRandParam; 26 | double *pRandParam, *randU, *randN; 27 | 28 | mxArray *pointsM, *weightsM, *indicesM; 29 | double *points, *weights; 30 | BallTree::index* indices; 31 | 32 | unsigned int i; 33 | unsigned int Niter,Ndens,Ndim; 34 | unsigned long Np; 35 | 36 | /********************************************************************* 37 | ** Verify arguments and initialize variables 38 | *********************************************************************/ 39 | 40 | if (nrhs < 3) 41 | mexErrMsgTxt("Takes 3-5 input arguments"); 42 | if (nlhs != 2) 43 | mexErrMsgTxt("Outputs 2 results"); 44 | 45 | Ndens = mxGetN(prhs[0]); // get # of densities 46 | 47 | /********************************************************************* 48 | ** Transform Matlab cell arrays into struct NPD representation 49 | *********************************************************************/ 50 | 51 | BallTreeDensity *trees = new BallTreeDensity[Ndens]; 52 | bool allGaussians = true; 53 | for (i=0; i < Ndens; i++) { 54 | trees[i] = BallTreeDensity( mxGetCell(prhs[0],i) ); 55 | if (trees[i].getType() != BallTreeDensity::Gaussian) allGaussians = false; 56 | } 57 | if (!allGaussians) 58 | mexErrMsgTxt("Sorry -- only Gaussian kernels supported"); 59 | 60 | Ndim = trees[0].Ndim(); // # of dimensions 61 | Np = (unsigned long) mxGetScalar(prhs[1]); // # of points to sample 62 | Niter = (unsigned int) mxGetScalar(prhs[2]); // # of gibbs iterations 63 | 64 | if ((nrhs < 5) || (mxGetN(prhs[3]) == 0)) { // load analytic function 65 | analyticFnParam = NULL; // params if required 66 | } 67 | else { 68 | analyticFnParam = (mxArray**) mxMalloc(3*sizeof(mxArray*)); 69 | analyticFnParam[0] = (mxArray*) prhs[3]; 70 | analyticFnParam[1] = (mxArray*) prhs[4]; 71 | } 72 | 73 | pointsM = plhs[0] = mxCreateDoubleMatrix(Ndim, Np, mxREAL); // set up matlab output 74 | points = (double*) mxGetData(plhs[0]); 75 | // plhs[1] = mxCreateDoubleMatrix(1, Np, mxREAL); 76 | // weights = (double*) mxGetData(plhs[1]); 77 | plhs[1] = mxCreateNumericMatrix(Ndens, Np, mxUINT32_CLASS, mxREAL); 78 | indices = (BallTree::index*) mxGetData(plhs[1]); 79 | 80 | // Generate enough random numbers to get us through the rest of this 81 | aRandParam = mxCreateDoubleMatrix(1, 2, mxREAL); 82 | pRandParam = mxGetPr(aRandParam); 83 | pRandParam[0] = 1; pRandParam[1] = Np*Ndens*(Niter+1); 84 | mexCallMATLAB(1, &aRandVec, 1, &aRandParam, "rand"); randU = mxGetPr(aRandVec); 85 | pRandParam[0] = 1; pRandParam[1] = Ndim*Np; 86 | mexCallMATLAB(1, &aRandVecN, 1, &aRandParam, "randn"); randN = mxGetPr(aRandVecN); 87 | mxDestroyArray(aRandParam); 88 | 89 | // Params: Ndens, trees, points, weights, indices, randomU, randomN 90 | gibbs1(Ndens,trees,Np,Niter,points,indices, randU,randN); 91 | 92 | delete[] trees; 93 | 94 | if (analyticFnParam != NULL) 95 | mxFree(analyticFnParam); 96 | 97 | mxDestroyArray(aRandVec); 98 | mxDestroyArray(aRandVecN); 99 | } 100 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/mex/prodSampleGibbs2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Matlab MEX interface for KD-tree C++ functions 3 | // 4 | // Written by Alex Ihler and Mike Mandel 5 | // Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 6 | // 7 | 8 | #define MEX 9 | #include "mex.h" 10 | #include "cpp/BallTreeDensity.h" 11 | 12 | void gibbs1(unsigned int _Ndens, const BallTreeDensity* _trees, 13 | unsigned long Np, unsigned int Niter, 14 | double *_pts, BallTree::index *_ind, 15 | double *_randU, double* _randN); 16 | void gibbs2(unsigned int _Ndens, const BallTreeDensity* _trees, 17 | unsigned long Np, unsigned int Niter, 18 | double *_pts, BallTree::index *_ind, 19 | double *_randU, double* _randN); 20 | 21 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 22 | { 23 | mxArray **analyticFnParam; 24 | mxArray *aRandVec, *aRandVecN; 25 | mxArray *aRandParam; 26 | double *pRandParam, *randU, *randN; 27 | 28 | mxArray *pointsM, *weightsM, *indicesM; 29 | double *points, *weights; 30 | BallTree::index* indices; 31 | 32 | unsigned int i; 33 | unsigned int Niter,Ndens,Ndim,Np; 34 | 35 | /********************************************************************* 36 | ** Verify arguments and initialize variables 37 | *********************************************************************/ 38 | 39 | if (nrhs < 3) 40 | mexErrMsgTxt("Takes 3-5 input arguments"); 41 | if (nlhs != 2) 42 | mexErrMsgTxt("Outputs 2 results"); 43 | 44 | Ndens = mxGetN(prhs[0]); // get # of densities 45 | 46 | /********************************************************************* 47 | ** Transform Matlab cell arrays into struct NPD representation 48 | *********************************************************************/ 49 | 50 | BallTreeDensity *trees = new BallTreeDensity[Ndens]; 51 | bool allGaussians = true; 52 | for (i=0; i < Ndens; i++) { 53 | trees[i] = BallTreeDensity( mxGetCell(prhs[0],i) ); 54 | if (trees[i].getType() != BallTreeDensity::Gaussian) allGaussians = false; 55 | } 56 | if (!allGaussians) 57 | mexErrMsgTxt("Sorry -- only Gaussian kernels supported"); 58 | 59 | Ndim = trees[0].Ndim(); // # of dimensions 60 | Np = (unsigned long) mxGetScalar(prhs[1]); // # of points to sample 61 | Niter = (unsigned int) mxGetScalar(prhs[2]); // # of gibbs iteration 62 | 63 | if ((nrhs < 5) || (mxGetN(prhs[3]) == 0)) { // load analytic function 64 | analyticFnParam = NULL; // params if required 65 | } 66 | else { 67 | analyticFnParam = (mxArray**) mxMalloc(3*sizeof(mxArray*)); 68 | analyticFnParam[0] = (mxArray*) prhs[3]; 69 | analyticFnParam[1] = (mxArray*) prhs[4]; 70 | } 71 | 72 | pointsM = plhs[0] = mxCreateDoubleMatrix(Ndim, Np, mxREAL); // set up matlab output 73 | points = (double*) mxGetData(plhs[0]); 74 | // plhs[1] = mxCreateDoubleMatrix(1, Np, mxREAL); 75 | // weights = (double*) mxGetData(plhs[1]); 76 | plhs[1] = mxCreateNumericMatrix(Ndens, Np, mxUINT32_CLASS, mxREAL); 77 | indices = (BallTree::index*) mxGetData(plhs[1]); 78 | 79 | // Generate enough random numbers to get us through the rest of this 80 | aRandParam = mxCreateDoubleMatrix(1, 2, mxREAL); 81 | pRandParam = mxGetPr(aRandParam); 82 | pRandParam[0] = 1; pRandParam[1] = Np*Ndens*(Niter+1); 83 | mexCallMATLAB(1, &aRandVec, 1, &aRandParam, "rand"); randU = mxGetPr(aRandVec); 84 | pRandParam[0] = 1; pRandParam[1] = Ndim*Np*(Niter+1); 85 | mexCallMATLAB(1, &aRandVecN, 1, &aRandParam, "randn"); randN = mxGetPr(aRandVecN); 86 | mxDestroyArray(aRandParam); 87 | 88 | // Params: Ndens, trees, points, weights, indices, randomU, randomN 89 | gibbs2(Ndens,trees,Np,Niter,points,indices, randU,randN); 90 | 91 | delete[] trees; 92 | 93 | if (analyticFnParam != NULL) 94 | mxFree(analyticFnParam); 95 | 96 | mxDestroyArray(aRandVec); 97 | mxDestroyArray(aRandVecN); 98 | } 99 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/miGrad.m: -------------------------------------------------------------------------------- 1 | function errI = miGrad(x,a_index,type,y,gamma) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % err = miGrad(dens,index [,estType]) 5 | % 6 | % Compute the gradient (direction of increasing) mutual information for a 7 | % kernel density estimate 'dens', namely, locations to shift the points 8 | % of dens which should increase I[ dens.pts(:,index), dens.pts(:,~index) ] 9 | % 10 | % estType is one of: 11 | % 'ISE' -- integrated squared error gradient entropy estimates 12 | % 'RS','LLN' -- resubstitution estimate of entropy gradients 13 | % 'KL','DIST'-- nearest-neighbor distance based estimates 14 | % 15 | % see also: kde, entropyGrad, klGrad, adjustPoints 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | 18 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 19 | 20 | if (nargin < 3) type = 'ise'; end; 21 | if (nargin < 5), gamma = 0; end; 22 | 23 | [Nd,Np] = size(getPoints(x)); 24 | allind = 1:Nd; 25 | b_index = setdiff(allind,a_index); 26 | 27 | errHA = entropyGrad(marginal(x,a_index),type); %marginal a of x 28 | errHB = entropyGrad(marginal(x,b_index),type); %marginal b of x 29 | errHAB= entropyGrad(x,type); 30 | 31 | % if we have negative examples 32 | if (gamma), 33 | errHA = errHA - gamma * entropyGrad(marginal(y,a_index), type ); 34 | errHB = errHB - gamma * entropyGrad(marginal(y,b_index), type ); 35 | errHAB = errHAB - gamma * entropyGrad(y, type ); 36 | end; 37 | 38 | % errI = errHA+errHB-errHAB % MI(a,b) = H(a)+H(b)-H(a,b): 39 | errI = -errHAB; 40 | errI(a_index,:) = errI(a_index,:)+errHA; 41 | errI(b_index,:) = errI(b_index,:)+errHB; 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/modes.m: -------------------------------------------------------------------------------- 1 | function [modeList,attr] = modes(dens,start) 2 | % 3 | % [modes,assoc] = modes(kde [,init]) -- Find modes of a KDE via fixed point iter. scheme 4 | % options: 5 | % init -- initial locations for search (default is kde's kernel centers) 6 | % returns: 7 | % modes -- list of estimated mode locations 8 | % assoc -- which mode each initial location was attracted to 9 | % 10 | % NOTE: this process is not guaranteed to find all modes; while it stands an 11 | % excellent chance for Gaussian mixtures, KDEs consisting of Ep. or Lap. kernels 12 | % have discontinous derivatives, leading to quite "jagged" distributions, and 13 | % may have many more modes than kernel centers. See M. Carreira-Perpinan's webpage, 14 | % http://www.cs.toronto.edu/~miguel/research/GMmodes.html, for an excellent 15 | % discussion. 16 | % 17 | 18 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 19 | 20 | if (nargin==1) start = getPoints(dens); end; 21 | 22 | tol=1e-4; % set tolerance values etc. 23 | max_it=1000; 24 | minDistance = 1e-2; 25 | 26 | pts = getPoints(dens); wts = getWeights(dens); start = start; 27 | Ndim = size(pts,1); Npts = size(pts,2); Nloc = size(start,2); 28 | BW = getBW(dens,1:Npts); bwMin = min(BW,[],2); 29 | modeList = []; vals = []; 30 | 31 | if (dens.type == 0) 32 | logBW = log(BW); % Cache log bandwidths for efficiency 33 | end 34 | 35 | for m=1:Nloc % From each location given: 36 | x = start(:,m); % rename for convenience 37 | xTmp = x+inf; 38 | iter = 1; 39 | 40 | % FIXED POINT ITERATION TO FIND A MODE: 41 | while (tol < dist(x,xTmp,bwMin) && iter < max_it) % Iterate until convergence: 42 | diff = pts - repmat(x,[1,Npts]); % get distance from kernel centers 43 | xTmp = x; % and compute the update: 44 | 45 | if (dens.type == 0) % GAUSSIAN 46 | K = exp(sum(-.5*(diff./BW).^2-logBW,1)); % compute kernel eval'n (missing 2pi) 47 | %K = prod(exp(-.5*(diff./BW).^2)./BW,1); % (slower kernel eval'n) 48 | px = wts * K'; % compute kde eval ( "" ) 49 | x = pts * (wts .* K)' ./ px; % compute recursion 50 | elseif (dens.type == 1) % EPANETCHNIKOV (Mean-shift like update) 51 | K = max(1-(diff./BW).^2,0)./BW; % compute kernel eval'n 52 | px = wts * prod(K,1)'; % compute kde eval ( "" ) 53 | for d=1:Ndim, % compute update in each dimension 54 | Kd = wts .* prod(K([1:d-1,d+1:Ndim],:),1) .* (K~=0); 55 | Kd = Kd ./ sum(Kd); % 56 | x(d) = pts(d,:) * Kd'; % 57 | end; 58 | else error('Sorry; KDE type not implemented'); 59 | end; 60 | 61 | iter = iter + 1; % increment and continue 62 | end 63 | 64 | H = llHess(dens,x); % Compute & 65 | if max(eig(H)) < 0 % Check the Hessian: if it's 66 | modeList = [modeList,x]; vals = [vals,px]; % neg. def. it's a mode; save it. 67 | end; 68 | 69 | end 70 | 71 | [tmp order] = sort(-vals); % Sort by descending likelihd 72 | modeList = modeList(:,order); % 73 | lookup=1:length(modeList); m = 1; % Remove any redundant modes: 74 | attr = 0*lookup; ok=[]; 75 | while (m < size(modeList,2)) % start with "best" modes and 76 | ind = [m+1:size(modeList,2)]; % work downwards: 77 | d = dist( modeList(:,ind), modeList(:,m+0*ind), bwMin(:,1+0*ind)); 78 | ok = find(d > minDistance); % remove any within minDistance 79 | modeList = modeList(:,[1:m,m+ok]); % of a better mode 80 | nok = find(d <= minDistance); 81 | attr(lookup([1,1+nok]))=m; 82 | lookup=lookup(1+ok); 83 | m = m+1; 84 | end; 85 | attr(lookup) = m; 86 | attr(order) = attr; % reverse sort operation for assoc. 87 | 88 | function d=dist(x,y,bw) 89 | d = sqrt( sum( ((x-y)./bw).^2 ,1)); 90 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/DualTree.m: -------------------------------------------------------------------------------- 1 | function [e,varargout] = DualTree(dens,pos,lvFlag) 2 | % 3 | % Crappy matlab implementation of kernel density estimate evaluation. 4 | % Slow & bloated. Only use this if BallTreeDensity.dll is absent. 5 | % 6 | % 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | if (dens.type ~= 0) error('Sorry -- crappy matlab version only does Gaussians.'); end; 11 | if (isa(pos,'kde')) pos = getPoints(kde); end; 12 | 13 | N1 = getDim(dens); 14 | N2 = getNpts(dens); 15 | [tmp, N3] = size(pos); 16 | if (tmp ~= N1) error('Eval locations have wrong dimension'); end; 17 | if (nargin < 3) lvFlag = 0; end; 18 | saveFlag = 0; 19 | 20 | sig = getBWall(dens); logsig = log(sig); % 21 | saveVal = repmat(permute(pos,[1,3,2]),[1,N2,1]); % New, faster version of above 22 | for i=1:N3, 23 | saveVal(:,:,i)=-.5*((saveVal(:,:,i)-getPoints(dens))./sig).^2 - logsig; 24 | end; 25 | 26 | prob = reshape(sum(saveVal,1),[N2,N3]); 27 | prob = exp(prob); 28 | 29 | if (lvFlag) % if leave-one-out estimate 30 | prob( sub2ind(size(prob),1:N2,1:N2) )=0; % clear the diagonal 31 | WeightAdj = 1-getWeights(dens); 32 | end; % (later avg over only N2-1 points) 33 | 34 | if (nargout >= 2) 35 | prob = 1.0/((2*pi)^(N1/2.0)) * prob .* repmat(getWeights(dens)',[1,N3]); 36 | e = sum(prob,1); 37 | else 38 | e = 1.0/((2*pi)^(N1/2.0)) * (getWeights(dens)*prob); 39 | end; 40 | if (lvFlag), e = e./WeightAdj; end; 41 | 42 | if (nargout == 2) varargout(1) = {prob}; end; % also return probabilities? 43 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/entropyDist.m: -------------------------------------------------------------------------------- 1 | function h=entropyDist(npd) 2 | % 3 | % Compute entropy estimate using nearest neighbor estimate 4 | % 5 | 6 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 7 | 8 | Ce = .57721566490153286; 9 | 10 | pts = getPoints(npd); 11 | 12 | [N1,N2] = size(pts); 13 | [tmp,D] = knn(npd,pts,2); 14 | 15 | Sr = N1* pi^(N1/2) / gamma((N1/2) + 1); 16 | h = N1/N2 * sum( log(D) ) + log(Sr * (N2-1)/N1 ) + Ce; 17 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/entropyGradDist.m: -------------------------------------------------------------------------------- 1 | function Dvect=entropyGradDist(npd) 2 | % 3 | % Compute entropy estimate using nearest neighbor estimate 4 | % 5 | 6 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 7 | 8 | pts = getPoints(npd); 9 | Ce = .57721566490153286; 10 | [N1,N2] = size(pts); 11 | [I,D] = knn(npd,pts,2); 12 | I = I(2,:); 13 | Dvect = pts - pts(:,I); 14 | 15 | %Sr = N1* pi^(N1/2) / gamma((N1/2) + 1); 16 | %h = N1/N2 * sum( log(D) ) + log(Sr * (N2-1)/N1 ) + Ce; 17 | 18 | Dvect = N1/N2 * Dvect ./ repmat(D.^2,[N1,1]); % find gradient direction 19 | %Dvect = .1 * Dvect / max(max(Dvect)); % scale for epsilon steps 20 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/golden.m: -------------------------------------------------------------------------------- 1 | function [xmin, fmin] = golden(npd, f, ax, bx, cx, tol, varargin) 2 | % 3 | %GOLDEN Minimize function of one variable using golden section search 4 | % 5 | % [xmin, fmin] = golden(npd, f, ax, bx, cx, tol) computes a local minimum 6 | % of f. xmin is the computed local minimizer of f and fmin is 7 | % f(xmin). xmin is computed to an relative accuracy of TOL. 8 | % 9 | % The parameters ax, bx and cx must satisfy the following conditions: 10 | % ax < bx < cx, f(bx) < f(ax) and f(bx) < f(cx). 11 | % 12 | % xmin satisfies ax < xmin < cx. golden is guaranteed to succeed if f 13 | % is continuous between ax and cx 14 | % 15 | % Roman Geus, ETH Zuerich, 9.12.97 16 | % 17 | % ATI -- added "npd" argument & made private to KDE class 18 | C = (3-sqrt(5))/2; 19 | R = 1-C; 20 | 21 | x0 = ax; 22 | x3 = cx; 23 | if (abs(cx-bx) > abs(bx-ax)), 24 | x1 = bx; 25 | x2 = bx + C*(cx-bx); 26 | else 27 | x2 = bx; 28 | x1 = bx - C*(bx-ax); 29 | end 30 | f1 = feval(f,x1,npd,varargin{:}); 31 | f2 = feval(f,x2,npd,varargin{:}); 32 | 33 | k = 1; 34 | while abs(x3-x0) > tol*(abs(x1)+abs(x2)), 35 | % fprintf(1,'k=%4d, |a-b|=%e\n', k, abs(x3-x0)); 36 | if f2 < f1, 37 | x0 = x1; 38 | x1 = x2; 39 | x2 = R*x1 + C*x3; % x2 = x1+c*(x3-x1) 40 | f1 = f2; 41 | f2 = feval(f,x2,npd,varargin{:}); 42 | else 43 | x3 = x2; 44 | x2 = x1; 45 | x1 = R*x2 + C*x0; % x1 = x2+c*(x0-x2) 46 | f2 = f1; 47 | f1 = feval(f,x1,npd,varargin{:}); 48 | end 49 | k = k+1; 50 | 51 | % [x0,x1,x2,x3,f1,f2] 52 | end 53 | 54 | if f1 < f2, 55 | xmin = x1; 56 | fmin = f1; 57 | else 58 | xmin = x2; 59 | fmin = f2; 60 | end 61 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/iqr.m: -------------------------------------------------------------------------------- 1 | function i = iqr(x) 2 | % 3 | % Calculate interquartile range without the stats package 4 | % 5 | 6 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 7 | 8 | xS = sort(x); % sort along dimensions 9 | N = size(x,1); 10 | i = xS(ceil(3*N/4),:) - xS(ceil(N/4),:); 11 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/ksizeCalcUseful.m: -------------------------------------------------------------------------------- 1 | function ksizeCalcUseful 2 | % 3 | % ksizeCalcUseful 4 | % -- find some useful numbers for the various kernels 5 | % 6 | 7 | 8 | % 9 | % Kernel size calculations for Rule of Thumb, Maximal Smoothing Principle 10 | % Assume that true density f is Gaussian (or whatever) 11 | % and find h_\infty = BW minimizing AMISE (Asymp. Mean Squared Err) 12 | % by h_\infty = (R(K)/mu2(K)/R(f^(2)))^(1/5) n^(-1/5) 13 | % where R(g) = \int g^2(x) dx 14 | % muJ(g) = \int x^J g(x) dx 15 | % g^(J) = J^th derivative of g 16 | % 17 | 18 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 19 | 20 | 21 | step = .005; 22 | x = -10:step:10; 23 | % Assume underlying distribution f is Gaussian 24 | Rf = sum( f2(x).^2 .* step ); 25 | fprintf('Reference Rf = %f\n',Rf); 26 | 27 | % Gaussian Kernel Calc: 28 | sum(Gauss(x) .* step) 29 | R = sum( Gauss(x).^2 .* step ); 30 | mu2 = sum( x.^2 .* Gauss(x) .* step ); 31 | mu4 = sum( x.^4 .* Gauss(x) .* step ); 32 | fprintf('Gauss: hROT = %f * sigma * n^(-1/5)\n',(R/mu2^2/Rf).^(1/5)); 33 | fprintf('Gauss: hMSP = %f * sigma * n^(-1/5)\n',3*(R/mu2^2/35).^(1/5)); 34 | fprintf('Gauss: R = %f mu2 = %f mu4 = %f\n',R,mu2,mu4); 35 | 36 | sum(Epanetch(x) .* step) 37 | R = sum( Epanetch(x).^2 .* step ); 38 | mu2 = sum( x.^2 .* Epanetch(x) .* step ); 39 | mu4 = sum( x.^4 .* Epanetch(x) .* step ); 40 | fprintf('Epan: hROT = %f * sigma * n^(-1/5)\n',(R/mu2^2/Rf).^(1/5)); 41 | fprintf('Epan: hMSP = %f * sigma * n^(-1/5)\n',3*(R/mu2^2/35).^(1/5)); 42 | fprintf('Epan: R = %f mu2 = %f mu4 = %f\n',R,mu2,mu4); 43 | 44 | sum(Laplace(x) .* step) 45 | R = sum( Laplace(x).^2 .* step ); 46 | mu2 = sum( x.^2 .* Laplace(x) .* step ); 47 | mu4 = sum( x.^4 .* Laplace(x) .* step ); 48 | fprintf('Laplace: hROT = %f * sigma * n^(-1/5)\n',(R/mu2^2/Rf).^(1/5)); 49 | fprintf('Laplace: hMSP = %f * sigma * n^(-1/5)\n',3*(R/mu2^2/35).^(1/5)); 50 | fprintf('Laplace: R = %f mu2 = %f mu4 = %f\n',R,mu2,mu4); 51 | 52 | 53 | function k=Laplace(x) 54 | k=1/2 * exp(-abs(x)/1); 55 | 56 | function k=Gauss(x) 57 | k=1/sqrt(2*pi) * 1/1 * exp(-.5*(x.^2)/1); 58 | 59 | function k=Epanetch(x) 60 | k=3/4 * 1/1 * (1-min(x.^2,1)); 61 | 62 | function k=f2(x) 63 | % Assume gaussian f 64 | k = Gauss(x) .* (x.^2/1^4 - 1/1^4); 65 | 66 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/ksizeHall.m: -------------------------------------------------------------------------------- 1 | function h = ksizeHall(npd) 2 | % 3 | % Find kernel size according to "plug-in" method of 4 | % Hall, Marron, Sheather, Jones (91) 5 | % 6 | % 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | x = getPoints(npd); 11 | [N1,N2] = size(x); 12 | sig = std(x,0,2); % estimate sigma (standard) 13 | lamS= .7413 * iqr(x')'; % find sigma by interquartile range lam 14 | if (max(lamS)==0) lamS=sig; end; % replace sigma est. if possible 15 | BW = 1.0592 * lamS * N2^(-1/(4+N1)); 16 | BW = repmat(BW,[1,N2]); 17 | 18 | dX = repmat(permute(x,[1,3,2]),[1,N2,1]); % compute Xi-Xj for all i,j 19 | for i=1:N2, 20 | dX(:,:,i) = (dX(:,:,i)-x)./BW; 21 | end; 22 | for i=1:N2, dX(:,i,i) = 2e22; end; 23 | dX = reshape(dX,[N1,N2*N2]); 24 | 25 | % use that to find I2 and I3 26 | I2=h_findI2(N2,dX,BW(:,1)); % I2 = \hat R( f^(2) ) = \int f^(2)^2 dx 27 | I3=h_findI3(N2,dX,BW(:,1)); % I3 = \hat R( f^(3) ) 28 | 29 | % for Gaussian Kernel, we evaluate to find: 30 | % RK = 1.0/(2^N1) * 1.0/pi^(N1/2.0); % R(K) = \int K^2(x) dx 31 | % mu2 = 1.0; % \mu_i = \int x^i K(x) dx 32 | % mu4 = 3.0^N1; 33 | switch (npd.type) 34 | case 0, RK = 0.282095; mu2 = 1.000000; mu4 = 3.000000; % Gauss 35 | case 1, RK = 0.600000; mu2 = 0.199994; mu4 = 0.085708; % Epanetch 36 | case 2, RK = 0.250002; mu2 = 1.994473; mu4 = 23.299070;% Laplace 37 | end; 38 | 39 | J1 = RK/mu2^2 .* 1./I2; 40 | J2 = (mu4 * I3) ./ (20 * mu2) .* 1./I2; 41 | h = (J1/N2).^(1.0/5) + J2.*(J1/N2).^(3.0/5); 42 | 43 | 44 | 45 | % Let us estimate R(f^(p)) by R( \hat f^(p) ) 46 | % (f is the original density to be est'd; f^(p) is its pth derivative) 47 | % Let L be the kernel function for this second estimator, with bandwidth alpha 48 | % 49 | % Ip = \int f^(p)^2_\alpha(x) dx 50 | % = [(-1)^p/n^2] \sum_i \sum_j L^(p)_\alpha * L^(p)_\alpha 51 | % = [(-1)^p/(n^2 \alpha^(2p+1))] \sum_i \sum_j (L^(p) * L^(p))( (Xi-Xj)/\alpha ) 52 | % 53 | % Take L to be a Gaussian kernel; we then evaluate L^(p) by: 54 | % 55 | % L^(p)(x) = (-1)^p H_p(x) L(x) 56 | % H_p(x) = x H_{p-1}(x) - (p-1)H_{p-2}(x) 57 | % p=2 => 58 | % H_2(x) = x H_1(x) - H_0(x) = x * x - 1 59 | % => L^(2)(x) = (x^2 - 1) * L(x) 60 | % p=3 => 61 | % H_3(x) = x H_2(x) - 2*H_1(x) = x*(x^2-1) - 2*x 62 | % => L^(3)(x) = (x^3 - 3x) * L(x) 63 | % 64 | 65 | function I2 = h_findI2(n,dXa,alpha) 66 | %% load ksizeHSJM.mat; 67 | %% xInd = fix(Nquant * (dXa-Xmin) / (Xmax-Xmin)); 68 | %% xInd = max(xInd,1); xInd = min(xInd,Nquant); 69 | %% s = sum( L2data(xInd) ,2); 70 | % s = sum( (dXa.^2 -1) .* 1/sqrt(2*pi) .* exp(-.5*dXa.^2) , 2); 71 | s = sum( (dXa.^2 -1) .* 1/sqrt(2*pi) .* repmat(exp(-.5*sum(dXa.^2,1)),[size(dXa,1),1]) , 2); 72 | I2=s./((n*(n-1))*alpha.^5); 73 | 74 | function I3 = h_findI3(n,dXb,beta) 75 | %% load ksizeHSJM.mat; 76 | %% xInd = fix(Nquant * (dXb-Xmin) / (Xmax-Xmin)); 77 | %% xInd = max(xInd,1); xInd = min(xInd,Nquant); 78 | %% s = sum( L3data(xInd) , 2); 79 | % s = sum( (dXb.^3 -3*dXb) .* 1/sqrt(2*pi) .* exp(-.5*dXb.^2) , 2); 80 | s = sum( (dXb.^3 -3*dXb) .* 1/sqrt(2*pi) .* repmat(exp(-.5*sum(dXb.^2,1)),[size(dXb,1),1]) , 2); 81 | I3 = -s./((n*(n-1))*beta.^7); 82 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/ksizeLSCV.m: -------------------------------------------------------------------------------- 1 | function h = ksizeLSCV(npd) 2 | % "Least-Squares Cross Validation" estimate (Silverman) 3 | % 4 | 5 | % Copyright (C) 2005 Alexander Ihler; distributable under GPL -- see README.txt 6 | 7 | % hROT = ksizeROT(npd); 8 | % npd = kde(getPoints(npd),hROT,getWeights(npd),getType(npd)); 9 | % h = golden(npd,@nLSCV,.1,1,30,1e-2); 10 | % h = h * hROT; 11 | 12 | [minm,maxm] = neighborMinMax(npd); 13 | npd = kde(getPoints(npd),(minm+maxm)/2,getWeights(npd),getType(npd)); 14 | h = golden(npd,@nLSCV,2*minm/(minm+maxm),1,2*maxm/(minm+maxm),1e-2); 15 | h = h * (minm+maxm)/2; 16 | 17 | function [minm,maxm] = neighborMinMax(npd) 18 | maxm = sqrt(sum( (2*npd.ranges(:,1)).^2) ); 19 | minm = min(sqrt(sum( (2*npd.ranges(:,1:npd.N-1)).^2 ,1)),[],2); 20 | minm = max(minm,1e-6); 21 | 22 | function H = nLSCV(alpha,npd) % only works for Gaussian kernels... 23 | if (nargin < 2) error('ksize: LSCV: Error! Too few arguments'); end; 24 | if (npd.type == 0) alpha = alpha.^2; end; 25 | npd.bandwidth = npd.bandwidth * 2*alpha; 26 | H = mean(evaluate(npd,npd)); % drop factor of 2 from both 27 | npd.bandwidth = npd.bandwidth / 2; 28 | H = H - mean(evaluate(npd,npd,'lvout')); 29 | npd.bandwidth = npd.bandwidth / alpha; 30 | 31 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/ksizeMSP.m: -------------------------------------------------------------------------------- 1 | function h = ksizeMSP(npd,noIQR) 2 | % "Maximal Smoothing Principle" estimate (Terrel '90) 3 | % Modified similarly to ROT for multivariate densities 4 | % Use ksizeMSP(X,1) to force use of stddev. instead of min(std,C*iqr) 5 | % (iqr = interquartile range, C*iqr = robust estimate of stddev) 6 | % 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | X = getPoints(npd); 11 | N = size(X,2); 12 | if (nargin<2) noIQR=0; end; 13 | 14 | prop = 1.06; % See ksizeCalcUseful for derivation 15 | switch(npd.type), 16 | case 0, prop = 1.143896; % Gaussian 17 | case 1, prop = 2.532394; % Epanetchnikov 18 | case 2, prop = 0.847159; % Laplacian 19 | end; 20 | 21 | sig = std(X,0,2); % estimate sigma (standard) 22 | if (noIQR) 23 | h = prop*sig*N^(-1/(4+length(sig))); 24 | else 25 | iqrSig = .7413*iqr(X')'; % find interquartile range sigma est. 26 | if (max(iqrSig)==0) iqrSig=sig; end; 27 | h = prop * min(sig,iqrSig) * N^(-1/(4+length(iqrSig))); 28 | end; 29 | 30 | % if (min(h) == 0) warning('Near-zero covariance => Kernel size set to 0'); end; 31 | 32 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/ksizeROT.m: -------------------------------------------------------------------------------- 1 | function h = ksizeROT(npd,noIQR) 2 | % "Rule of Thumb" estimate (Silverman) 3 | % Estimate is based on assumptions of Gaussian data and kernel 4 | % Actually the multivariate version in Scott ('92) 5 | % Use ksizeROT(X,1) to force use of stddev. instead of min(std,C*iqr) 6 | % (iqr = interquartile range, C*iqr = robust stddev estimate) 7 | % 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | X = getPoints(npd); 12 | N = size(X,2); dim = size(X,1); 13 | if (nargin<2) noIQR=0; end; 14 | 15 | Rg = .282095; Mg=1; % See ksizeCalcUseful for derivation 16 | Re = .6; Me = .199994; % this is the canonical kernel adjustment 17 | Rl = .25; Ml = 1.994473; % for product kernels of these types 18 | switch(npd.type), 19 | case 0, prop = 1.0; % Approximate; 1D prop = 1.059224; % Gaussian 20 | case 1, prop = ((Re/Rg)^dim / (Me/Mg)^2 )^(1/(dim+4)); % 1D prop = 2.344944; % Epanetchnikov 21 | case 2, prop = ((Rl/Rg)^dim / (Ml/Mg)^2 )^(1/(dim+4)); % 1D prop = 0.784452; % Laplacian 22 | end; 23 | 24 | sig = std(X,0,2); % estimate sigma (standard) 25 | if (noIQR) 26 | h = prop*sig*N^(-1/(4+dim)); 27 | else 28 | iqrSig = .7413*iqr(X')'; % find interquartile range sigma est. 29 | if (max(iqrSig)==0) iqrSig=sig; end; 30 | h = prop * min(sig,iqrSig) * N^(-1/(4+dim)); 31 | end; 32 | 33 | % if (min(h) == 0) warning('Near-zero covariance => Kernel size set to 0'); end; 34 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/prodSampleImportGauss.m: -------------------------------------------------------------------------------- 1 | function [ptsS, wtsS] = prodSampleImportGaussian(npds,Npts,anFns,anParams,overSamp,type) 2 | % 3 | % Gaussian-approximation-based importance sampling (private function) 4 | % 5 | % See Ihler,Sudderth,Freeman,&Willsky, "Efficient multiscale sampling from products 6 | % of Gaussian mixtures", in Proc. Neural Information Processing Systems 2003 7 | % 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | if (nargin < 6) type = 'repeat'; end; 12 | 13 | Ndim = getDim(npds{1}); NptsSamp = round(overSamp * Npts); 14 | iC = zeros(Ndim,1); iM = iC; 15 | for i=1:length(npds) 16 | iC = iC + 1./covar(npds{i}); 17 | iM = iM + mean(npds{i}) ./ covar(npds{i}); 18 | end; 19 | C = 1./iC; 20 | M = iM .* C; 21 | 22 | ptsN = randn(Ndim,NptsSamp); 23 | 24 | pts = ptsN .* repmat(sqrt(C),[1,NptsSamp]); 25 | pts = pts + repmat(M,[1,NptsSamp]); 26 | 27 | w = ones(1,NptsSamp)/NptsSamp; 28 | for i=1:length(npds) 29 | w = w .* evaluate(npds{i},pts); 30 | w = w ./ sum(w); 31 | end; 32 | w = w ./ likeli(ptsN); 33 | 34 | for i=1:length(anFns), 35 | w = w .* feval(anFns{i},pts,anParams{i}{:}); 36 | w = w / sum(w); 37 | end; 38 | 39 | w = cumsum(w); w = w/w(end); 40 | r = sort(rand(1,Npts)); 41 | j=1; i=1; k=1; 42 | 43 | %%%%%%%%%%%%%%%%%%%%%%% % return < N unique samples (vs N repeating samples) 44 | if(strcmp(type,'unique') ) 45 | ptsS = zeros(Ndim,Npts); wtsS = ones(1,Npts); 46 | i=1; k=1; while i<=Npts, %for i=1:Npts 47 | while (w(j) < r(i)) j=j+1; end; 48 | ptsS(:,k) = pts(:,j); i=i+1; 49 | while (i <= Npts && w(j) >= r(i)) 50 | i=i+1; 51 | wtsS(k)=wtsS(k)+1; 52 | end; 53 | k=k+1; 54 | end; 55 | ptsS = ptsS(:,1:k-1); wtsS = wtsS(:,1:k-1); wtsS = wtsS/sum(wtsS); 56 | %%%%%%%%%%%%%%%%%%%%%%% 57 | else 58 | ptsS = zeros(Ndim,Npts); 59 | for i=1:Npts 60 | while (w(j) < r(i)) j = j+1; end; 61 | ptsS(:,i) = pts(:,j); 62 | end; 63 | wtsS = ones(1,Npts)/Npts; 64 | end; 65 | %%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | 68 | function L = likeli(pts) % likelihood of points drawn from normal dist. 69 | L = 1/(2*pi)^(size(pts,1)/2) * exp(-sum(pts .^2,1)); 70 | L = L + .01; % otherwise we get weight problems in the tails 71 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/prodSampleImportMix.m: -------------------------------------------------------------------------------- 1 | function [ptsS, wtsS] = prodSampleImportMix(npds,Npts,anFns,anParams,overSamp,type) 2 | % 3 | % Message-based importance sampling (private function) 4 | % 5 | % See Ihler,Sudderth,Freeman,&Willsky, "Efficient multiscale sampling from products 6 | % of Gaussian mixtures", in Proc. Neural Information Processing Systems 2003 7 | % 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | if (nargin < 6) type='repeat'; end; 12 | 13 | Ndim = getDim(npds{1}); NptsSamp = round(overSamp * Npts); 14 | 15 | pts = []; wts = []; 16 | sumNpds = npds{1}; 17 | for i=2:length(npds) 18 | sumNpds = joinTrees(sumNpds,npds{i}, (i-1)/i ); 19 | end; 20 | pts = sample(sumNpds,NptsSamp); wts = evaluate(sumNpds,pts); 21 | 22 | w = ones(1,NptsSamp); 23 | for i=1:length(npds) 24 | w = w .* (evaluate(npds{i},pts)+eps); 25 | w = w/sum(w); 26 | end; 27 | w = w ./ wts; 28 | 29 | for i=1:length(anFns), 30 | w = w .* feval(anFns{i},pts,anParams{i}{:}); 31 | w = w / sum(w); 32 | end; 33 | 34 | w = cumsum(w); w = w/w(end); 35 | r = sort(rand(1,Npts)); 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Unique vs Repeating %%% 38 | if (strcmp(type,'unique')) 39 | ptsS = zeros(Ndim,Npts); wtsS = ones(1,Npts); 40 | i=1; j=1; k=1; while i<=Npts, %for i=1:Npts 41 | while (w(j) < r(i)) j=j+1; end; 42 | ptsS(:,k) = pts(:,j); i=i+1; 43 | while (i <= Npts && w(j) >= r(i)) 44 | i=i+1; 45 | wtsS(k)=wtsS(k)+1; 46 | end; 47 | k=k+1; 48 | end; 49 | ptsS = ptsS(:,1:k-1); wtsS = wtsS(:,1:k-1); wtsS = wtsS/sum(wtsS); 50 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 51 | else 52 | j=1; ptsS = zeros(Ndim,Npts); 53 | for i=1:Npts 54 | while (w(j) < r(i)) j = j+1; end; 55 | ptsS(:,i) = pts(:,j); 56 | end; 57 | wtsS = ones(1,Npts)/Npts; 58 | end; 59 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/prodSampleImportPair.m: -------------------------------------------------------------------------------- 1 | function [ptsS, wtsS] = prodSampleImportPair(npds,Npts,anFns,anParams,overSamp,type) 2 | % 3 | % Message-based importance sampling (private function) 4 | % 5 | % See Ihler,Sudderth,Freeman,&Willsky, "Efficient multiscale sampling from products 6 | % of Gaussian mixtures", in Proc. Neural Information Processing Systems 2003 7 | % 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | Ndim = getDim(npds{1}); 12 | Ndens=length(npds); 13 | if (nargin < 6) type = 'repeat'; end; 14 | 15 | if (Ndens < 2) error('Cannot use ImportancePair sampling on < 2 kdes...'); end; 16 | 17 | p=[]; pts = []; wts = []; sumNpds={}; relwt = 0; NptsSamp = round(overSamp * Npts); 18 | for i=1:Ndens 19 | for j=i+1:Ndens 20 | p = [p,prodSampleEpsilon(npds([i,j]),NptsSamp/Ndens,1e-3)]; 21 | %if (isempty(sumNpds)) sumNpds = kde(p,'rot'); 22 | %else sumNpds = joinTrees(sumNpds,kde(p,'rot'),relwt/(relwt+1)); 23 | %end; 24 | %relwt = relwt + 1; 25 | end; end; 26 | sumNpds = kde(p,'rot'); 27 | 28 | pts = sample(sumNpds,NptsSamp); 29 | wts = evaluate(sumNpds,pts); 30 | w = ones(1,overSamp*Npts); 31 | for i=1:length(npds) 32 | w = w .* evaluate(npds{i},pts); 33 | end; 34 | w = w ./ wts; 35 | 36 | for i=1:length(anFns), 37 | w = w .* feval(anFns{i},pts,anParams{i}{:}); 38 | w = w / sum(w); 39 | end; 40 | 41 | w = cumsum(w); if(w(end)~=0) w = w/w(end); end; 42 | r = sort(rand(1,Npts)); 43 | 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% Unique vs Repeating %%% 45 | if (strcmp(type,'unique')) 46 | ptsS = zeros(Ndim,Npts); wtsS = zeros(1,Npts); 47 | i=1; j=1; k=1; 48 | while i<=Npts, %for i=1:Npts 49 | while (w(j) < r(i)) j=j+1; end; 50 | ptsS(:,k) = pts(:,j); i=i+1; wtsS(k)=1; 51 | while (i <= Npts && w(j) >= r(i)) 52 | i=i+1; 53 | wtsS(k)=wtsS(k)+1; 54 | end; 55 | k=k+1; 56 | end; 57 | ptsS = ptsS(:,1:k-1); wtsS = wtsS(:,1:k-1); wtsS = wtsS/sum(wtsS); 58 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 | else 60 | j=1; ptsS = zeros(Ndim,Npts); 61 | for i=1:Npts 62 | while (w(j) < r(i)) j = j+1; end; 63 | ptsS(:,i) = pts(:,j); 64 | end; 65 | if (w(end)==0) wtsS = zeros(1,Npts); 66 | else wtsS = ones(1,Npts)/Npts; end; 67 | end; 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/randKernel.m: -------------------------------------------------------------------------------- 1 | function samples = randKernel(N,M,type) 2 | % 3 | % samples = randKernel(N,M,type) -- Draw samples from a kernel of the 4 | % given type, with bandwidth 1; for bw!=1, 5 | % eg bw=getBW(dens,ind), use B.*randKernel(N,M,type) 6 | % 7 | 8 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 9 | 10 | type = lower(type); type = type(1); 11 | switch type, 12 | case 'g', samples = randNormal(N,M); 13 | case 'l', samples = randLaplace(N,M); 14 | case 'e', samples = randEpanetch(N,M); 15 | otherwise, error('Unknown kernel type -- cannot draw samples!'); 16 | end; 17 | 18 | function samples = randLaplace(N,M) 19 | % Sample forom double-exponential 20 | % 21 | binary = rand(N,M) > .5; 22 | binary = 2*binary -1; 23 | samples = binary .* log(rand(N,M)); 24 | 25 | function samples = randNormal(N,M) 26 | % Sample from Gaussian -- built-in matlab routine 27 | % 28 | samples = randn(N,M); 29 | 30 | function samples = randEpanetch(N,M) 31 | % 32 | % Sample from Truncated Quadratic by analytic solution of CDF (a cubic) 33 | % 34 | u = rand(N,M); 35 | a2 = 0; a1=-3; a0=4*u-2; % defines the cubic 36 | Q = 1/3 * a1; % solve (assumes simple a2=0 form) 37 | R = 1/2 * (-a0); 38 | D = Q.^3 + R.^2; 39 | S = (R + sqrt(D)).^(1/3); 40 | T = (R - sqrt(D)).^(1/3); 41 | % ans1 = S + T; 42 | % ans2 = -.5*(S+T) + .5*sqrt(3)*i*(S-T); 43 | ans3 = -.5*(S+T) - .5*sqrt(3)*i*(S-T); % only this sol'n in [-1,1] (?) 44 | 45 | samples = zeros(N,M); 46 | % F= find(abs(ans1)<1); if (samples(F)~=0) fprintf('!'); end; samples(F)=ans1(F); 47 | % F= find(abs(ans2)<1); if (samples(F)~=0) fprintf('!'); end; samples(F)=ans2(F); 48 | F= find(abs(ans3)<1); if (samples(F)~=0) fprintf('!'); end; samples(F)=ans3(F); 49 | 50 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/reduceKD.m: -------------------------------------------------------------------------------- 1 | function [q,e,c]=reduceKD(p,varargin) 2 | % KD-tree based density reduction method of Ihler et al, 2004. 3 | % 4 | costType = 'kld'; maxCost = .01; 5 | costs = ones(1,2*getNpts(p)); % cost-matrix in terms of # components 6 | for i=1:length(varargin) 7 | if (isa(varargin{i},'char')), costType = varargin{i}; end; 8 | if (isa(varargin{i},'double') && numel(varargin{i})==1), maxCost = varargin{i}; end; 9 | if (isa(varargin{i},'uint32') && numel(varargin{i})==1), maxCost = varargin{i}; end; 10 | if (isa(varargin{i},'double') && numel(varargin{i})>1), costs = varargin{i}; end; 11 | end; 12 | 13 | bw = getBW(p,1); out = kde(mean(p),3*sqrt(covar(p))); outW = .99; N = getNpts(p); 14 | d=zeros(1,2*N); 15 | 16 | %%%%%%%%% Specify "Cost" in terms of # of components %%%%%%%%%%%%%%%%%%%% 17 | if (isa(maxCost,'uint32')) 18 | ind = [1]; eC=zeros(1,2*N); eC(1) = err(p,1,bw,out,outW,costType,d); 19 | done = ind; minEC = eC(1); thisEC=minEC; 20 | while (sum(costs(ind))maxCost) % compare p(below ind) to q(ind): 41 | [tmp,i] = max(eC); ind = setdiff(ind,i); eC(i) = 0; 42 | ii=double(p.leftch(i))+1; d(ii)=d(i)+1; 43 | eC(ii) = err(p,ii,bw,out,outW,costType,d); ind=[ind,ii]; 44 | ii=double(p.rightch(i))+1; d(ii)=d(i)+1; 45 | eC(ii) = err(p,ii,bw,out,outW,costType,d); ind=[ind,ii]; 46 | if (strcmp(costType,'maxlog')) thisEC = max(eC); else thisEC = sum(eC); end; 47 | if (thisEC < minEC) done = ind; minEC = thisEC; end; 48 | end; 49 | end; 50 | means = p.means(:,done); 51 | wts = p.weights(:,done); 52 | bws = p.bandwidth(:,done); 53 | c = sum(costs(done)); e = minEC; 54 | q = kde(means,sqrt(bws),wts); %q = joinTrees(q,out,outW); 55 | 56 | function eC = err(p,ii,bw,out,outW,cT,depth) 57 | pp = kde( p.means(:,1+[double(p.lower(ii)):double(p.upper(ii))]), bw); 58 | qq = kde( p.means(:,ii), sqrt(p.bandwidth(:,ii)) ); 59 | if (strcmp(cT,'maxlog')) 60 | pp = joinTrees(pp,out,outW); qq = joinTrees(qq,out,outW); 61 | end; 62 | if (strcmp(cT,'maxlog')) eC=max(abs( log(evaluate(pp,pp))-log(evaluate(qq,pp)) )); 63 | elseif (strcmp(cT,'ise')) eC = 2.^depth(ii) .* p.weights(ii).^2 .* ise(pp,qq,1e-3); 64 | elseif (strcmp(cT,'kld')) eC = p.weights(ii) .* abs(kld(pp,qq)); 65 | elseif (strcmp(cT,'L1')) eC = p.weights(ii) .* abs(L1(pp,qq)); 66 | else error('Unknown cost type...'); 67 | end; 68 | 69 | function e = L1(p,q) % simple plug-in estimate of L1-error 70 | x = getPoints(p); w = getWeights(p); 71 | e = w * abs(1-evaluate(q,x)./evaluate(p,x))'; 72 | 73 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/private/reduceKD2.m: -------------------------------------------------------------------------------- 1 | function q=reduceKD(p,maxCost,costType) 2 | if (nargin < 3) costType = 1; end; % "max" cost 3 | if (nargin < 2) maxCost = round(getNpts(p)/10); end; 4 | 5 | bw = getBW(p,1); out = kde(mean(p),3*covar(p)); outW = .999; N = getNpts(p); 6 | 7 | ind = [1]; done = []; eC=zeros(1,2*N); eC(1) = cost(p,1,bw,out,outW,costType); 8 | done = ind; minEC = eC(1); 9 | while (length(ind)0)) - log(factorial(length(find(w>0)))); 31 | 32 | function eC=errCost(p,q,p0,costType) 33 | evalLoc = discretization( [-1:.02:1],[-1:.02:1]); 34 | if (costType == 1) 35 | eC = logerr(p,q); % 36 | % eC = max(abs(log(evaluate(p,evalLoc)./evaluate(q,evalLoc)))); 37 | elseif (costType == -1) 38 | eC = kld(p,q); eC = abs(eC); 39 | % evalLoc = -1:.01:2; 40 | % pnorm = evaluate(p,evalLoc); pnorm = pnorm ./ sum(pnorm); 41 | % qnorm = evaluate(q,evalLoc); qnorm = qnorm ./ sum(qnorm); 42 | % eC = sum(pnorm.*log(pnorm./qnorm)); 43 | else 44 | pnorm = evaluate(p0,evalLoc); pnorm = pnorm ./ sum(pnorm); 45 | eC = sum(pnorm.*abs(log(evaluate(p,evalLoc)./evaluate(q,evalLoc)))); 46 | end; 47 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/productApprox.m: -------------------------------------------------------------------------------- 1 | function [dens,ind] = productApprox(npd0, npds , anFns,anParams , type, varargin) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % generate an approximate density for the product of the input densities using 4 | % MCMC approach 5 | % 6 | % productApprox(npd, {npdensities...}, {analyticFunctions...}, {analyticParams...}, 7 | % type, [options] ) 8 | % 9 | % {npdensities...} = cell array of kernel density estimates in product 10 | % type = product method, one of: 'exact', 'epsilon', 'gibbs1', 'gibbs2', ... 11 | % OPTIONS: 12 | % 'exact': no add'l arguments 13 | % 'epsilon': [,tol] -- use tolerance tol when sampling approximately 14 | % 'gibbs1': [,Niter] -- Niter iterations of sequential gibbs sampling 15 | % 'gibbs2': [,Niter] -- "" of parallel gibbs sampling 16 | % 'gibbsMS1' (or 2) [,Niter] -- Niter iters *per scale* in multiscale versions 17 | % Importance Samplers: 18 | % args: alpha = sample alpha*N times, weight, then resample 19 | % type = 'repeat' (default), 'unique' -- unique, weighted samples (< N) 20 | % 'import' [,alpha,type] -- "mixture" importance sampling 21 | % 'importG' [,alpha,type] -- "gaussian" importance sampling 22 | % 'importPair' [...] -- use sum of epsilon products of all pairs as proposal 23 | % 'importNoAn' [...] -- "mixture" importance sampling, but resampling BEFORE 24 | % analytic function evaluation (for costly anFns) 25 | % 26 | % {analyticFns...} = cell array of analytic functions in product 27 | % {analyticPar...} = cell array of parameters for above functions 28 | % each should take [Nd x Np] array and evaluate it at each [Nd x 1] location 29 | % 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | % 32 | % See Ihler,Sudderth,Freeman,&Willsky, "Efficient multiscale sampling from products 33 | % of Gaussian mixtures", in Proc. Neural Information Processing Systems 2003 34 | % 35 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 | 37 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 38 | 39 | for i=1:length(npds) 40 | if (npds{i}.type ~= 0) error('Sorry! Product only works for Gaussian densities.'); end; 41 | end; 42 | 43 | % if there's only one density, don't bother with the complex stuff: 44 | if (length(npds) == 1) 45 | dens = resample(npds{1},getNpts(npd0),'rot'); ind=[]; 46 | p = getPoints(dens); w = getWeights(dens); 47 | for i=1:length(anFns), 48 | w = w .* feval(anFns{i},p,anParams{i}{:}); 49 | w = w / sum(w); 50 | end; 51 | dens = kde(p, 'rot', w); 52 | 53 | % Otherwise, lots of ways to take the product: 54 | else 55 | w = ones(1,getNpts(npd0)); 56 | switch(lower(type)) 57 | case 'exact', [p,ind] = prodSampleExact(npds,getNpts(npd0)); 58 | case 'epsilon', [p,ind] = prodSampleEpsilon(npds,getNpts(npd0),varargin{:}); 59 | case 'gibbs1', [p,ind] = prodSampleGibbs1(npds,getNpts(npd0),varargin{:}); 60 | case 'gibbs2', [p,ind] = prodSampleGibbs2(npds,getNpts(npd0),varargin{:}); 61 | case 'gibbsms1',[p,ind] = prodSampleGibbsMS1(npds,getNpts(npd0),varargin{:}); 62 | case 'gibbsms2',[p,ind] = prodSampleGibbsMS2(npds,getNpts(npd0),varargin{:}); 63 | case 'import', [p,w] = prodSampleImportMix(npds,getNpts(npd0),anFns,anParams,varargin{:}); 64 | case 'importg', [p,w] = prodSampleImportGauss(npds,getNpts(npd0),anFns,anParams,varargin{:}); 65 | case 'importpair',[p,w]=prodSampleImportPair(npds,getNpts(npd0),anFns,anParams,varargin{:}); 66 | case 'importnoan',[p,w] = prodSampleImportMix(npds,getNpts(npd0),{},{},varargin{:}); 67 | otherwise, error('Unknown product type %s',type); 68 | end; 69 | 70 | switch(lower(type)) 71 | case {'import','importg','importpair'} 72 | if ( 1/sum(w.^2)<.02*getNpts(npd0) || max(w)==0 ) 73 | warning('KDE:importFail','Importance sampling failed. Generating samples with GibbsMS...'); 74 | [p,ind] = prodSampleGibbsMS1(npds,getNpts(npd0),5); % quick & dirty fix 75 | w = ones(1,getNpts(npd0)); 76 | for i=1:length(anFns), w=w.*feval(anFns{i},p,anParams{i}{:});w=w/sum(w);end; 77 | end; 78 | otherwise 79 | for i=1:length(anFns), 80 | w = w .* feval(anFns{i},p,anParams{i}{:}); 81 | w = w / sum(w); 82 | end; 83 | end; 84 | dens = kde(p, 'rot', w); 85 | end; 86 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/productExact.m: -------------------------------------------------------------------------------- 1 | function dens = productExact(npd_placeholder, npdensities , analyticFns, analyticParams) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % productExact(kde,{kdes} [,{analyticFns},{analyticParams}]); 4 | % generate the exact density for the product of the input densities 5 | % this produces an N1xN2xN3x... particle density 6 | % 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | for i=1:length(npdensities) 12 | if (npdensities{i}.type ~= 0) error('Sorry! Product only works for Gaussian densities.'); end; 13 | end; 14 | 15 | Ndens = length(npdensities); Ndim = getDim(npd_placeholder); Nfns = length(analyticFns); 16 | Np = getNpts(npd_placeholder); % this is supposed to be how many particles to 17 | % approximate with 18 | Npts = zeros(Ndens,1); ind = ones(Ndens,1); totalInd = 1; 19 | for i=1:Ndens, Npts(i) = getNpts(npdensities{i}); end; 20 | 21 | REPEAT = 1; % do for exponentially many product particles 22 | while (REPEAT), % (all combos of input indices) 23 | 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | % ind' % do what we want with these indices 26 | for i=1:Ndens, % Get locations & variance (brute force, lots of repetition) 27 | particles(:,i) = getPoints(npdensities{i},ind(i)); 28 | variance(:,i) = getBW(npdensities{i},ind(i)).^2; 29 | end; 30 | 31 | iC = sum(1./variance,2); % calculate variance and mean of 32 | iM = sum(particles./variance,2); % the product from this index set 33 | C = 1./iC; 34 | M = C .* iM; 35 | m(:,totalInd) = M; % & save them 36 | c(:,totalInd) = C; 37 | 38 | p(totalInd) = 1; 39 | for i=1:Ndens, % Get weight for this combo (again brute force, wasteful) 40 | p(totalInd) = p(totalInd) * getWeights(npdensities{i},ind(i)); 41 | p(totalInd) = p(totalInd) / (2*pi)^(Ndim/2) / sqrt(prod(variance(:,i))); 42 | p(totalInd) = p(totalInd) * exp(-.5*sum((particles(:,i)-M).^2 ./ variance(:,i))); 43 | end; 44 | p(totalInd) = p(totalInd) * (2*pi)^(Ndim/2) * sqrt(prod(C)); 45 | for k=1:Nfns % Evaluate analytic functions here too 46 | pF = feval(analyticFns{k},M,analyticParams{k}{:}); 47 | p(totalInd) = pF .* p(totalInd); 48 | end; 49 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 | 51 | if (sum(ind) == sum(Npts)), REPEAT =0; end; % check for end of loop condition 52 | 53 | ind(end) = ind(end)+1; % otherwise advance the two counters 54 | totalInd = totalInd + 1; 55 | for i=Ndens:-1:2 % and check for wrapping in the 56 | if (ind(i)>Npts(i)), % index counters 57 | ind(i)=1; ind(i-1)=ind(i-1)+1; 58 | else 59 | break; 60 | end; end; 61 | end; 62 | p = p ./ sum(p); % normalize the weights 63 | dens = kde(m,sqrt(c),p); % and you've got a KDE 64 | 65 | 66 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/quantize.m: -------------------------------------------------------------------------------- 1 | function p = quantize(p,R,minV,maxV,minS,maxS) 2 | % 3 | % p = quantize(p,R,type) -- "quantize" elements of KDE p to R bits 4 | % 5 | 6 | %p.centers = round(1000*p.centers)/1000; 7 | %p.means = round(1000*p.means)/1000; 8 | %p.ranges = round(1000*p.ranges)/1000; 9 | %p.bandwidth = ceil(10000*p.bandwidth)/10000; 10 | 11 | p.centers = roundVals(p.centers ,minV,maxV,R); 12 | p.means = roundVals(p.means ,minV,maxV,R); 13 | p.ranges = roundVals(p.ranges ,minV,maxV,R); 14 | p.bandwidth = roundVals(p.bandwidth,minS,maxS,R); 15 | 16 | 17 | function x = roundVals(x,minV,maxV,R) 18 | scale = 2^R ./ repmat(maxV-minV,size(x)./size(maxV)); 19 | minV = repmat(minV,size(x)./size(minV)); x = x - minV; x = max(x,0); 20 | x = x .* scale; x = min(round(x),2^R-1); x = x./scale; x = x + minV; 21 | 22 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/resample.m: -------------------------------------------------------------------------------- 1 | function p2 = resample(p,Np,ksType) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % resample(p,Np,KSType) -- construct a new estimate of the KDE p by sampling 5 | % Np new points; determines a bandwidth by ksize(pNew,KSType) 6 | % NOTE: KStype = 'discrete' resamples points by weight & 7 | % preserves original kernel size 8 | % see also: kde, ksize 9 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10 | 11 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 12 | 13 | if (nargin < 3) ksType = 'rot'; end; 14 | if (nargin < 2) Np = getNpts(p); end; 15 | if (strcmp(ksType,'discrete')) 16 | q = kde(getPoints(p),zeros(getDim(p),1),getWeights(p)); 17 | [samplePts,ind] = sample(q,Np); 18 | if (size(p.bandwidth,2)>2*p.N), ks = getBW(p,ind); 19 | else ks = getBW(p,1); end; 20 | p2 = kde(samplePts,ks); 21 | else 22 | samplePts = sample(p,Np); 23 | p2 = kde(samplePts,ksType); 24 | end; 25 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/rescale.m: -------------------------------------------------------------------------------- 1 | function npd = rescale(npd,factor) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % rescale(P, factor) -- Rescales the KDE "P" proportionally by 5 | % "factor" (a column-vector) 6 | % 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | N = npd.N; 12 | npd.centers = npd.centers .* repmat(factor,[1,2*N]); 13 | npd.ranges = npd.ranges .* max(factor); % to be safe 14 | npd.means = npd.means .* repmat(factor,[1,2*N]); 15 | npd.bandwidth = npd.bandwidth .* repmat(factor.^2,size(npd.bandwidth)./size(factor)); 16 | -------------------------------------------------------------------------------- /render_pipeline/kde/matlab_kde_package/sample.m: -------------------------------------------------------------------------------- 1 | function [points,ind] = sample(npd,Npts,ind) 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 | % 4 | % [pts,ind] = sample(kde,Npts) -- sample Npts new points from a kde 5 | % ,ind) -- take the samples from the given indices 6 | % 7 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8 | 9 | % Copyright (C) 2003 Alexander Ihler; distributable under GPL -- see README.txt 10 | 11 | pts = getPoints(npd); 12 | if (nargin < 3) 13 | points = zeros(getDim(npd),Npts); ind = zeros(1,Npts); 14 | bw = getBW(npd); 15 | w = getWeights(npd); w = cumsum(w); w = w/w(end); 16 | randnums = randKernel(getDim(npd),Npts,getType(npd)); 17 | t = [sort(rand(1,Npts)),10]; 18 | 19 | ii = 1; 20 | for i=1:size(pts,2) 21 | while (w(i) > t(ii)) 22 | points(:,ii) = pts(:,i) + bw(:,i).*randnums(:,ii); 23 | ind(ii) = i; 24 | ii = ii + 1; 25 | end; 26 | end; 27 | else 28 | points = pts(:,ind) + getBW(npd,ind).*randKernel(getDim(npd),length(ind),getType(npd)); 29 | end; 30 | -------------------------------------------------------------------------------- /render_pipeline/kde/run_sampling.m: -------------------------------------------------------------------------------- 1 | % Generate view samples for PASCAL3D classes 2 | close all; clear; 3 | 4 | setup_path; 5 | visualize = 0; 6 | 7 | clsList = {'aeroplane', 'bicycle', 'boat', 'bottle', 'bus', 'car', 'chair', 'diningtable', 'motorbike', 'sofa', 'train', 'tvmonitor'}; 8 | 9 | 10 | %% Collect real image statistics 11 | for k = 1:length(clsList) 12 | get_voc12train_view_stats(clsList{k}); 13 | get_voc12train_truncation_stats(clsList{k}); 14 | end 15 | 16 | %% Visualize real image sample statistics 17 | azimuths_all = []; 18 | elevations_all = []; 19 | distances_all = []; 20 | tilts_all = []; 21 | left_all = []; 22 | right_all = []; 23 | top_all = []; 24 | bottom_all = []; 25 | for k = 1:length(clsList) 26 | cls = clsList{k}; 27 | load(fullfile(g_view_statistics_folder, sprintf('%s_viewpoint_stats.mat', cls))); 28 | azimuths_all = [azimuths_all azimuths]; 29 | elevations_all = [elevations_all, elevations]; 30 | distances_all = [distances_all distances]; 31 | tilts_all = [tilts_all tilts]; 32 | if visualize 33 | figure, 34 | subplot(2,2,1), hist(azimuths), title([cls ' azimuth']); 35 | subplot(2,2,2), hist(elevations), title([cls ' elevation']); 36 | subplot(2,2,3), hist(tilts), title([cls ' tilt']); 37 | subplot(2,2,4), hist(distances), title([cls ' distance']); 38 | end 39 | load(fullfile(g_truncation_statistics_folder, sprintf('%s_truncation_stats.mat', cls))); 40 | left_all = [left_all, left']; 41 | right_all = [right_all, right']; 42 | top_all = [top_all, top']; 43 | bottom_all = [bottom_all, bottom']; 44 | 45 | if visualize 46 | figure, 47 | subplot(2,2,1), hist(left), title([cls ' left']); 48 | subplot(2,2,2), hist(right), title([cls ' right']); 49 | subplot(2,2,3), hist(top), title([cls ' top']); 50 | subplot(2,2,4), hist(bottom), title([cls ' bottom']); 51 | end 52 | end 53 | 54 | if visualize 55 | figure, 56 | subplot(2,2,1), hist(azimuths_all,32), title('all azimuth'); 57 | subplot(2,2,2), hist(elevations_all,32), title('all elevation'); 58 | subplot(2,2,3), hist(tilts_all,32), title('all tilt'); 59 | subplot(2,2,4), hist(distances_all,32), title('all distance'); 60 | 61 | figure, 62 | subplot(2,2,1), hist(left_all,32), title('left all'); 63 | subplot(2,2,2), hist(right_all,32), title('right all'); 64 | subplot(2,2,3), hist(top_all,32), title('top all'); 65 | subplot(2,2,4), hist(bottom_all,32), title('bottom all'); 66 | end 67 | 68 | %% KDE on real image samples and Generate samples from estimated distributions 69 | tilt_avg = mean(tilts_all); 70 | tilt_std = 20; 71 | elevation_avg = mean(elevations_all); 72 | elevation_std = 20; 73 | num_samples = 10^6; 74 | outlier_ratio = 0.2; 75 | 76 | for k = 1:length(clsList) 77 | cls = clsList{k}; 78 | sample_viewpoints(cls, num_samples, outlier_ratio, elevation_avg, elevation_std, tilt_avg, tilt_std); 79 | sample_truncations(cls, num_samples, outlier_ratio); 80 | end 81 | 82 | -------------------------------------------------------------------------------- /render_pipeline/kde/sample_truncations.m: -------------------------------------------------------------------------------- 1 | function sample_truncations(cls, num_samples, outlier_ratio) 2 | 3 | setup_path; 4 | load(fullfile(g_truncation_statistics_folder, sprintf('%s_truncation_stats.mat', cls))); 5 | 6 | targetSamples_left_right = [left, right]; 7 | targetSamples_top_bottom = [top, bottom]; 8 | bandwidth_left_right = 1.06 * std(targetSamples_left_right) * (size(targetSamples_left_right, 1)^(-0.2)); 9 | bandwidth_top_bottom = 1.06 * std(targetSamples_top_bottom) * (size(targetSamples_top_bottom, 1)^(-0.2)); 10 | 11 | addpath(g_matlab_kde_folder); 12 | p_left_right = kde(targetSamples_left_right', bandwidth_left_right'); 13 | p_top_bottom = kde(targetSamples_top_bottom', bandwidth_top_bottom'); 14 | newSamples_left_right = sample(p_left_right, num_samples); 15 | newSamples_top_bottom = sample(p_top_bottom, num_samples); 16 | rmpath(g_matlab_kde_folder); 17 | 18 | % left, right, top, bottom. 19 | % set up/low-bound for truncations 20 | goodSamples = [newSamples_left_right; newSamples_top_bottom]'; 21 | filt = goodSamples(:,2) - goodSamples(:,1) > 1; % too truncated 22 | goodSamples(filt, [1,2]) = min(max(normrnd(0, 0.1, sum(filt), 2),-0.5), 0.5); 23 | filt = goodSamples(:,4) - goodSamples(:,3) > 1; % too truncated 24 | goodSamples(filt, [3,4]) = min(max(normrnd(0, 0.1, sum(filt), 2),-0.5), 0.5); 25 | 26 | % add some outliers 27 | rp = randperm(num_samples); 28 | numRandPerturbation = int32(num_samples*outlier_ratio); 29 | rp = rp(1:numRandPerturbation); 30 | goodSamples(rp, :) = min(max(normrnd(0, 0.1, numRandPerturbation, 4),-0.5), 0.5); 31 | 32 | figure, 33 | subplot(2,2,1), histogram(goodSamples(:,1), 32, 'Normalization', 'probability'), title([cls ' left shift ratio']); 34 | subplot(2,2,2), histogram(goodSamples(:,2), 32,'Normalization', 'probability'), title([cls ' right shift ratio']); 35 | subplot(2,2,3), histogram(goodSamples(:,3), 32,'Normalization', 'probability'), title([cls ' top shift ratio']); 36 | subplot(2,2,4), histogram(goodSamples(:,4), 32,'Normalization', 'probability'), title([cls ' bottom shift ratio']); 37 | 38 | mkdir(g_truncation_distribution_folder); 39 | dlmwrite(fullfile(g_truncation_distribution_folder, sprintf('%s.txt', cls)), goodSamples, 'delimiter', ' ', 'precision', 6); -------------------------------------------------------------------------------- /render_pipeline/kde/sample_viewpoints.m: -------------------------------------------------------------------------------- 1 | function sample_viewpoints(cls, num_samples, outlier_ratio, outlier_elevation_avg, outlier_elevation_std, outlier_tilt_avg, outlier_tilt_std) 2 | 3 | setup_path; 4 | 5 | load(fullfile(g_view_statistics_folder, sprintf('%s_viewpoint_stats.mat', cls))); 6 | invalidSamples = find(distances == 0); 7 | 8 | azimuths(invalidSamples) = []; 9 | elevations(invalidSamples) = []; 10 | tilts(invalidSamples) = []; 11 | distances(invalidSamples) = []; 12 | 13 | ha = hist(azimuths, linspace(min(azimuths), max(azimuths)+1e-5, 51)); 14 | arange = linspace(min(azimuths), max(azimuths)+1e-5, 51); 15 | ha(end) = []; 16 | 17 | he = histc(elevations, linspace(min(elevations), max(elevations)+1e-5, 51)); 18 | erange = linspace(min(elevations), max(elevations)+1e-5, 51); 19 | he(end) = []; 20 | 21 | ht = histc(tilts, linspace(min(tilts), max(tilts)+1e-5, 51)); 22 | trange = linspace(min(tilts), max(tilts)+1e-5, 51); 23 | ht(end) = []; 24 | 25 | ha = ha / sum(ha); 26 | he = he / sum(he); 27 | ht = ht / sum(ht); 28 | 29 | % calibrate distance by a factor of 3, because estimated distances 30 | % from pascal3d annotations are over-estimated. 31 | targetSamples = [azimuths', elevations', tilts', distances'/3]; 32 | bandwidth = 1.06 * std(targetSamples) * (size(targetSamples, 1)^(-0.2)); 33 | 34 | addpath(g_matlab_kde_folder); 35 | p = kde(targetSamples', bandwidth'); 36 | newSamples = sample(p, num_samples); 37 | rmpath(g_matlab_kde_folder); 38 | 39 | goodSamples = newSamples'; 40 | goodSamples(:, 1) = mod(goodSamples(:, 1), 360); 41 | goodSamples(:, 2) = mod(goodSamples(:, 2)+90, 180)-90; 42 | goodSamples(:, 3) = mod(goodSamples(:, 3)+90, 180)-90; 43 | 44 | distance_min = 1; 45 | distance_max = 29; 46 | filt = goodSamples(:, 4) > distance_max | goodSamples(:, 4) < distance_min; 47 | goodSamples(filt, 4) = datasample(goodSamples(~filt,4), sum(filt)) + 1*rand(sum(filt),1); 48 | 49 | % goodSamples(:, 4) = max([goodSamples(:, 4), min(distances) * ones(num_samples, 1)], [], 2); 50 | % goodSamples(:, 4) = min([goodSamples(:, 4), max(distances) * ones(num_samples, 1)], [], 2); 51 | 52 | % add some outliers 53 | rp = randperm(num_samples); 54 | numRandPerturbation = int32(num_samples*outlier_ratio); 55 | rp = rp(1:numRandPerturbation); 56 | 57 | randAzimuth = rand(numRandPerturbation, 1) * 360; 58 | randElevation = max(min(normrnd(outlier_elevation_avg, outlier_elevation_std, numRandPerturbation, 1), 85),-85); 59 | randTilt = max(min(normrnd(outlier_tilt_avg, outlier_tilt_std, numRandPerturbation, 1), 45),-45); 60 | 61 | goodSamples(rp, 1) = randAzimuth; 62 | goodSamples(rp, 2) = randElevation; 63 | goodSamples(rp, 3) = randTilt; 64 | 65 | 66 | figure, 67 | subplot(2,2,1), histogram(goodSamples(:,1), 32, 'Normalization', 'probability'), title([cls ' azimuth']); 68 | subplot(2,2,2), histogram(goodSamples(:,2), 32,'Normalization', 'probability'), title([cls ' elevation']); 69 | subplot(2,2,3), histogram(goodSamples(:,3), 32,'Normalization', 'probability'), title([cls ' tilt']); 70 | subplot(2,2,4), histogram(goodSamples(:,4), 32,'Normalization', 'probability'), title([cls ' distance']); 71 | 72 | mkdir(g_view_distribution_folder); 73 | dlmwrite(fullfile(g_view_distribution_folder, sprintf('%s.txt', cls)), goodSamples, 'delimiter', ' ', 'precision', 6); 74 | -------------------------------------------------------------------------------- /render_pipeline/kde/setup_path.m: -------------------------------------------------------------------------------- 1 | % add paths 2 | RENDER4CNN_ROOT = fullfile(mfilename('fullpath'),'../../../'); 3 | PASCAL3D_DIR = fullfile(RENDER4CNN_ROOT, 'datasets/pascal3d/'); 4 | addpath(fullfile(PASCAL3D_DIR, 'VDPM')); 5 | addpath(fullfile(PASCAL3D_DIR, 'Annotation_tools')); 6 | addpath(RENDER4CNN_ROOT); 7 | global_variables; 8 | 9 | % initialize the PASCAL development kit 10 | tmp = pwd; 11 | cd(fullfile(PASCAL3D_DIR, 'PASCAL/VOCdevkit')); 12 | addpath([cd '/VOCcode']); 13 | VOCinit; 14 | cd(tmp); -------------------------------------------------------------------------------- /render_pipeline/overlay_background.m: -------------------------------------------------------------------------------- 1 | function overlay_background(src_folder, dst_folder, bkgFilelist, bkgFolder, clutteredBkgRatio, single_thread) 2 | 3 | if nargin < 6 4 | single_thread = 0; 5 | end 6 | if single_thread 7 | num_workers = 0; 8 | else 9 | num_workers = 24; 10 | end 11 | 12 | image_files = rdir(fullfile(src_folder,'*/*.png')); 13 | image_num = length(image_files); 14 | fprintf('%d images in total.\n', image_num); 15 | if image_num == 0 16 | return; 17 | end 18 | sunImageList = importdata(bkgFilelist); 19 | rng('shuffle'); 20 | 21 | fprintf('Start overlaying images at time %s, it takes for a while...\n', datestr(now, 'HH:MM:SS')); 22 | report_num = 80; 23 | fprintf([repmat('.',1,report_num) '\n\n']); 24 | report_step = floor((image_num+report_num-1)/report_num); 25 | t_begin = clock; 26 | %for i = 1:image_num 27 | parfor(i = 1:image_num, num_workers) 28 | src_image_file = image_files(i).name; 29 | try 30 | [I, ~, alpha] = imread(src_image_file); 31 | catch 32 | fprintf('Failed to read %s\n', src_image_file); 33 | end 34 | 35 | s = size(I); 36 | fh = s(1); fw = s(2); 37 | mask = double(alpha) / 255; 38 | mask = repmat(mask,1,1,3); 39 | 40 | if rand() > clutteredBkgRatio 41 | I = uint8(double(I) .* mask + double(rand()*255) * (1 - mask)); 42 | else 43 | while true 44 | id = randi(length(sunImageList)); 45 | bg = imread(fullfile(bkgFolder, sunImageList{id})); 46 | s = size(bg); 47 | bh = s(1); bw = s(2); 48 | if bh < fh || bw < fw 49 | %fprintf(1, '.'); 50 | continue; 51 | end 52 | if length(s) < 3 53 | continue; 54 | end 55 | break; 56 | end 57 | by = randi(bh - fh + 1); 58 | bx = randi(bw - fw + 1); 59 | bgcrop = bg(by:(by+fh-1), bx:(bx+fw-1), :); 60 | 61 | I = uint8(double(I) .* mask + double(bgcrop) .* (1 - mask)); 62 | end 63 | 64 | if numel(I) == 0 65 | fprintf('Failed to overlay %s (empty image after crop)\n', src_image_file); 66 | else 67 | dst_image_file = strrep(src_image_file, src_folder, dst_folder); 68 | dst_image_file = strrep(dst_image_file, '.png', '.jpg'); 69 | [dst_image_file_folder, ~, ~] = fileparts(dst_image_file); 70 | if ~exist(dst_image_file_folder, 'dir') 71 | mkdir(dst_image_file_folder); 72 | end 73 | %imwrite(I, dst_image_file, 'png', 'Alpha', alpha); 74 | imwrite(I, dst_image_file, 'jpg'); 75 | end 76 | 77 | if mod(i, report_step) == 0 78 | fprintf('\b|\n'); 79 | end 80 | end 81 | t_end = clock; 82 | fprintf('%f seconds spent on background overlay!\n', etime(t_end, t_begin)); 83 | -------------------------------------------------------------------------------- /render_pipeline/render_helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import shutil 7 | import random 8 | import tempfile 9 | import datetime 10 | from functools import partial 11 | from multiprocessing.dummy import Pool 12 | from subprocess import call 13 | 14 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 15 | sys.path.append(os.path.dirname(BASE_DIR)) 16 | from global_variables import * 17 | 18 | 19 | ''' 20 | @input: 21 | shape_synset e.g. '03001627' (each category has a synset) 22 | @output: 23 | a list of (synset, md5, obj_filename, view_num) for each shape of that synset category 24 | where synset is the input synset, md5 is md5 of one shape in the synset category, 25 | obj_filename is the obj file of the shape, view_num is the number of images to render for that shape 26 | ''' 27 | def load_one_category_shape_list(shape_synset): 28 | # return a list of (synset, md5, numofviews) tuples 29 | shape_md5_list = os.listdir(os.path.join(g_shapenet_root_folder,shape_synset)) 30 | view_num = g_syn_images_num_per_category / len(shape_md5_list) 31 | shape_list = [(shape_synset, shape_md5, os.path.join(g_shapenet_root_folder, shape_synset, shape_md5, 'model.obj'), view_num) for shape_md5 in shape_md5_list] 32 | return shape_list 33 | 34 | ''' 35 | @input: 36 | shape synset 37 | @output: 38 | samples of viewpoints (plus distances) from pre-generated file, each element of view_params is 39 | a list of azimuth,elevation,tilt angles and distance 40 | ''' 41 | def load_one_category_shape_views(synset): 42 | # return shape_synset_view_params 43 | if not os.path.exists(g_view_distribution_files[synset]): 44 | print('Failed to read view distribution files from %s for synset %s' % 45 | (g_view_distribution_files[synset], synset)) 46 | exit() 47 | view_params = open(g_view_distribution_files[synset]).readlines() 48 | view_params = [[float(x) for x in line.strip().split(' ')] for line in view_params] 49 | return view_params 50 | 51 | ''' 52 | @input: 53 | shape_list and view_params as output of load_one_category_shape_list/views 54 | @output: 55 | save rendered images to g_syn_images_folder///xxx.png 56 | ''' 57 | def render_one_category_model_views(shape_list, view_params): 58 | tmp_dirname = tempfile.mkdtemp(dir=g_data_folder, prefix='tmp_view_') 59 | if not os.path.exists(tmp_dirname): 60 | os.mkdir(tmp_dirname) 61 | 62 | print('Generating rendering commands...') 63 | commands = [] 64 | for shape_synset, shape_md5, shape_file, view_num in shape_list: 65 | # write tmp view file 66 | tmp = tempfile.NamedTemporaryFile(dir=tmp_dirname, delete=False) 67 | for i in range(view_num): 68 | paramId = random.randint(0, len(view_params)-1) 69 | tmp_string = '%f %f %f %f\n' % (view_params[paramId][0], view_params[paramId][1], view_params[paramId][2], max(0.01,view_params[paramId][3])) 70 | tmp.write(tmp_string) 71 | tmp.close() 72 | 73 | command = '%s %s --background --python %s -- %s %s %s %s %s > /dev/null 2>&1' % (g_blender_executable_path, g_blank_blend_file_path, os.path.join(BASE_DIR, 'render_model_views.py'), shape_file, shape_synset, shape_md5, tmp.name, os.path.join(g_syn_images_folder, shape_synset, shape_md5)) 74 | commands.append(command) 75 | print('done (%d commands)!'%(len(commands))) 76 | print commands[0] 77 | 78 | print('Rendering, it takes long time...') 79 | report_step = 100 80 | if not os.path.exists(os.path.join(g_syn_images_folder, shape_synset)): 81 | os.mkdir(os.path.join(g_syn_images_folder, shape_synset)) 82 | pool = Pool(g_syn_rendering_thread_num) 83 | for idx, return_code in enumerate(pool.imap(partial(call, shell=True), commands)): 84 | if idx % report_step == 0: 85 | print('[%s] Rendering command %d of %d' % (datetime.datetime.now().time(), idx, len(shape_list))) 86 | if return_code != 0: 87 | print('Rendering command %d of %d (\"%s\") failed' % (idx, len(shape_list), commands[idx])) 88 | shutil.rmtree(tmp_dirname) 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /render_pipeline/run_crop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | ''' 4 | CROP_ALL_IMAGES 5 | @brief: 6 | crop all rendered images of PASCAL3D 12 rigid object classes 7 | ''' 8 | 9 | import os 10 | import sys 11 | import socket 12 | 13 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 14 | sys.path.append(BASE_DIR) 15 | sys.path.append(os.path.dirname(BASE_DIR)) 16 | from global_variables import * 17 | 18 | if __name__ == '__main__': 19 | if not os.path.exists(g_syn_images_cropped_folder): 20 | os.mkdir(g_syn_images_cropped_folder) 21 | 22 | for idx in g_crop_hostname_synset_idx_map[socket.gethostname()]: 23 | synset = g_shape_synsets[idx] 24 | name = g_shape_names[idx] 25 | print('%d: %s, %s\n' % (idx, synset, name)) 26 | matlab_cmd = "addpath('%s'); crop_images('%s','%s','%s');" % (BASE_DIR, os.path.join(g_syn_images_folder, synset), os.path.join(g_syn_images_cropped_folder, synset), os.path.join(g_truncation_distribution_folder, name+'.txt')) 27 | print matlab_cmd 28 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;"' % (g_matlab_executable_path, matlab_cmd)) 29 | -------------------------------------------------------------------------------- /render_pipeline/run_overlay.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | ''' 4 | BACKGROUND OVERLAY 5 | @brief: 6 | overlay backgrounds to images of PASCAL3D 12 rigid object classes 7 | ''' 8 | 9 | import os 10 | import sys 11 | import socket 12 | 13 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 14 | sys.path.append(BASE_DIR) 15 | sys.path.append(os.path.dirname(BASE_DIR)) 16 | from global_variables import * 17 | 18 | if __name__ == '__main__': 19 | if not os.path.exists(g_syn_images_bkg_overlaid_folder): 20 | os.mkdir(g_syn_images_bkg_overlaid_folder) 21 | 22 | for idx in g_overlay_hostname_synset_idx_map[socket.gethostname()]: 23 | synset = g_shape_synsets[idx] 24 | print('%d: %s, %s\n' % (idx, synset, g_shape_names[idx])) 25 | matlab_cmd = "addpath('%s'); overlay_background('%s','%s','%s', '%s', %f);" % (BASE_DIR, os.path.join(g_syn_images_cropped_folder, synset), os.path.join(g_syn_images_bkg_overlaid_folder, synset), g_syn_bkg_filelist, g_syn_bkg_folder, g_syn_cluttered_bkg_ratio) 26 | print matlab_cmd 27 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;"' % (g_matlab_executable_path, matlab_cmd)) 28 | -------------------------------------------------------------------------------- /render_pipeline/run_render.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | ''' 4 | RENDER_ALL_SHAPES 5 | @brief: 6 | render all shapes of PASCAL3D 12 rigid object classes 7 | ''' 8 | 9 | import os 10 | import sys 11 | import socket 12 | 13 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 14 | sys.path.append(BASE_DIR) 15 | sys.path.append(os.path.dirname(BASE_DIR)) 16 | from global_variables import * 17 | from render_helper import * 18 | 19 | if __name__ == '__main__': 20 | if not os.path.exists(g_syn_images_folder): 21 | os.mkdir(g_syn_images_folder) 22 | 23 | for idx in g_hostname_synset_idx_map[socket.gethostname()]: 24 | synset = g_shape_synsets[idx] 25 | print('%d: %s, %s\n' % (idx, synset, g_shape_names[idx])) 26 | shape_list = load_one_category_shape_list(synset) 27 | view_params = load_one_category_shape_views(synset) 28 | render_one_category_model_views(shape_list, view_params) 29 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from global_variables import * 3 | 4 | # matlab global variable file 5 | mf = open(os.path.join(g_render4cnn_root_folder, 'global_variables.m'), 'w') 6 | 7 | mf.write("g_matlab_kde_folder = '%s';\n" % (g_matlab_kde_folder)) 8 | mf.write("g_view_statistics_folder = '%s';\n" % (g_view_statistics_folder)) 9 | mf.write("g_view_distribution_folder = '%s';\n" % (g_view_distribution_folder)) 10 | mf.write("g_truncation_statistics_folder = '%s';\n" % (g_truncation_statistics_folder)) 11 | mf.write("g_truncation_distribution_folder = '%s';\n" % (g_truncation_distribution_folder)) 12 | 13 | mf.write("g_pascal3d_root_folder = '%s';\n" % (g_pascal3d_root_folder)) 14 | 15 | mf.write("g_cls_names = {'aeroplane','bicycle','boat','bottle','bus','car','chair','diningtable','motorbike','sofa','train','tvmonitor'};\n") 16 | mf.write("g_detection_results_folder = '%s';\n" % (g_detection_results_folder)) 17 | -------------------------------------------------------------------------------- /train/imagenet_mean.binaryproto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShapeNet/RenderForCNN/c0bee04aad3dc2f0ae5de71daf6d51664ce02e76/train/imagenet_mean.binaryproto -------------------------------------------------------------------------------- /train/solver.prototxt.example: -------------------------------------------------------------------------------- 1 | net: "train_val.prototxt" 2 | test_iter: 100 3 | test_interval: 1000 4 | base_lr: 0.001 5 | lr_policy: "step" 6 | gamma: 0.1 7 | stepsize: 20000 8 | display: 20 9 | max_iter: 80000 10 | momentum: 0.9 11 | weight_decay: 0.0005 12 | snapshot: 5000 13 | snapshot_prefix: "snapshots" 14 | solver_mode: GPU 15 | -------------------------------------------------------------------------------- /view_estimation/.gitignore: -------------------------------------------------------------------------------- 1 | avp_test_results* 2 | vp_test_results* 3 | -------------------------------------------------------------------------------- /view_estimation/README.md: -------------------------------------------------------------------------------- 1 | Render for CNN: viewpoint estimator 2 | 3 | To prepare testing images, run: 4 | 5 | python prepare_testing_data.py 6 | 7 | To do evaluation (AVP-NV of VOC12 val images and Acc-pi/6 and MedErr on VOC12 val non-truncated and non-occluded images), run: 8 | 9 | python run_evaluation.py 10 | 11 | For usages of the off-the-shelf viewpoint estimator, see `../demo_view` for an example. 12 | ref output of evaluation is in `ref_evaluation_results`. 13 | -------------------------------------------------------------------------------- /view_estimation/box_overlap.m: -------------------------------------------------------------------------------- 1 | % The box [x1 y1 x2 y2] here is different for box in matlab [x y w h] 2 | function o = box_overlap(a, b) 3 | 4 | % Compute the symmetric intersection over union overlap between a set of 5 | % bounding boxes in a and a single bounding box in b. 6 | % 7 | % a a matrix where each row specifies a bounding box 8 | % b a single bounding box 9 | 10 | x1 = max(a(:,1), b(1)); 11 | y1 = max(a(:,2), b(2)); 12 | x2 = min(a(:,3), b(3)); 13 | y2 = min(a(:,4), b(4)); 14 | 15 | w = x2-x1+1; 16 | h = y2-y1+1; 17 | inter = w.*h; 18 | aarea = (a(:,3)-a(:,1)+1) .* (a(:,4)-a(:,2)+1); 19 | barea = (b(3)-b(1)+1) * (b(4)-b(2)+1); 20 | % intersection over union overlap 21 | o = inter ./ (aarea+barea-inter); 22 | % set invalid entries to 0 overlap 23 | o(w <= 0) = 0; 24 | o(h <= 0) = 0; 25 | -------------------------------------------------------------------------------- /view_estimation/combine_bbox_view.m: -------------------------------------------------------------------------------- 1 | % combine detection bbox result and viewestimation result 2 | % if ~is3d 3 | % input: bbox: N*5 (x1,y1,x2,y2,score), view: N*1 (view) 4 | % output: combined: N*6 (x1,y1,x2,y2,view,score) as aeroplane_v4.mat etc. 5 | % if is3d 6 | % input: bbox: N*5 (x1,y1,x2,y2,score), view: N*3 (azimuth, elevation, tilt) 7 | % output: combined: N*8 (x1,y1,x2,y2,azimuth,elevation,tilt,score) as aeroplane_3dview.mat etc. 8 | % 9 | % cls: one of PASCAL3D+ class names 10 | % view_pred_file: each line is view for an image 11 | % det_bbox_mat_file: .mat file with object "boxes" as Nx5 array 12 | % 13 | function combine_bbox_view(cls, det_bbox_mat_file, view_pred_file, output_folder, is3d) 14 | 15 | addpath(fullfile(mfilename('fullpath'), '../../')); 16 | global_variables; 17 | 18 | if nargin < 5 19 | is3d = 0; 20 | end 21 | 22 | mkdir(output_folder); 23 | 24 | try 25 | object = load(det_bbox_mat_file); 26 | boxes = object.boxes; 27 | views = importdata(view_pred_file); 28 | if is3d 29 | dets = combine_bbox_3dview(boxes, views); 30 | save(fullfile(output_folder, sprintf('%s_3dview.mat',cls)), 'dets'); 31 | else 32 | for vnum_test = [4,8,16,24] 33 | azimuth_interval = [0 (360/(vnum_test*2)):(360/vnum_test):360-(360/(vnum_test*2))]; 34 | dets = combine_bbox_azimuthview(boxes, views, azimuth_interval); 35 | save(fullfile(output_folder, sprintf('%s_v%s.mat',cls, num2str(vnum_test))), 'dets'); 36 | end 37 | end 38 | catch 39 | fprintf('%s error..', cls); 40 | end 41 | 42 | 43 | function dets = combine_bbox_azimuthview(boxes, views, azimuth_interval) 44 | n = 1; 45 | dets = cell(1,numel(boxes)); 46 | for k = 1:numel(boxes) 47 | b = boxes{k}; 48 | d = zeros(size(b,1),6,'single'); 49 | d(:,1:4) = b(:,1:4); 50 | 51 | for j = 1:size(b,1) 52 | d(j,5) = find_interval(views(n), azimuth_interval); 53 | n = n + 1; 54 | end 55 | 56 | d(:,6) = b(:,5); 57 | dets{k} = d; 58 | end 59 | 60 | 61 | function dets = combine_bbox_3dview(boxes, views) 62 | n = 1; 63 | dets = cell(1,numel(boxes)); 64 | for k = 1:numel(boxes) 65 | b = boxes{k}; 66 | d = zeros(size(b,1),8,'single'); 67 | d(:,1:4) = b(:,1:4); 68 | 69 | for j = 1:size(b,1) 70 | d(j,5:7) = views(n,:) 71 | n = n + 1; 72 | end 73 | 74 | d(:,8) = b(:,5); 75 | dets{k} = d; 76 | end 77 | 78 | 79 | 80 | function ind = find_interval(azimuth, a) 81 | 82 | for i = 1:numel(a) 83 | if azimuth < a(i) 84 | break; 85 | end 86 | end 87 | ind = i - 1; 88 | if azimuth > a(end) 89 | ind = 1; 90 | end 91 | -------------------------------------------------------------------------------- /view_estimation/compute_vp_acc_mederror.m: -------------------------------------------------------------------------------- 1 | function [acc, mederr] = compute_vp_acc_mederror(view_filename, img_label_filename) 2 | 3 | est_views = importdata(view_filename); 4 | object = importdata(img_label_filename); 5 | data = object.data; 6 | gt_views = data(:,2:4); 7 | 8 | % CALCULATE ROTATION MATRIX ANGLES 9 | est_views = est_views/180*pi; 10 | gt_views = gt_views/180*pi; 11 | N = size(gt_views,1); 12 | R_angle_results = []; 13 | for j = 1:N 14 | R_pred = angle2dcm(est_views(j,1), est_views(j,2), est_views(j,3)); 15 | R_label = angle2dcm(gt_views(j,1), gt_views(j,2), gt_views(j,3)); 16 | R_angle = norm(logm(R_pred'*R_label)) / sqrt(2); 17 | R_angle_results = [R_angle_results; R_angle]; 18 | end 19 | 20 | acc = sum(R_angle_results < pi/6) / length(R_angle_results); 21 | mederr = median(R_angle_results); 22 | 23 | end 24 | -------------------------------------------------------------------------------- /view_estimation/extract_records.m: -------------------------------------------------------------------------------- 1 | BASE_DIR = fullfile(mfilename('fullpath'),'../'); 2 | addpath(fullfile(BASE_DIR, '../')); 3 | global_variables; 4 | 5 | % viewpoint annotation path 6 | %path_ann_view = '../Annotations'; 7 | path_ann_view = fullfile(g_pascal3d_root_folder, 'Annotations'); 8 | 9 | % read ids of validation images 10 | addpath(fullfile(g_pascal3d_root_folder, 'VDPM')); 11 | addpath(fullfile(g_pascal3d_root_folder, 'PASCAL/VOCdevkit/VOCcode')); 12 | VOCinit; 13 | %pascal_init; 14 | ids = textread(sprintf(VOCopts.imgsetpath, 'val'), '%s'); 15 | M = numel(ids); 16 | 17 | for i = 1:M 18 | % read ground truth bounding box 19 | rec = PASreadrecord(sprintf(VOCopts.annopath, ids{i})); 20 | voc12val_records{i} = rec; 21 | end 22 | 23 | save(fullfile(BASE_DIR, 'voc12val_records.mat'),'voc12val_records'); 24 | -------------------------------------------------------------------------------- /view_estimation/jitter_imcrop.m: -------------------------------------------------------------------------------- 1 | function [cropped_im, ov] = jitter_imcrop(im, rect, IoU) 2 | % im: input whole image 3 | % rect: [horizontal pos of top-left point, vertical pos of top-left point, 4 | % width of box, height of box] 5 | % IoU: 0~1 intersection-area/union-area 6 | w = size(im,2); 7 | h = size(im,1); 8 | bbox_w = rect(3); 9 | bbox_h = rect(4); 10 | assert(rect(1) > 0 && rect(1) < w); 11 | assert(rect(2) > 0 && rect(2) < h); 12 | assert(rect(3) <= w); 13 | assert(rect(4) <= h); 14 | 15 | % original imcrop 16 | if IoU >= 1 17 | cropped_im = imcrop(im, rect); 18 | return; 19 | end 20 | 21 | % jittered crop to make IoU >= input IoU 22 | assert(IoU > 0 && IoU < 1); 23 | jrect = rect; 24 | % horizontal position of top-left point 25 | b = (1-IoU); 26 | a = (1-1/IoU); 27 | while 1 28 | r = a + (b-a).*rand(4,1); 29 | jrect(1) = max(min(rect(1) + r(1)*bbox_w, w), 1); 30 | jrect(2) = max(min(rect(2) + r(2)*bbox_h, h), 1); 31 | jrect(3) = max(min(rect(3) + r(3)*bbox_w, w), 1); 32 | jrect(4) = max(min(rect(4) + r(4)*bbox_h, h), 1); 33 | jrect = round(jrect); 34 | ov = box_overlap([rect(1),rect(2),rect(1)+rect(3)-1,rect(2)+rect(4)-1],... 35 | [jrect(1),jrect(2),jrect(1)+jrect(3)-1,jrect(2)+jrect(4)-1]); 36 | if ov > IoU 37 | break; 38 | end 39 | end 40 | cropped_im = imcrop(im, jrect); 41 | end 42 | -------------------------------------------------------------------------------- /view_estimation/prepare_testing_data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | ''' 4 | Prepare Testing Data 5 | 6 | prepare filelist and LMDB for real images 7 | running this program will populate following folders: 8 | g_real_images_voc12val_det_bbox_folder 9 | g_real_images_voc12val_easy_gt_bbox_folder 10 | ''' 11 | 12 | import os 13 | import sys 14 | from data_prep_helper import * 15 | 16 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 17 | sys.path.append(BASE_DIR) 18 | sys.path.append(os.path.dirname(BASE_DIR)) 19 | from global_variables import * 20 | 21 | if __name__ == '__main__': 22 | 23 | # prepare voc12val det bbox (from rcnn) images 24 | matlab_cmd = "addpath('%s'); prepare_voc12val_det_imgs('%s','%s', 0);" % (BASE_DIR, g_real_images_voc12val_det_bbox_folder, g_rcnn_detection_bbox_mat_filelist) 25 | print matlab_cmd 26 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;"' % (g_matlab_executable_path, matlab_cmd)) 27 | 28 | 29 | # prepare voc12val gt bbox easy (no trunction/occlusion) images 30 | matlab_cmd = "addpath('%s'); prepare_voc12_imgs('val','%s',struct('flip',0,'aug_n',1,'jitter_IoU',1,'difficult',0,'truncated',0,'occluded',0));" % (BASE_DIR, g_real_images_voc12val_easy_gt_bbox_folder) 31 | print matlab_cmd 32 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;"' % (g_matlab_executable_path, matlab_cmd)) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /view_estimation/prepare_training_data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | ''' 4 | Prepare Training Data 5 | 6 | Running this program will populate following folders: 7 | g_syn_images_lmdb_folder 8 | with img-label files and g_syn_images_lmdb_pathname_prefix+[_label,_image] LMDBs 9 | g_real_images_voc12train_all_gt_bbox_folder 10 | with cropped images and img-label files and g_real_images_voc12train_all_gt_bbox_lmdb_prefix+[_label,_image] LMDBs 11 | ''' 12 | 13 | import os 14 | import sys 15 | from data_prep_helper import * 16 | 17 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 18 | sys.path.append(BASE_DIR) 19 | sys.path.append(os.path.dirname(BASE_DIR)) 20 | from global_variables import * 21 | 22 | if __name__ == '__main__': 23 | 24 | # ---------------------------------- 25 | # ---- SYNTHESIZED IMAGES ---------- 26 | # ---------------------------------- 27 | 28 | if not os.path.exists(g_syn_images_lmdb_folder): 29 | os.mkdir(g_syn_images_lmdb_folder) 30 | 31 | # get image filenames and labels, separated to train/test sets 32 | for idx, synset in enumerate(g_shape_synsets): 33 | name = g_shape_names[idx] 34 | get_one_category_image_label_file(synset, os.path.join(g_syn_images_lmdb_folder, name+'_train.txt'), os.path.join(g_syn_images_lmdb_folder, name+'_test.txt')) 35 | 36 | for keyword in ['train', 'test']: 37 | # combine filenames&labels from all 12 classes (shuffled) 38 | input_file_list = [os.path.join(g_syn_images_lmdb_folder, '%s_%s.txt' % (name, keyword)) for name in g_shape_names] 39 | output_file = os.path.join(g_syn_images_lmdb_folder, 'all_%s.txt' % (keyword)) 40 | combine_files(input_file_list, output_file) 41 | 42 | # generate LMDB 43 | generate_image_view_lmdb(output_file, '%s_%s' % (g_syn_images_lmdb_pathname_prefix, keyword)) 44 | 45 | 46 | # ---------------------------------- 47 | # ---- VOC12 TRAIN SET ------------- 48 | # ---------------------------------- 49 | 50 | # prepare voc12train gt bbox images and its LMDB 51 | matlab_cmd = "addpath('%s'); prepare_voc12_imgs('train','%s',struct('flip',%d,'aug_n',%d,'jitter_IoU',%d,'difficult',1,'truncated',1,'occluded',1));" % (BASE_DIR, g_real_images_voc12train_all_gt_bbox_folder, g_real_images_voc12train_flip, g_real_images_voc12train_aug_n, g_real_images_voc12train_jitter_IoU) 52 | print matlab_cmd 53 | os.system('%s -nodisplay -r "try %s ; catch; end; quit;"' % (g_matlab_executable_path, matlab_cmd)) 54 | 55 | if not os.path.exists(g_real_images_lmdb_folder): 56 | os.mkdir(g_real_images_lmdb_folder) 57 | 58 | # generate lmdb 59 | input_file_list = [os.path.join(g_real_images_voc12train_all_gt_bbox_folder,name+'.txt') for name in g_shape_names] 60 | output_file = os.path.join(g_real_images_voc12train_all_gt_bbox_folder, 'all.txt') 61 | combine_files(input_file_list, output_file) 62 | generate_image_view_lmdb(output_file, g_real_images_voc12train_all_gt_bbox_lmdb_prefix) 63 | -------------------------------------------------------------------------------- /view_estimation/prepare_voc12val_det_imgs.m: -------------------------------------------------------------------------------- 1 | function prepare_voc12val_det_imgs(output_img_dir, bbox_mat_filelist, resize_dim) 2 | % PREPARE_VOC12VAL_DET 3 | % Prepare testing images from detector outputs on VOC12 val set. 4 | % input: 5 | % output_img_dir: output image folder name, output will be like // 6 | % bbox_mat_filenames: txt files containing a list of bbox mat filenames 7 | % resize_dim (D): if >0 resize images to DxD. 8 | % 9 | 10 | addpath(fullfile(mfilename('fullpath'), '../../')); 11 | global_variables; 12 | cls_names = g_cls_names; 13 | 14 | % paths 15 | annotation_path = fullfile(g_pascal3d_root_folder, 'Annotations'); 16 | image_path = fullfile(g_pascal3d_root_folder, 'PASCAL/VOCdevkit/VOC2012/JPEGImages'); 17 | addpath(fullfile(g_pascal3d_root_folder, 'VDPM')); 18 | addpath(fullfile(g_pascal3d_root_folder, 'PASCAL/VOCdevkit/VOCcode')); 19 | 20 | % read ids of train/val set images 21 | VOCinit; 22 | img_set = 'val'; 23 | ids = textread(sprintf(VOCopts.imgsetpath, img_set), '%s'); 24 | M = numel(ids); 25 | 26 | bbox_mat_filenames = importdata(bbox_mat_filelist); 27 | for k = 1:numel(bbox_mat_filenames) 28 | bbox_mat_filenames{k} = fullfile(g_detection_results_folder, bbox_mat_filenames{k}); 29 | end 30 | 31 | % avoid duplication 32 | assert(exist(output_img_dir,'dir')==0); 33 | mkdir(output_img_dir); 34 | for cls_idx = 1:numel(cls_names) 35 | mkdir([output_img_dir '/' cls_names{cls_idx}]); 36 | end 37 | 38 | 39 | for cls_idx = 1:numel(cls_names) 40 | cls = cls_names{cls_idx}; 41 | 42 | imgfile = fopen(fullfile(output_img_dir, sprintf('%s.txt', cls)),'w'); 43 | 44 | % load detection bboxes of all images for class 45 | detection_filename = bbox_mat_filenames{cls_idx}; 46 | assert(~isempty(strfind(detection_filename, cls))); 47 | mat = load(detection_filename); 48 | det_bboxes_all = mat.boxes; 49 | 50 | for i = 1:M 51 | if mod(i,100) == 0 52 | fprintf('%s: %d/%d\n', cls, i, M); 53 | end 54 | 55 | % bboxes for image i, class cls 56 | det_bboxes = det_bboxes_all{i}; 57 | 58 | % load i-th image in VOC val 59 | img_filename = fullfile(image_path, sprintf('%s.jpg', ids{i})); 60 | im = imread(img_filename); 61 | 62 | for k = 1:size(det_bboxes,1) 63 | box = det_bboxes(k,:); 64 | box = box(1:4); 65 | w = box(3)-box(1)+1; 66 | h = box(4)-box(2)+1; 67 | rect = [box(1),box(2), w, h]; 68 | 69 | % write cropped img 70 | cropped_im = imcrop(im, rect); 71 | if resize_dim > 0 72 | copped_im = imresize(cropped_im, [resize_dim, resize_dim]); 73 | end 74 | cropped_im_filename = sprintf('%s/%s/%s_%s_%s.jpg', output_img_dir, cls, cls, ids{i}, num2str(k)); 75 | imwrite(cropped_im, cropped_im_filename); 76 | fprintf(imgfile, '%s\n', cropped_im_filename); 77 | end 78 | end 79 | fclose(imgfile); 80 | end 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /view_estimation/ref_evaluation_results/acc_mederr_results.txt: -------------------------------------------------------------------------------- 1 | aeroplane bicycle boat bottle bus car chair diningtable motorbike sofa train tvmonitor 2 | 0.803636 0.838983 0.620690 0.955645 0.954545 0.847403 0.754098 0.857143 0.880597 0.871795 0.823009 0.896396 3 | 10.202968 12.156138 18.544340 6.517484 4.527420 6.359017 12.373798 8.620423 13.040811 10.962882 5.745353 13.071721 4 | Mean acc = 0.841995 5 | Mean mederr = 10.176863 6 | (in degree) 7 | -------------------------------------------------------------------------------- /view_estimation/ref_evaluation_results/avp_nv_results.txt: -------------------------------------------------------------------------------- 1 | aeroplane bicycle boat bottle bus car chair diningtable motorbike sofa train tvmonitor 2 | 0.621800 0.590500 0.176500 0.309700 0.616400 0.482000 0.172100 0.204700 0.598500 0.348500 0.515700 0.604600 3 | 0.557600 0.522200 0.146800 0.309700 0.482100 0.428700 0.155400 0.165900 0.510300 0.293300 0.479000 0.458500 4 | 0.397800 0.342700 0.094300 0.306400 0.518100 0.354600 0.118600 0.176400 0.363000 0.203500 0.352000 0.298700 5 | 0.284300 0.233900 0.076700 0.300300 0.395200 0.321000 0.106400 0.125800 0.281000 0.196600 0.385000 0.178900 6 | 7 | Mean AVP-4V = 0.448300 8 | Mean AVP-8V = 0.381800 9 | Mean AVP-16V = 0.292700 10 | Mean AVP-24V = 0.234982 11 | 12 | 13 | AP: 14 | aeroplane bicycle boat bottle bus car chair diningtable motorbike sofa train tvmonitor 15 | 0.739100 0.666200 0.326800 0.311600 0.679100 0.581100 0.259100 0.361000 0.714000 0.429600 0.630100 0.635700 16 | 17 | Mean AP = 0.527783 18 | -------------------------------------------------------------------------------- /view_estimation/run_evaluation.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 5 | sys.path.append(BASE_DIR) 6 | sys.path.append(os.path.dirname(BASE_DIR)) 7 | from global_variables import * 8 | from evaluation_helper import * 9 | 10 | cls_names = g_shape_names 11 | 12 | img_name_file_list = [os.path.join(g_real_images_voc12val_det_bbox_folder, name+'.txt') for name in cls_names] 13 | det_bbox_mat_file_list = [os.path.join(g_detection_results_folder, x.rstrip()) for x in open(g_rcnn_detection_bbox_mat_filelist)] 14 | result_folder = os.path.join(BASE_DIR, 'avp_test_results') 15 | test_avp_nv(cls_names, img_name_file_list, det_bbox_mat_file_list, result_folder) 16 | 17 | img_name_file_list = [os.path.join(g_real_images_voc12val_easy_gt_bbox_folder, name+'.txt') for name in cls_names] 18 | view_label_folder = g_real_images_voc12val_easy_gt_bbox_folder 19 | result_folder = os.path.join(BASE_DIR, 'vp_test_results') 20 | test_vp_acc(cls_names, img_name_file_list, result_folder, view_label_folder) 21 | -------------------------------------------------------------------------------- /view_estimation/test_det.m: -------------------------------------------------------------------------------- 1 | function test_det(prediction_folder, ARP, show_curve, write_result) 2 | addpath(fullfile(mfilename('fullpath'), '../../')); 3 | global_variables; 4 | 5 | if nargin < 2 6 | ARP = 0; 7 | end 8 | if nargin < 3 9 | show_curve = 0; 10 | end 11 | if nargin < 4 12 | write_result = 1; 13 | end 14 | 15 | aps = []; 16 | aas = []; 17 | for k = 1:numel(g_cls_names) 18 | cls = g_cls_names{k}; 19 | try 20 | if ARP 21 | [recall, precision, accuracy, ap, aa] = compute_recall_precision_accuracy_3dview(cls, fullfile(prediction_folder,sprintf('%s_3dview.mat',cls)), show_curve, ARP); 22 | aps = [aps ap]; 23 | aas = [aas aa]; 24 | else 25 | for n = [4,8,16,24] 26 | [recall, precision, accuracy, ap, aa] = compute_recall_precision_accuracy_azimuth(cls, n, n, fullfile(prediction_folder,sprintf('%s_v%s.mat',cls,num2str(n))), show_curve); 27 | aps = [aps ap]; 28 | aas = [aas aa]; 29 | end 30 | end 31 | catch 32 | end 33 | end 34 | aas = reshape(aas, 4, numel(aas)/4); 35 | display(aas); 36 | aps = reshape(aps, 4, numel(aps)/4); 37 | display(aps(1,:)); 38 | 39 | 40 | N = length(g_cls_names); 41 | aps = aps(1,:); 42 | if write_result 43 | if ARP 44 | result_filename = 'arp_results.txt'; 45 | else 46 | result_filename = 'avp_nv_results.txt'; 47 | end 48 | fid = fopen(fullfile(prediction_folder, result_filename), 'w'); 49 | for k = 1:N 50 | fprintf(fid, sprintf('%s ', g_cls_names{k})); 51 | end 52 | fprintf(fid, '\n'); 53 | 54 | if ARP 55 | fprintf('ARP:\n'); 56 | for k = 1:N 57 | fprintf(fid, sprintf('%f ', aas(k))); 58 | end 59 | fprintf(fid, '\n'); 60 | fprintf(fid, '\n'); 61 | fprintf(fid, 'Mean ARP = %f\n', mean(aas)); 62 | else 63 | fprintf('AVP-NV (N=4,8,16,24):\n'); 64 | for j = 1:4 65 | for k = 1:N 66 | fprintf(fid, sprintf('%f ', aas(j,k))); 67 | end 68 | fprintf(fid, '\n'); 69 | end 70 | fprintf(fid, '\n'); 71 | fprintf('Mean AVP-NV excluding bottles\n'); 72 | avp_mean = mean(aas(:,[1,2,3,5,6,7,8,9,10,11,12]),2); 73 | vs = [4,8,16,24]; 74 | for j = 1:4 75 | fprintf(fid, 'Mean AVP-%dV = %f\n', vs(j), mean(avp_mean(j))); 76 | end 77 | end 78 | fprintf(fid, '\n\n'); 79 | fprintf(fid, 'AP:\n'); 80 | for k = 1:N 81 | fprintf(fid, sprintf('%s ', g_cls_names{k})); 82 | end 83 | fprintf(fid, '\n'); 84 | for k = 1:N 85 | fprintf(fid, sprintf('%f ', aps(k))); 86 | end 87 | fprintf(fid, '\n\n'); 88 | fprintf(fid, 'Mean AP = %f\n', mean(aps)); 89 | 90 | fclose(fid); 91 | end -------------------------------------------------------------------------------- /view_estimation/test_gt.m: -------------------------------------------------------------------------------- 1 | function test_gt(prediction_folder, view_label_folder, write_result) 2 | % prediction_folder contains _pred_view.txt 3 | % view_label_folder contains .txt 4 | % write_result - if set to 1, write result to acc_mederr_results.txt in prediction_folder 5 | 6 | addpath(fullfile(mfilename('fullpath'), '../../')); 7 | global_variables; 8 | 9 | N = numel(g_cls_names); 10 | 11 | acc = zeros(1,N); 12 | mederr = zeros(1,N); 13 | 14 | for k = 1:N 15 | cls = g_cls_names{k}; 16 | try 17 | [acc(k), mederr(k)] = compute_vp_acc_mederror(fullfile(prediction_folder,sprintf('%s_pred_view.txt', cls)), ... 18 | fullfile(view_label_folder, sprintf('%s.txt', cls))); 19 | catch 20 | end 21 | end 22 | display(acc); 23 | display(mederr); 24 | fprintf('Mean acc = %f\n', mean(acc)); 25 | fprintf('Mean mederr = %f\n (in degree)\n', mean(mederr)/pi*180); 26 | 27 | if nargin < 3 28 | write_result = 1; 29 | end 30 | if write_result 31 | fid = fopen(fullfile(prediction_folder, 'acc_mederr_results.txt'), 'w'); 32 | for k = 1:N 33 | fprintf(fid, sprintf('%s ', g_cls_names{k})); 34 | end 35 | fprintf(fid, '\n'); 36 | for k = 1:N 37 | fprintf(fid, sprintf('%f ', acc(k))); 38 | end 39 | fprintf(fid, '\n'); 40 | for k = 1:N 41 | fprintf(fid, sprintf('%f ', mederr(k)/pi*180)); 42 | end 43 | fprintf(fid, '\n'); 44 | fprintf(fid, 'Mean acc = %f\n', mean(acc)); 45 | fprintf(fid, 'Mean mederr = %f\n (in degree)\n', mean(mederr)/pi*180); 46 | fclose(fid); 47 | end 48 | --------------------------------------------------------------------------------