Full Code of ElegantGod/SSHA for AI

master bbf78059bf70 cached
22 files
75.6 MB
28.5k tokens
33 symbols
1 requests
Download .txt
Repository: ElegantGod/SSHA
Branch: master
Commit: bbf78059bf70
Files: 22
Total size: 75.6 MB

Directory structure:
gitextract_ddu7n4mp/

├── Makefile
├── README.md
├── __init__.py
├── kmodel/
│   ├── e2e-0000.params
│   └── e2e-symbol.json
├── rcnn/
│   ├── __init__.py
│   ├── cython/
│   │   ├── .gitignore
│   │   ├── __init__.py
│   │   ├── anchors.pyx
│   │   ├── bbox.pyx
│   │   ├── cpu_nms.pyx
│   │   ├── gpu_nms.hpp
│   │   ├── gpu_nms.pyx
│   │   ├── nms_kernel.cu
│   │   └── setup.py
│   └── processing/
│       ├── __init__.py
│       ├── bbox_regression.py
│       ├── bbox_transform.py
│       ├── generate_anchor.py
│       └── nms.py
├── ssha_detector.py
└── test_kpoint.py

================================================
FILE CONTENTS
================================================

================================================
FILE: Makefile
================================================
all:
	cd rcnn/cython/; python setup.py build_ext --inplace; rm -rf build; cd ../../
	#cd rcnn/pycocotools/; python setup.py build_ext --inplace; rm -rf build; cd ../../
clean:
	cd rcnn/cython/; rm *.so *.c *.cpp; cd ../../
	#cd rcnn/pycocotools/; rm *.so; cd ../../


================================================
FILE: README.md
================================================
# SSHA, SSH with Alignment

## Result

![img0](res2.jpg)
![img1](res1.jpg)
![img2](res0.jpg)

## How To Use
#### 0. install mxnet and opencv for python version
#### 1. clone SSHA
    git clone https://github.com/ElegantGod/SSHA
#### 2. make cython
    cd SSHA && make
#### 3. run it 
    python test_kpoint.py

### FDDB
![fddb](FDDB.png)

### Reference:
[Insightface](https://github.com/deepinsight/insightface/SSH)


================================================
FILE: __init__.py
================================================


================================================
FILE: kmodel/e2e-0000.params
================================================
[File too large to display: 75.5 MB]

================================================
FILE: kmodel/e2e-symbol.json
================================================
{
  "nodes": [
    {
      "op": "null", 
      "name": "data", 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv1_1_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv1_1_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv1_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[0, 0, 0], [1, 0, 0], [2, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu1_1", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[3, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv1_2_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv1_2_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv1_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[4, 0, 0], [5, 0, 0], [6, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu1_2", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[7, 0, 0]]
    }, 
    {
      "op": "Pooling", 
      "name": "pool1", 
      "attrs": {
        "kernel": "(2, 2)", 
        "pool_type": "max", 
        "stride": "(2, 2)"
      }, 
      "inputs": [[8, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv2_1_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv2_1_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv2_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[9, 0, 0], [10, 0, 0], [11, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu2_1", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[12, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv2_2_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv2_2_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv2_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[13, 0, 0], [14, 0, 0], [15, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu2_2", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[16, 0, 0]]
    }, 
    {
      "op": "Pooling", 
      "name": "pool2", 
      "attrs": {
        "kernel": "(2, 2)", 
        "pool_type": "max", 
        "stride": "(2, 2)"
      }, 
      "inputs": [[17, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv3_1_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv3_1_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv3_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[18, 0, 0], [19, 0, 0], [20, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu3_1", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[21, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv3_2_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv3_2_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv3_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[22, 0, 0], [23, 0, 0], [24, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu3_2", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[25, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv3_3_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv3_3_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv3_3", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[26, 0, 0], [27, 0, 0], [28, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu3_3", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[29, 0, 0]]
    }, 
    {
      "op": "Pooling", 
      "name": "pool3", 
      "attrs": {
        "kernel": "(2, 2)", 
        "pool_type": "max", 
        "stride": "(2, 2)"
      }, 
      "inputs": [[30, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv4_1_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv4_1_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv4_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[31, 0, 0], [32, 0, 0], [33, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu4_1", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[34, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv4_2_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv4_2_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv4_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[35, 0, 0], [36, 0, 0], [37, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu4_2", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[38, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv4_3_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv4_3_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv4_3", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[39, 0, 0], [40, 0, 0], [41, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu4_3", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[42, 0, 0]]
    }, 
    {
      "op": "Pooling", 
      "name": "pool4", 
      "attrs": {
        "kernel": "(2, 2)", 
        "pool_type": "max", 
        "stride": "(2, 2)"
      }, 
      "inputs": [[43, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv5_1_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv5_1_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv5_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[44, 0, 0], [45, 0, 0], [46, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu5_1", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[47, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv5_2_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv5_2_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv5_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[48, 0, 0], [49, 0, 0], [50, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu5_2", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[51, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "conv5_3_weight", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "conv5_3_bias", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "conv5_3", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "512", 
        "pad": "(1, 1)", 
        "workspace": "2048"
      }, 
      "inputs": [[52, 0, 0], [53, 0, 0], [54, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "relu5_3", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[55, 0, 0]]
    }, 
    {
      "op": "Pooling", 
      "name": "pooling0", 
      "attrs": {
        "kernel": "(2, 2)", 
        "pad": "(0, 0)", 
        "pool_type": "max", 
        "stride": "(2, 2)"
      }, 
      "inputs": [[56, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_conv1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_conv1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m3_det_conv1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[57, 0, 0], [58, 0, 0], [59, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m3_det_context_conv1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[57, 0, 0], [61, 0, 0], [62, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m3_det_context_conv1_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[63, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv2_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv2_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m3_det_context_conv2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[64, 0, 0], [65, 0, 0], [66, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv3_1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv3_1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m3_det_context_conv3_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[64, 0, 0], [68, 0, 0], [69, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m3_det_context_conv3_1_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[70, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv3_2_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m3_det_context_conv3_2_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m3_det_context_conv3_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[71, 0, 0], [72, 0, 0], [73, 0, 0]]
    }, 
    {
      "op": "Concat", 
      "name": "ssh_m3_det_concat", 
      "attrs": {
        "dim": "1", 
        "num_args": "3"
      }, 
      "inputs": [[60, 0, 0], [67, 0, 0], [74, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m3_det_concat_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[75, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_cls_score_stride32_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_cls_score_stride32_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_cls_score_stride32", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "4", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[76, 0, 0], [77, 0, 0], [78, 0, 0]]
    }, 
    {
      "op": "Reshape", 
      "name": "rpn_cls_score_reshape_stride32", 
      "attrs": {"shape": "(0, 2, -1, 0)"}, 
      "inputs": [[79, 0, 0]]
    }, 
    {
      "op": "SoftmaxActivation", 
      "name": "rpn_cls_prob_stride32", 
      "attrs": {"mode": "channel"}, 
      "inputs": [[80, 0, 0]]
    }, 
    {
      "op": "Reshape", 
      "name": "rpn_cls_prob_reshape_stride32", 
      "attrs": {"shape": "(0, 4, -1, 0)"}, 
      "inputs": [[81, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_bbox_pred_stride32_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_bbox_pred_stride32_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_bbox_pred_stride32", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "8", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[76, 0, 0], [83, 0, 0], [84, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_kpoint_pred_stride32_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_kpoint_pred_stride32_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_kpoint_pred_stride32", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "20", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[76, 0, 0], [86, 0, 0], [87, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_conv1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_conv1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m2_det_conv1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "256", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[56, 0, 0], [89, 0, 0], [90, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m2_det_context_conv1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[56, 0, 0], [92, 0, 0], [93, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m2_det_context_conv1_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[94, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv2_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv2_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m2_det_context_conv2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[95, 0, 0], [96, 0, 0], [97, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv3_1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv3_1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m2_det_context_conv3_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[95, 0, 0], [99, 0, 0], [100, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m2_det_context_conv3_1_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[101, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv3_2_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_det_context_conv3_2_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m2_det_context_conv3_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[102, 0, 0], [103, 0, 0], [104, 0, 0]]
    }, 
    {
      "op": "Concat", 
      "name": "ssh_m2_det_concat", 
      "attrs": {
        "dim": "1", 
        "num_args": "3"
      }, 
      "inputs": [[91, 0, 0], [98, 0, 0], [105, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m2_det_concat_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[106, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_cls_score_stride16_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_cls_score_stride16_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_cls_score_stride16", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "4", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[107, 0, 0], [108, 0, 0], [109, 0, 0]]
    }, 
    {
      "op": "Reshape", 
      "name": "rpn_cls_score_reshape_stride16", 
      "attrs": {"shape": "(0, 2, -1, 0)"}, 
      "inputs": [[110, 0, 0]]
    }, 
    {
      "op": "SoftmaxActivation", 
      "name": "rpn_cls_prob_stride16", 
      "attrs": {"mode": "channel"}, 
      "inputs": [[111, 0, 0]]
    }, 
    {
      "op": "Reshape", 
      "name": "rpn_cls_prob_reshape_stride16", 
      "attrs": {"shape": "(0, 4, -1, 0)"}, 
      "inputs": [[112, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_bbox_pred_stride16_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_bbox_pred_stride16_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_bbox_pred_stride16", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "8", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[107, 0, 0], [114, 0, 0], [115, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_kpoint_pred_stride16_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_kpoint_pred_stride16_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_kpoint_pred_stride16", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "20", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[107, 0, 0], [117, 0, 0], [118, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_red_conv_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_red_conv_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_red_conv", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "128", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[43, 0, 0], [120, 0, 0], [121, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m1_red_conv_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[122, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_red_conv_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_red_conv_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m2_red_conv", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "128", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[56, 0, 0], [124, 0, 0], [125, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m2_red_conv_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[126, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m2_red_upsampling_weight", 
      "attrs": {
        "__lr_mult__": "0.0", 
        "__wd_mult__": "0.0", 
        "kernel": "(4, 4)", 
        "no_bias": "True", 
        "num_filter": "128", 
        "num_group": "128", 
        "pad": "(1, 1)", 
        "stride": "(2, 2)"
      }, 
      "inputs": []
    }, 
    {
      "op": "Deconvolution", 
      "name": "ssh_m2_red_upsampling", 
      "attrs": {
        "__lr_mult__": "0.0", 
        "__wd_mult__": "0.0", 
        "kernel": "(4, 4)", 
        "no_bias": "True", 
        "num_filter": "128", 
        "num_group": "128", 
        "pad": "(1, 1)", 
        "stride": "(2, 2)"
      }, 
      "inputs": [[127, 0, 0], [128, 0, 0]]
    }, 
    {
      "op": "Crop", 
      "name": "crop0", 
      "attrs": {"num_args": "2"}, 
      "inputs": [[123, 0, 0], [129, 0, 0]]
    }, 
    {
      "op": "elemwise_add", 
      "name": "_plus0", 
      "inputs": [[130, 0, 0], [129, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_conv_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_conv_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_conv", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[131, 0, 0], [132, 0, 0], [133, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m1_conv_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[134, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_conv1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_conv1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_det_conv1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "128", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[135, 0, 0], [136, 0, 0], [137, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_det_context_conv1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[135, 0, 0], [139, 0, 0], [140, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m1_det_context_conv1_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[141, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv2_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv2_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_det_context_conv2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[142, 0, 0], [143, 0, 0], [144, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv3_1_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv3_1_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_det_context_conv3_1", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[142, 0, 0], [146, 0, 0], [147, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m1_det_context_conv3_1_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[148, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv3_2_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "ssh_m1_det_context_conv3_2_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "ssh_m1_det_context_conv3_2", 
      "attrs": {
        "kernel": "(3, 3)", 
        "num_filter": "64", 
        "pad": "(1, 1)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[149, 0, 0], [150, 0, 0], [151, 0, 0]]
    }, 
    {
      "op": "Concat", 
      "name": "ssh_m1_det_concat", 
      "attrs": {
        "dim": "1", 
        "num_args": "3"
      }, 
      "inputs": [[138, 0, 0], [145, 0, 0], [152, 0, 0]]
    }, 
    {
      "op": "Activation", 
      "name": "ssh_m1_det_concat_relu", 
      "attrs": {"act_type": "relu"}, 
      "inputs": [[153, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_cls_score_stride8_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_cls_score_stride8_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_cls_score_stride8", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "4", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[154, 0, 0], [155, 0, 0], [156, 0, 0]]
    }, 
    {
      "op": "Reshape", 
      "name": "rpn_cls_score_reshape_stride8", 
      "attrs": {"shape": "(0, 2, -1, 0)"}, 
      "inputs": [[157, 0, 0]]
    }, 
    {
      "op": "SoftmaxActivation", 
      "name": "rpn_cls_prob_stride8", 
      "attrs": {"mode": "channel"}, 
      "inputs": [[158, 0, 0]]
    }, 
    {
      "op": "Reshape", 
      "name": "rpn_cls_prob_reshape_stride8", 
      "attrs": {"shape": "(0, 4, -1, 0)"}, 
      "inputs": [[159, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_bbox_pred_stride8_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_bbox_pred_stride8_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_bbox_pred_stride8", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "8", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[154, 0, 0], [161, 0, 0], [162, 0, 0]]
    }, 
    {
      "op": "null", 
      "name": "rpn_kpoint_pred_stride8_weight", 
      "attrs": {
        "__init__": "[\"normal\", {\"sigma\": 0.01}]", 
        "__lr_mult__": "1.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "null", 
      "name": "rpn_kpoint_pred_stride8_bias", 
      "attrs": {
        "__init__": "[\"constant\", {\"value\": 0.0}]", 
        "__lr_mult__": "2.0", 
        "__wd_mult__": "0.0"
      }, 
      "inputs": []
    }, 
    {
      "op": "Convolution", 
      "name": "rpn_kpoint_pred_stride8", 
      "attrs": {
        "kernel": "(1, 1)", 
        "num_filter": "20", 
        "pad": "(0, 0)", 
        "stride": "(1, 1)"
      }, 
      "inputs": [[154, 0, 0], [164, 0, 0], [165, 0, 0]]
    }
  ], 
  "arg_nodes": [
    0, 
    1, 
    2, 
    5, 
    6, 
    10, 
    11, 
    14, 
    15, 
    19, 
    20, 
    23, 
    24, 
    27, 
    28, 
    32, 
    33, 
    36, 
    37, 
    40, 
    41, 
    45, 
    46, 
    49, 
    50, 
    53, 
    54, 
    58, 
    59, 
    61, 
    62, 
    65, 
    66, 
    68, 
    69, 
    72, 
    73, 
    77, 
    78, 
    83, 
    84, 
    86, 
    87, 
    89, 
    90, 
    92, 
    93, 
    96, 
    97, 
    99, 
    100, 
    103, 
    104, 
    108, 
    109, 
    114, 
    115, 
    117, 
    118, 
    120, 
    121, 
    124, 
    125, 
    128, 
    132, 
    133, 
    136, 
    137, 
    139, 
    140, 
    143, 
    144, 
    146, 
    147, 
    150, 
    151, 
    155, 
    156, 
    161, 
    162, 
    164, 
    165
  ], 
  "node_row_ptr": [
    0, 
    1, 
    2, 
    3, 
    4, 
    5, 
    6, 
    7, 
    8, 
    9, 
    10, 
    11, 
    12, 
    13, 
    14, 
    15, 
    16, 
    17, 
    18, 
    19, 
    20, 
    21, 
    22, 
    23, 
    24, 
    25, 
    26, 
    27, 
    28, 
    29, 
    30, 
    31, 
    32, 
    33, 
    34, 
    35, 
    36, 
    37, 
    38, 
    39, 
    40, 
    41, 
    42, 
    43, 
    44, 
    45, 
    46, 
    47, 
    48, 
    49, 
    50, 
    51, 
    52, 
    53, 
    54, 
    55, 
    56, 
    57, 
    58, 
    59, 
    60, 
    61, 
    62, 
    63, 
    64, 
    65, 
    66, 
    67, 
    68, 
    69, 
    70, 
    71, 
    72, 
    73, 
    74, 
    75, 
    76, 
    77, 
    78, 
    79, 
    80, 
    81, 
    82, 
    83, 
    84, 
    85, 
    86, 
    87, 
    88, 
    89, 
    90, 
    91, 
    92, 
    93, 
    94, 
    95, 
    96, 
    97, 
    98, 
    99, 
    100, 
    101, 
    102, 
    103, 
    104, 
    105, 
    106, 
    107, 
    108, 
    109, 
    110, 
    111, 
    112, 
    113, 
    114, 
    115, 
    116, 
    117, 
    118, 
    119, 
    120, 
    121, 
    122, 
    123, 
    124, 
    125, 
    126, 
    127, 
    128, 
    129, 
    130, 
    131, 
    132, 
    133, 
    134, 
    135, 
    136, 
    137, 
    138, 
    139, 
    140, 
    141, 
    142, 
    143, 
    144, 
    145, 
    146, 
    147, 
    148, 
    149, 
    150, 
    151, 
    152, 
    153, 
    154, 
    155, 
    156, 
    157, 
    158, 
    159, 
    160, 
    161, 
    162, 
    163, 
    164, 
    165, 
    166, 
    167
  ], 
  "heads": [[82, 0, 0], [85, 0, 0], [88, 0, 0], [113, 0, 0], [116, 0, 0], [119, 0, 0], [160, 0, 0], [163, 0, 0], [166, 0, 0]], 
  "attrs": {"mxnet_version": ["int", 10300]}
}

================================================
FILE: rcnn/__init__.py
================================================


================================================
FILE: rcnn/cython/.gitignore
================================================
*.c
*.cpp
*.so


================================================
FILE: rcnn/cython/__init__.py
================================================


================================================
FILE: rcnn/cython/anchors.pyx
================================================
cimport cython
import numpy as np
cimport numpy as np

DTYPE = np.float32
ctypedef np.float32_t DTYPE_t

def anchors_cython(int height, int width, int stride, np.ndarray[DTYPE_t, ndim=2] base_anchors):
    """
    Parameters
    ----------
    height: height of plane
    width:  width of plane
    stride: stride ot the original image
    anchors_base: (A, 4) a base set of anchors
    Returns
    -------
    all_anchors: (height, width, A, 4) ndarray of anchors spreading over the plane
    """
    cdef unsigned int A = base_anchors.shape[0]
    cdef np.ndarray[DTYPE_t, ndim=4] all_anchors = np.zeros((height, width, A, 4), dtype=DTYPE)
    cdef unsigned int iw, ih
    cdef unsigned int k
    cdef unsigned int sh
    cdef unsigned int sw
    for iw in range(width):
        sw = iw * stride
        for ih in range(height):
            sh = ih * stride
            for k in range(A):
                all_anchors[ih, iw, k, 0] = base_anchors[k, 0] + sw
                all_anchors[ih, iw, k, 1] = base_anchors[k, 1] + sh
                all_anchors[ih, iw, k, 2] = base_anchors[k, 2] + sw
                all_anchors[ih, iw, k, 3] = base_anchors[k, 3] + sh
    return all_anchors

================================================
FILE: rcnn/cython/bbox.pyx
================================================
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Sergey Karayev
# --------------------------------------------------------

cimport cython
import numpy as np
cimport numpy as np

DTYPE = np.float
ctypedef np.float_t DTYPE_t

def bbox_overlaps_cython(
        np.ndarray[DTYPE_t, ndim=2] boxes,
        np.ndarray[DTYPE_t, ndim=2] query_boxes):
    """
    Parameters
    ----------
    boxes: (N, 4) ndarray of float
    query_boxes: (K, 4) ndarray of float
    Returns
    -------
    overlaps: (N, K) ndarray of overlap between boxes and query_boxes
    """
    cdef unsigned int N = boxes.shape[0]
    cdef unsigned int K = query_boxes.shape[0]
    cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)
    cdef DTYPE_t iw, ih, box_area
    cdef DTYPE_t ua
    cdef unsigned int k, n
    for k in range(K):
        box_area = (
            (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
            (query_boxes[k, 3] - query_boxes[k, 1] + 1)
        )
        for n in range(N):
            iw = (
                min(boxes[n, 2], query_boxes[k, 2]) -
                max(boxes[n, 0], query_boxes[k, 0]) + 1
            )
            if iw > 0:
                ih = (
                    min(boxes[n, 3], query_boxes[k, 3]) -
                    max(boxes[n, 1], query_boxes[k, 1]) + 1
                )
                if ih > 0:
                    ua = float(
                        (boxes[n, 2] - boxes[n, 0] + 1) *
                        (boxes[n, 3] - boxes[n, 1] + 1) +
                        box_area - iw * ih
                    )
                    overlaps[n, k] = iw * ih / ua
    return overlaps


================================================
FILE: rcnn/cython/cpu_nms.pyx
================================================
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import numpy as np
cimport numpy as np

cdef inline np.float32_t max(np.float32_t a, np.float32_t b):
    return a if a >= b else b

cdef inline np.float32_t min(np.float32_t a, np.float32_t b):
    return a if a <= b else b

def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):
    cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]
    cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]
    cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]
    cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]
    cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]

    cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]

    cdef int ndets = dets.shape[0]
    cdef np.ndarray[np.int_t, ndim=1] suppressed = \
            np.zeros((ndets), dtype=np.int)

    # nominal indices
    cdef int _i, _j
    # sorted indices
    cdef int i, j
    # temp variables for box i's (the box currently under consideration)
    cdef np.float32_t ix1, iy1, ix2, iy2, iarea
    # variables for computing overlap with box j (lower scoring box)
    cdef np.float32_t xx1, yy1, xx2, yy2
    cdef np.float32_t w, h
    cdef np.float32_t inter, ovr

    keep = []
    for _i in range(ndets):
        i = order[_i]
        if suppressed[i] == 1:
            continue
        keep.append(i)
        ix1 = x1[i]
        iy1 = y1[i]
        ix2 = x2[i]
        iy2 = y2[i]
        iarea = areas[i]
        for _j in range(_i + 1, ndets):
            j = order[_j]
            if suppressed[j] == 1:
                continue
            xx1 = max(ix1, x1[j])
            yy1 = max(iy1, y1[j])
            xx2 = min(ix2, x2[j])
            yy2 = min(iy2, y2[j])
            w = max(0.0, xx2 - xx1 + 1)
            h = max(0.0, yy2 - yy1 + 1)
            inter = w * h
            ovr = inter / (iarea + areas[j] - inter)
            if ovr >= thresh:
                suppressed[j] = 1

    return keep


================================================
FILE: rcnn/cython/gpu_nms.hpp
================================================
void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num,
          int boxes_dim, float nms_overlap_thresh, int device_id);


================================================
FILE: rcnn/cython/gpu_nms.pyx
================================================
# --------------------------------------------------------
# Faster R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import numpy as np
cimport numpy as np

assert sizeof(int) == sizeof(np.int32_t)

cdef extern from "gpu_nms.hpp":
    void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int)

def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,
            np.int32_t device_id=0):
    cdef int boxes_num = dets.shape[0]
    cdef int boxes_dim = dets.shape[1]
    cdef int num_out
    cdef np.ndarray[np.int32_t, ndim=1] \
        keep = np.zeros(boxes_num, dtype=np.int32)
    cdef np.ndarray[np.float32_t, ndim=1] \
        scores = dets[:, 4]
    cdef np.ndarray[np.int_t, ndim=1] \
        order = scores.argsort()[::-1]
    cdef np.ndarray[np.float32_t, ndim=2] \
        sorted_dets = dets[order, :]
    _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)
    keep = keep[:num_out]
    return list(order[keep])


================================================
FILE: rcnn/cython/nms_kernel.cu
================================================
// ------------------------------------------------------------------
// Faster R-CNN
// Copyright (c) 2015 Microsoft
// Licensed under The MIT License [see fast-rcnn/LICENSE for details]
// Written by Shaoqing Ren
// ------------------------------------------------------------------

#include "gpu_nms.hpp"
#include <vector>
#include <iostream>

#define CUDA_CHECK(condition) \
  /* Code block avoids redefinition of cudaError_t error */ \
  do { \
    cudaError_t error = condition; \
    if (error != cudaSuccess) { \
      std::cout << cudaGetErrorString(error) << std::endl; \
    } \
  } while (0)

#define DIVUP(m,n) ((m) / (n) + ((m) % (n) > 0))
int const threadsPerBlock = sizeof(unsigned long long) * 8;

__device__ inline float devIoU(float const * const a, float const * const b) {
  float left = max(a[0], b[0]), right = min(a[2], b[2]);
  float top = max(a[1], b[1]), bottom = min(a[3], b[3]);
  float width = max(right - left + 1, 0.f), height = max(bottom - top + 1, 0.f);
  float interS = width * height;
  float Sa = (a[2] - a[0] + 1) * (a[3] - a[1] + 1);
  float Sb = (b[2] - b[0] + 1) * (b[3] - b[1] + 1);
  return interS / (Sa + Sb - interS);
}

__global__ void nms_kernel(const int n_boxes, const float nms_overlap_thresh,
                           const float *dev_boxes, unsigned long long *dev_mask) {
  const int row_start = blockIdx.y;
  const int col_start = blockIdx.x;

  // if (row_start > col_start) return;

  const int row_size =
        min(n_boxes - row_start * threadsPerBlock, threadsPerBlock);
  const int col_size =
        min(n_boxes - col_start * threadsPerBlock, threadsPerBlock);

  __shared__ float block_boxes[threadsPerBlock * 5];
  if (threadIdx.x < col_size) {
    block_boxes[threadIdx.x * 5 + 0] =
        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0];
    block_boxes[threadIdx.x * 5 + 1] =
        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1];
    block_boxes[threadIdx.x * 5 + 2] =
        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2];
    block_boxes[threadIdx.x * 5 + 3] =
        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3];
    block_boxes[threadIdx.x * 5 + 4] =
        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4];
  }
  __syncthreads();

  if (threadIdx.x < row_size) {
    const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x;
    const float *cur_box = dev_boxes + cur_box_idx * 5;
    int i = 0;
    unsigned long long t = 0;
    int start = 0;
    if (row_start == col_start) {
      start = threadIdx.x + 1;
    }
    for (i = start; i < col_size; i++) {
      if (devIoU(cur_box, block_boxes + i * 5) > nms_overlap_thresh) {
        t |= 1ULL << i;
      }
    }
    const int col_blocks = DIVUP(n_boxes, threadsPerBlock);
    dev_mask[cur_box_idx * col_blocks + col_start] = t;
  }
}

void _set_device(int device_id) {
  int current_device;
  CUDA_CHECK(cudaGetDevice(&current_device));
  if (current_device == device_id) {
    return;
  }
  // The call to cudaSetDevice must come before any calls to Get, which
  // may perform initialization using the GPU.
  CUDA_CHECK(cudaSetDevice(device_id));
}

void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num,
          int boxes_dim, float nms_overlap_thresh, int device_id) {
  _set_device(device_id);

  float* boxes_dev = NULL;
  unsigned long long* mask_dev = NULL;

  const int col_blocks = DIVUP(boxes_num, threadsPerBlock);

  CUDA_CHECK(cudaMalloc(&boxes_dev,
                        boxes_num * boxes_dim * sizeof(float)));
  CUDA_CHECK(cudaMemcpy(boxes_dev,
                        boxes_host,
                        boxes_num * boxes_dim * sizeof(float),
                        cudaMemcpyHostToDevice));

  CUDA_CHECK(cudaMalloc(&mask_dev,
                        boxes_num * col_blocks * sizeof(unsigned long long)));

  dim3 blocks(DIVUP(boxes_num, threadsPerBlock),
              DIVUP(boxes_num, threadsPerBlock));
  dim3 threads(threadsPerBlock);
  nms_kernel<<<blocks, threads>>>(boxes_num,
                                  nms_overlap_thresh,
                                  boxes_dev,
                                  mask_dev);

  std::vector<unsigned long long> mask_host(boxes_num * col_blocks);
  CUDA_CHECK(cudaMemcpy(&mask_host[0],
                        mask_dev,
                        sizeof(unsigned long long) * boxes_num * col_blocks,
                        cudaMemcpyDeviceToHost));

  std::vector<unsigned long long> remv(col_blocks);
  memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks);

  int num_to_keep = 0;
  for (int i = 0; i < boxes_num; i++) {
    int nblock = i / threadsPerBlock;
    int inblock = i % threadsPerBlock;

    if (!(remv[nblock] & (1ULL << inblock))) {
      keep_out[num_to_keep++] = i;
      unsigned long long *p = &mask_host[0] + i * col_blocks;
      for (int j = nblock; j < col_blocks; j++) {
        remv[j] |= p[j];
      }
    }
  }
  *num_out = num_to_keep;

  CUDA_CHECK(cudaFree(boxes_dev));
  CUDA_CHECK(cudaFree(mask_dev));
}


================================================
FILE: rcnn/cython/setup.py
================================================
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import os
from os.path import join as pjoin
from setuptools import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np


def find_in_path(name, path):
    "Find a file in a search path"
    # Adapted fom
    # http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/
    for dir in path.split(os.pathsep):
        binpath = pjoin(dir, name)
        if os.path.exists(binpath):
            return os.path.abspath(binpath)
    return None


def locate_cuda():
    """Locate the CUDA environment on the system

    Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64'
    and values giving the absolute path to each directory.

    Starts by looking for the CUDAHOME env variable. If not found, everything
    is based on finding 'nvcc' in the PATH.
    """

    # first check if the CUDAHOME env variable is in use
    if 'CUDAHOME' in os.environ:
        home = os.environ['CUDAHOME']
        nvcc = pjoin(home, 'bin', 'nvcc')
    else:
        # otherwise, search the PATH for NVCC
        default_path = pjoin(os.sep, 'usr', 'local', 'cuda', 'bin')
        nvcc = find_in_path('nvcc', os.environ['PATH'] + os.pathsep + default_path)
        if nvcc is None:
            raise EnvironmentError('The nvcc binary could not be '
                'located in your $PATH. Either add it to your path, or set $CUDAHOME')
        home = os.path.dirname(os.path.dirname(nvcc))

    cudaconfig = {'home':home, 'nvcc':nvcc,
                  'include': pjoin(home, 'include'),
                  'lib64': pjoin(home, 'lib64')}
    for k, v in cudaconfig.items():
        if not os.path.exists(v):
            raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v))

    return cudaconfig


# Test if cuda could be foun
try:
    CUDA = locate_cuda()
except EnvironmentError:
    CUDA = None


# Obtain the numpy include directory.  This logic works across numpy versions.
try:
    numpy_include = np.get_include()
except AttributeError:
    numpy_include = np.get_numpy_include()


def customize_compiler_for_nvcc(self):
    """inject deep into distutils to customize how the dispatch
    to gcc/nvcc works.

    If you subclass UnixCCompiler, it's not trivial to get your subclass
    injected in, and still have the right customizations (i.e.
    distutils.sysconfig.customize_compiler) run on it. So instead of going
    the OO route, I have this. Note, it's kindof like a wierd functional
    subclassing going on."""

    # tell the compiler it can processes .cu
    self.src_extensions.append('.cu')

    # save references to the default compiler_so and _comple methods
    default_compiler_so = self.compiler_so
    super = self._compile

    # now redefine the _compile method. This gets executed for each
    # object but distutils doesn't have the ability to change compilers
    # based on source extension: we add it.
    def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):
        if os.path.splitext(src)[1] == '.cu':
            # use the cuda for .cu files
            self.set_executable('compiler_so', CUDA['nvcc'])
            # use only a subset of the extra_postargs, which are 1-1 translated
            # from the extra_compile_args in the Extension class
            postargs = extra_postargs['nvcc']
        else:
            postargs = extra_postargs['gcc']

        super(obj, src, ext, cc_args, postargs, pp_opts)
        # reset the default compiler_so, which we might have changed for cuda
        self.compiler_so = default_compiler_so

    # inject our redefined _compile method into the class
    self._compile = _compile


# run the customize_compiler
class custom_build_ext(build_ext):
    def build_extensions(self):
        customize_compiler_for_nvcc(self.compiler)
        build_ext.build_extensions(self)


ext_modules = [
    Extension(
        "bbox",
        ["bbox.pyx"],
        extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        include_dirs=[numpy_include]
    ),
    Extension(
        "anchors",
        ["anchors.pyx"],
        extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        include_dirs=[numpy_include]
    ),
    Extension(
        "cpu_nms",
        ["cpu_nms.pyx"],
        extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        include_dirs = [numpy_include]
    ),
]

if CUDA is not None:
    ext_modules.append(
        Extension('gpu_nms',
            ['nms_kernel.cu', 'gpu_nms.pyx'],
            library_dirs=[CUDA['lib64']],
            libraries=['cudart'],
            language='c++',
            runtime_library_dirs=[CUDA['lib64']],
            # this syntax is specific to this build system
            # we're only going to use certain compiler args with nvcc and not with
            # gcc the implementation of this trick is in customize_compiler() below
            extra_compile_args={'gcc': ["-Wno-unused-function"],
                                'nvcc': ['-arch=sm_35',
                                         '--ptxas-options=-v',
                                         '-c',
                                         '--compiler-options',
                                         "'-fPIC'"]},
            include_dirs = [numpy_include, CUDA['include']]
        )
    )
else:
    print('Skipping GPU_NMS')


setup(
    name='frcnn_cython',
    ext_modules=ext_modules,
    # inject our custom trigger
    cmdclass={'build_ext': custom_build_ext},
)


================================================
FILE: rcnn/processing/__init__.py
================================================


================================================
FILE: rcnn/processing/bbox_regression.py
================================================
"""
This file has functions about generating bounding box regression targets
"""

import numpy as np

from ..logger import logger
from .bbox_transform import bbox_overlaps, bbox_transform
from rcnn.config import config


def compute_bbox_regression_targets(rois, overlaps, labels):
    """
    given rois, overlaps, gt labels, compute bounding box regression targets
    :param rois: roidb[i]['boxes'] k * 4
    :param overlaps: roidb[i]['max_overlaps'] k * 1
    :param labels: roidb[i]['max_classes'] k * 1
    :return: targets[i][class, dx, dy, dw, dh] k * 5
    """
    # Ensure ROIs are floats
    rois = rois.astype(np.float, copy=False)

    # Sanity check
    if len(rois) != len(overlaps):
        logger.warning('bbox regression: len(rois) != len(overlaps)')

    # Indices of ground-truth ROIs
    gt_inds = np.where(overlaps == 1)[0]
    if len(gt_inds) == 0:
        logger.warning('bbox regression: len(gt_inds) == 0')

    # Indices of examples for which we try to make predictions
    ex_inds = np.where(overlaps >= config.TRAIN.BBOX_REGRESSION_THRESH)[0]

    # Get IoU overlap between each ex ROI and gt ROI
    ex_gt_overlaps = bbox_overlaps(rois[ex_inds, :], rois[gt_inds, :])

    # Find which gt ROI each ex ROI has max overlap with:
    # this will be the ex ROI's gt target
    gt_assignment = ex_gt_overlaps.argmax(axis=1)
    gt_rois = rois[gt_inds[gt_assignment], :]
    ex_rois = rois[ex_inds, :]

    targets = np.zeros((rois.shape[0], 5), dtype=np.float32)
    targets[ex_inds, 0] = labels[ex_inds]
    targets[ex_inds, 1:] = bbox_transform(ex_rois, gt_rois)
    return targets


def add_bbox_regression_targets(roidb):
    """
    given roidb, add ['bbox_targets'] and normalize bounding box regression targets
    :param roidb: roidb to be processed. must have gone through imdb.prepare_roidb
    :return: means, std variances of targets
    """
    logger.info('bbox regression: add bounding box regression targets')
    assert len(roidb) > 0
    assert 'max_classes' in roidb[0]

    num_images = len(roidb)
    num_classes = roidb[0]['gt_overlaps'].shape[1]
    for im_i in range(num_images):
        rois = roidb[im_i]['boxes']
        max_overlaps = roidb[im_i]['max_overlaps']
        max_classes = roidb[im_i]['max_classes']
        roidb[im_i]['bbox_targets'] = compute_bbox_regression_targets(rois, max_overlaps, max_classes)

    if config.TRAIN.BBOX_NORMALIZATION_PRECOMPUTED:
        # use fixed / precomputed means and stds instead of empirical values
        means = np.tile(np.array(config.TRAIN.BBOX_MEANS), (num_classes, 1))
        stds = np.tile(np.array(config.TRAIN.BBOX_STDS), (num_classes, 1))
    else:
        # compute mean, std values
        class_counts = np.zeros((num_classes, 1)) + 1e-14
        sums = np.zeros((num_classes, 4))
        squared_sums = np.zeros((num_classes, 4))
        for im_i in range(num_images):
            targets = roidb[im_i]['bbox_targets']
            for cls in range(1, num_classes):
                cls_indexes = np.where(targets[:, 0] == cls)[0]
                if cls_indexes.size > 0:
                    class_counts[cls] += cls_indexes.size
                    sums[cls, :] += targets[cls_indexes, 1:].sum(axis=0)
                    squared_sums[cls, :] += (targets[cls_indexes, 1:] ** 2).sum(axis=0)

        means = sums / class_counts
        # var(x) = E(x^2) - E(x)^2
        stds = np.sqrt(squared_sums / class_counts - means ** 2)

    # normalized targets
    for im_i in range(num_images):
        targets = roidb[im_i]['bbox_targets']
        for cls in range(1, num_classes):
            cls_indexes = np.where(targets[:, 0] == cls)[0]
            roidb[im_i]['bbox_targets'][cls_indexes, 1:] -= means[cls, :]
            roidb[im_i]['bbox_targets'][cls_indexes, 1:] /= stds[cls, :]

    return means.ravel(), stds.ravel()


def expand_bbox_regression_targets(bbox_targets_data, num_classes):
    """
    expand from 5 to 4 * num_classes; only the right class has non-zero bbox regression targets
    :param bbox_targets_data: [k * 5]
    :param num_classes: number of classes
    :return: bbox target processed [k * 4 num_classes]
    bbox_weights ! only foreground boxes have bbox regression computation!
    """
    classes = bbox_targets_data[:, 0]
    bbox_targets = np.zeros((classes.size, 4 * num_classes), dtype=np.float32)
    bbox_weights = np.zeros(bbox_targets.shape, dtype=np.float32)
    indexes = np.where(classes > 0)[0]
    for index in indexes:
        cls = classes[index]
        start = int(4 * cls)
        end = start + 4
        bbox_targets[index, start:end] = bbox_targets_data[index, 1:]
        bbox_weights[index, start:end] = config.TRAIN.BBOX_WEIGHTS
    return bbox_targets, bbox_weights



================================================
FILE: rcnn/processing/bbox_transform.py
================================================
import numpy as np
from ..cython.bbox import bbox_overlaps_cython


def bbox_overlaps(boxes, query_boxes):
    return bbox_overlaps_cython(boxes, query_boxes)


def bbox_overlaps_py(boxes, query_boxes):
    """
    determine overlaps between boxes and query_boxes
    :param boxes: n * 4 bounding boxes
    :param query_boxes: k * 4 bounding boxes
    :return: overlaps: n * k overlaps
    """
    n_ = boxes.shape[0]
    k_ = query_boxes.shape[0]
    overlaps = np.zeros((n_, k_), dtype=np.float)
    for k in range(k_):
        query_box_area = (query_boxes[k, 2] - query_boxes[k, 0] + 1) * (query_boxes[k, 3] - query_boxes[k, 1] + 1)
        for n in range(n_):
            iw = min(boxes[n, 2], query_boxes[k, 2]) - max(boxes[n, 0], query_boxes[k, 0]) + 1
            if iw > 0:
                ih = min(boxes[n, 3], query_boxes[k, 3]) - max(boxes[n, 1], query_boxes[k, 1]) + 1
                if ih > 0:
                    box_area = (boxes[n, 2] - boxes[n, 0] + 1) * (boxes[n, 3] - boxes[n, 1] + 1)
                    all_area = float(box_area + query_box_area - iw * ih)
                    overlaps[n, k] = iw * ih / all_area
    return overlaps


def clip_boxes(boxes, im_shape):
    """
    Clip boxes to image boundaries.
    :param boxes: [N, 4* num_classes]
    :param im_shape: tuple of 2
    :return: [N, 4* num_classes]
    """
    # x1 >= 0
    boxes[:, 0::4] = np.maximum(np.minimum(boxes[:, 0::4], im_shape[1] - 1), 0)
    # y1 >= 0
    boxes[:, 1::4] = np.maximum(np.minimum(boxes[:, 1::4], im_shape[0] - 1), 0)
    # x2 < im_shape[1]
    boxes[:, 2::4] = np.maximum(np.minimum(boxes[:, 2::4], im_shape[1] - 1), 0)
    # y2 < im_shape[0]
    boxes[:, 3::4] = np.maximum(np.minimum(boxes[:, 3::4], im_shape[0] - 1), 0)
    return boxes

def clip_points(points, im_shape):
    """
    Clip boxes to image boundaries.
    :param boxes: [N, 4* num_classes]
    :param im_shape: tuple of 2
    :return: [N, 4* num_classes]
    """

    points[:, 0::10] = np.maximum(np.minimum(points[:, 0::10], im_shape[1] - 1), 0)
    points[:, 1::10] = np.maximum(np.minimum(points[:, 1::10], im_shape[0] - 1), 0)
    points[:, 2::10] = np.maximum(np.minimum(points[:, 2::10], im_shape[1] - 1), 0)
    points[:, 3::10] = np.maximum(np.minimum(points[:, 3::10], im_shape[0] - 1), 0)
    points[:, 4::10] = np.maximum(np.minimum(points[:, 4::10], im_shape[1] - 1), 0)
    points[:, 5::10] = np.maximum(np.minimum(points[:, 5::10], im_shape[0] - 1), 0)
    points[:, 6::10] = np.maximum(np.minimum(points[:, 6::10], im_shape[1] - 1), 0)
    points[:, 7::10] = np.maximum(np.minimum(points[:, 7::10], im_shape[0] - 1), 0)
    points[:, 8::10] = np.maximum(np.minimum(points[:, 8::10], im_shape[1] - 1), 0)
    points[:, 9::10] = np.maximum(np.minimum(points[:, 9::10], im_shape[0] - 1), 0)

    return points

def nonlinear_transform(ex_rois, gt_rois):
    """
    compute bounding box regression targets from ex_rois to gt_rois
    :param ex_rois: [N, 4]
    :param gt_rois: [N, 4]
    :return: [N, 4]
    """
    assert ex_rois.shape[0] == gt_rois.shape[0], 'inconsistent rois number'

    ex_widths = ex_rois[:, 2] - ex_rois[:, 0] + 1.0
    ex_heights = ex_rois[:, 3] - ex_rois[:, 1] + 1.0
    ex_ctr_x = ex_rois[:, 0] + 0.5 * (ex_widths - 1.0)
    ex_ctr_y = ex_rois[:, 1] + 0.5 * (ex_heights - 1.0)

    gt_widths = gt_rois[:, 2] - gt_rois[:, 0] + 1.0
    gt_heights = gt_rois[:, 3] - gt_rois[:, 1] + 1.0
    gt_ctr_x = gt_rois[:, 0] + 0.5 * (gt_widths - 1.0)
    gt_ctr_y = gt_rois[:, 1] + 0.5 * (gt_heights - 1.0)

    targets_dx = (gt_ctr_x - ex_ctr_x) / (ex_widths + 1e-14)
    targets_dy = (gt_ctr_y - ex_ctr_y) / (ex_heights + 1e-14)
    targets_dw = np.log(gt_widths / ex_widths)
    targets_dh = np.log(gt_heights / ex_heights)

    targets = np.vstack(
        (targets_dx, targets_dy, targets_dw, targets_dh)).transpose()
    return targets


def nonlinear_pred(boxes, box_deltas):
    """
    Transform the set of class-agnostic boxes into class-specific boxes
    by applying the predicted offsets (box_deltas)
    :param boxes: !important [N 4]
    :param box_deltas: [N, 4 * num_classes]
    :return: [N 4 * num_classes]
    """
    if boxes.shape[0] == 0:
        return np.zeros((0, box_deltas.shape[1]))

    boxes = boxes.astype(np.float, copy=False)
    widths = boxes[:, 2] - boxes[:, 0] + 1.0
    heights = boxes[:, 3] - boxes[:, 1] + 1.0
    ctr_x = boxes[:, 0] + 0.5 * (widths - 1.0)
    ctr_y = boxes[:, 1] + 0.5 * (heights - 1.0)

    dx = box_deltas[:, 0::4]
    dy = box_deltas[:, 1::4]
    dw = box_deltas[:, 2::4]
    dh = box_deltas[:, 3::4]

    pred_ctr_x = dx * widths[:, np.newaxis] + ctr_x[:, np.newaxis]
    pred_ctr_y = dy * heights[:, np.newaxis] + ctr_y[:, np.newaxis]
    pred_w = np.exp(dw) * widths[:, np.newaxis]
    pred_h = np.exp(dh) * heights[:, np.newaxis]

    pred_boxes = np.zeros(box_deltas.shape)
    # x1
    pred_boxes[:, 0::4] = pred_ctr_x - 0.5 * (pred_w - 1.0)
    # y1
    pred_boxes[:, 1::4] = pred_ctr_y - 0.5 * (pred_h - 1.0)
    # x2
    pred_boxes[:, 2::4] = pred_ctr_x + 0.5 * (pred_w - 1.0)
    # y2
    pred_boxes[:, 3::4] = pred_ctr_y + 0.5 * (pred_h - 1.0)

    return pred_boxes

def kpoint_pred(boxes, point_deltas):
    """
    Transform the set of class-agnostic boxes into class-specific boxes
    by applying the predicted offsets (box_deltas)
    :param boxes: !important [N 4]
    :param box_deltas: [N, 4 * num_classes]
    :return: [N 4 * num_classes]
    """
    if boxes.shape[0] == 0:
        return np.zeros((0, point_deltas.shape[1]))

    boxes = boxes.astype(np.float, copy=False)
    widths = boxes[:, 2] - boxes[:, 0] + 1.0
    heights = boxes[:, 3] - boxes[:, 1] + 1.0
    ctr_x = boxes[:, 0] + 0.5 * (widths - 1.0)
    ctr_y = boxes[:, 1] + 0.5 * (heights - 1.0)

    d1x = point_deltas[:, 0]
    d1y = point_deltas[:, 1]
    d2x = point_deltas[:, 2]
    d2y = point_deltas[:, 3]
    d3x = point_deltas[:, 4]
    d3y = point_deltas[:, 5]
    d4x = point_deltas[:, 6]
    d4y = point_deltas[:, 7]
    d5x = point_deltas[:, 8]
    d5y = point_deltas[:, 9]


    pred_points = np.zeros(point_deltas.shape)
    # x1
    x = d1x * widths
    # print("aa", d1x.shape, widths.shape, ctr_x.shape, x.shape)
    pred_points[:, 0] = d1x * widths + ctr_x
    pred_points[:, 1] = d1y * heights + ctr_y
    pred_points[:, 2] = d2x * widths + ctr_x
    pred_points[:, 3] = d2y * heights + ctr_y
    pred_points[:, 4] = d3x * widths + ctr_x
    pred_points[:, 5] = d3y * heights + ctr_y
    pred_points[:, 6] = d4x * widths + ctr_x
    pred_points[:, 7] = d4y * heights + ctr_y
    pred_points[:, 8] = d5x * widths + ctr_x
    pred_points[:, 9] = d5y * heights + ctr_y

    return pred_points

def iou_transform(ex_rois, gt_rois):
    """ return bbox targets, IoU loss uses gt_rois as gt """
    assert ex_rois.shape[0] == gt_rois.shape[0], 'inconsistent rois number'
    return gt_rois


def iou_pred(boxes, box_deltas):
    """
    Transform the set of class-agnostic boxes into class-specific boxes
    by applying the predicted offsets (box_deltas)
    :param boxes: !important [N 4]
    :param box_deltas: [N, 4 * num_classes]
    :return: [N 4 * num_classes]
    """
    if boxes.shape[0] == 0:
        return np.zeros((0, box_deltas.shape[1]))

    boxes = boxes.astype(np.float, copy=False)
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]

    dx1 = box_deltas[:, 0::4]
    dy1 = box_deltas[:, 1::4]
    dx2 = box_deltas[:, 2::4]
    dy2 = box_deltas[:, 3::4]

    pred_boxes = np.zeros(box_deltas.shape)
    # x1
    pred_boxes[:, 0::4] = dx1 + x1[:, np.newaxis]
    # y1
    pred_boxes[:, 1::4] = dy1 + y1[:, np.newaxis]
    # x2
    pred_boxes[:, 2::4] = dx2 + x2[:, np.newaxis]
    # y2
    pred_boxes[:, 3::4] = dy2 + y2[:, np.newaxis]

    return pred_boxes


# define bbox_transform and bbox_pred
bbox_transform = nonlinear_transform
bbox_pred = nonlinear_pred


================================================
FILE: rcnn/processing/generate_anchor.py
================================================
"""
Generate base anchors on index 0
"""
from __future__ import print_function
import sys
#from builtins import range
import numpy as np
from ..cython.anchors import anchors_cython


def anchors_plane(feat_h, feat_w, stride, base_anchor):
    return anchors_cython(feat_h, feat_w, stride, base_anchor)

def generate_anchors(base_size=16, ratios=[0.5, 1, 2],
                     scales=2 ** np.arange(3, 6)):
    """
    Generate anchor (reference) windows by enumerating aspect ratios X
    scales wrt a reference (0, 0, 15, 15) window.
    """

    base_anchor = np.array([1, 1, base_size, base_size]) - 1
    ratio_anchors = _ratio_enum(base_anchor, ratios)
    anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales)
                         for i in range(ratio_anchors.shape[0])])
    return anchors

def generate_anchors_fpn(base_size=[64,32,16,8,4], ratios=[0.5, 1, 2],
                     scales=8):
    """
    Generate anchor (reference) windows by enumerating aspect ratios X
    scales wrt a reference (0, 0, 15, 15) window.
    """
    anchors = []
    _ratios = ratios.reshape( (len(base_size), -1) )
    _scales = scales.reshape( (len(base_size), -1) )
    for i,bs in enumerate(base_size):
      __ratios = _ratios[i]
      __scales = _scales[i]
      #print('anchors_fpn', bs, __ratios, __scales, file=sys.stderr)
      r = generate_anchors(bs, __ratios, __scales)
      #print('anchors_fpn', r.shape, file=sys.stderr)
      anchors.append(r)

    return anchors

def _whctrs(anchor):
    """
    Return width, height, x center, and y center for an anchor (window).
    """

    w = anchor[2] - anchor[0] + 1
    h = anchor[3] - anchor[1] + 1
    x_ctr = anchor[0] + 0.5 * (w - 1)
    y_ctr = anchor[1] + 0.5 * (h - 1)
    return w, h, x_ctr, y_ctr


def _mkanchors(ws, hs, x_ctr, y_ctr):
    """
    Given a vector of widths (ws) and heights (hs) around a center
    (x_ctr, y_ctr), output a set of anchors (windows).
    """

    ws = ws[:, np.newaxis]
    hs = hs[:, np.newaxis]
    anchors = np.hstack((x_ctr - 0.5 * (ws - 1),
                         y_ctr - 0.5 * (hs - 1),
                         x_ctr + 0.5 * (ws - 1),
                         y_ctr + 0.5 * (hs - 1)))
    return anchors


def _ratio_enum(anchor, ratios):
    """
    Enumerate a set of anchors for each aspect ratio wrt an anchor.
    """

    w, h, x_ctr, y_ctr = _whctrs(anchor)
    size = w * h
    size_ratios = size / ratios
    ws = np.round(np.sqrt(size_ratios))
    hs = np.round(ws * ratios)
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    return anchors


def _scale_enum(anchor, scales):
    """
    Enumerate a set of anchors for each scale wrt an anchor.
    """

    w, h, x_ctr, y_ctr = _whctrs(anchor)
    ws = w * scales
    hs = h * scales
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    return anchors


================================================
FILE: rcnn/processing/nms.py
================================================
import numpy as np
from ..cython.cpu_nms import cpu_nms
try:
    from ..cython.gpu_nms import gpu_nms
except ImportError:
    gpu_nms = None


def py_nms_wrapper(thresh):
    def _nms(dets):
        return nms(dets, thresh)
    return _nms


def cpu_nms_wrapper(thresh):
    def _nms(dets):
        return cpu_nms(dets, thresh)
    return _nms


def gpu_nms_wrapper(thresh, device_id):
    def _nms(dets):
        return gpu_nms(dets[:,0:5], thresh, device_id)
    if gpu_nms is not None:
        return _nms
    else:
        return cpu_nms_wrapper(thresh)


def nms(dets, thresh):
    """
    greedily select boxes with high confidence and overlap with current maximum <= thresh
    rule out overlap >= thresh
    :param dets: [[x1, y1, x2, y2 score]]
    :param thresh: retain overlap < thresh
    :return: indexes to keep
    """
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]

    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    order = scores.argsort()[::-1]

    keep = []
    while order.size > 0:
        i = order[0]
        keep.append(i)
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])

        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = w * h
        ovr = inter / (areas[i] + areas[order[1:]] - inter)

        inds = np.where(ovr <= thresh)[0]
        order = order[inds + 1]

    return keep


================================================
FILE: ssha_detector.py
================================================
from __future__ import print_function
import sys
import cv2
import mxnet as mx
from mxnet import ndarray as nd
import numpy as np
import numpy.random as npr
from distutils.util import strtobool

from rcnn.processing.bbox_transform import nonlinear_pred, clip_boxes, kpoint_pred, clip_points
from rcnn.processing.generate_anchor import generate_anchors_fpn, anchors_plane
from rcnn.processing.nms import gpu_nms_wrapper


class SSHDetector:
    def __init__(self, prefix, epoch, ctx_id=0, test_mode=False):
        self.ctx_id = ctx_id
        self.ctx = mx.gpu(self.ctx_id)
        self.fpn_keys = []
        fpn_stride = []
        fpn_base_size = []
        self._feat_stride_fpn = [32, 16, 8]

        for s in self._feat_stride_fpn:
            self.fpn_keys.append('stride%s' % s)
            fpn_stride.append(int(s))
            fpn_base_size.append(16)

        self._scales = np.array([32, 16, 8, 4, 2, 1])
        self._ratios = np.array([1.0] * len(self._feat_stride_fpn))
        self._anchors_fpn = dict(
            zip(self.fpn_keys, generate_anchors_fpn(base_size=fpn_base_size, scales=self._scales, ratios=self._ratios)))
        self._num_anchors = dict(zip(self.fpn_keys, [anchors.shape[0] for anchors in self._anchors_fpn.values()]))
        self._rpn_pre_nms_top_n = 1000
        # self._rpn_post_nms_top_n = rpn_post_nms_top_n
        # self.score_threshold = 0.05
        self.nms_threshold = 0.3
        self._bbox_pred = nonlinear_pred
        sym, arg_params, aux_params = mx.model.load_checkpoint(prefix, epoch)
        # mx.viz.plot_network(sym).view()
        self.nms = gpu_nms_wrapper(self.nms_threshold, self.ctx_id)
        self.pixel_means = np.array([103.939, 116.779, 123.68])  # BGR

        if not test_mode:
            image_size = (640, 640)
            self.model = mx.mod.Module(symbol=sym, context=self.ctx, label_names=None)
            self.model.bind(data_shapes=[('data', (1, 3, image_size[0], image_size[1]))], for_training=False)
            self.model.set_params(arg_params, aux_params)
        else:
            from rcnn.core.module import MutableModule
            image_size = (2400, 2400)
            data_shape = [('data', (1, 3, image_size[0], image_size[1]))]
            self.model = MutableModule(symbol=sym, data_names=['data'], label_names=None,
                                       context=self.ctx, max_data_shapes=data_shape)
            self.model.bind(data_shape, None, for_training=False)
            self.model.set_params(arg_params, aux_params)

    def detect(self, img, threshold=0.5, scales=[1.0]):
        proposals_list = []
        proposals_kp_list = []
        scores_list = []

        for im_scale in scales:

            if im_scale != 1.0:
                im = cv2.resize(img, None, None, fx=im_scale, fy=im_scale, interpolation=cv2.INTER_LINEAR)
            else:
                im = img
            im = im.astype(np.float32)
            # self.model.bind(data_shapes=[('data', (1, 3, image_size[0], image_size[1]))], for_training=False)
            im_info = [im.shape[0], im.shape[1], im_scale]
            im_tensor = np.zeros((1, 3, im.shape[0], im.shape[1]))
            for i in range(3):
                im_tensor[0, i, :, :] = im[:, :, 2 - i] - self.pixel_means[2 - i]
            data = nd.array(im_tensor)
            print("data.shape: ", data.shape)
            db = mx.io.DataBatch(data=(data,), provide_data=[('data', data.shape)])
            self.model.forward(db, is_train=False)
            net_out = self.model.get_outputs()
            # print("net_out: ", net_out)
            pre_nms_topN = self._rpn_pre_nms_top_n
            # post_nms_topN = self._rpn_post_nms_top_n
            # min_size_dict = self._rpn_min_size_fpn

            for s in self._feat_stride_fpn:
                if len(scales) > 1 and s == 32 and im_scale == scales[-1]:
                    continue
                _key = 'stride%s' % s
                stride = int(s)
                idx = 0
                if s == 16:
                    idx = 3
                elif s == 8:
                    idx = 6
                print('getting', im_scale, stride, idx, len(net_out), data.shape, file=sys.stderr)

                # print("net_out", net_out)
                scores = net_out[idx].asnumpy()
                # print(scores.shape)
                idx += 1
                # print('scores',stride, scores.shape, file=sys.stderr)
                scores = scores[:, self._num_anchors['stride%s' % s]:, :, :]
                bbox_deltas = net_out[idx].asnumpy()
                idx += 1

                # if DEBUG:
                #    print 'im_size: ({}, {})'.format(im_info[0], im_info[1])
                #    print 'scale: {}'.format(im_info[2])

                _height, _width = int(im_info[0] / stride), int(im_info[1] / stride)
                height, width = bbox_deltas.shape[2], bbox_deltas.shape[3]

                # kpoint
                kpoint_deltas = net_out[idx].asnumpy()


                A = self._num_anchors['stride%s' % s]
                K = height * width

                anchors = anchors_plane(height, width, stride, self._anchors_fpn['stride%s' % s].astype(np.float32))
                # print((height, width), (_height, _width), anchors.shape, bbox_deltas.shape, scores.shape, file=sys.stderr)
                anchors = anchors.reshape((K * A, 4))
                # print('pre', bbox_deltas.shape, height, width)
                bbox_deltas = self._clip_pad(bbox_deltas, (height, width))
                # print('after', bbox_deltas.shape, height, width)
                bbox_deltas = bbox_deltas.transpose((0, 2, 3, 1)).reshape((-1, 4))

                kpoint_deltas = self._clip_pad(kpoint_deltas, (height, width))
                kpoint_deltas = kpoint_deltas.transpose((0, 2, 3, 1)).reshape((-1, 10))

                scores = self._clip_pad(scores, (height, width))
                scores = scores.transpose((0, 2, 3, 1)).reshape((-1, 1))

                # print(anchors.shape, bbox_deltas.shape, A, K, file=sys.stderr)
                proposals = self._bbox_pred(anchors, bbox_deltas)
                # proposals = anchors

                proposals = clip_boxes(proposals, im_info[:2])

                proposals_kp = kpoint_pred(anchors, kpoint_deltas)

                proposals_kp = clip_points(proposals_kp, im_info[:2])

                # keep = self._filter_boxes(proposals, min_size_dict['stride%s'%s] * im_info[2])
                # proposals = proposals[keep, :]
                # scores = scores[keep]
                # print('333', proposals.shape)

                scores_ravel = scores.ravel()
                order = scores_ravel.argsort()[::-1]
                if pre_nms_topN > 0:
                    order = order[:pre_nms_topN]
                proposals = proposals[order, :]
                proposals_kp = proposals_kp[order, :]
                scores = scores[order]

                proposals /= im_scale
                proposals_kp /= im_scale

                proposals_list.append(proposals)
                proposals_kp_list.append(proposals_kp)
                scores_list.append(scores)

        proposals = np.vstack(proposals_list)
        proposals_kp = np.vstack(proposals_kp_list)
        scores = np.vstack(scores_list)
        scores_ravel = scores.ravel()
        order = scores_ravel.argsort()[::-1]
        # if config.TEST.SCORE_THRESH>0.0:
        #  _count = np.sum(scores_ravel>config.TEST.SCORE_THRESH)
        #  order = order[:_count]
        # if pre_nms_topN > 0:
        #    order = order[:pre_nms_topN]
        proposals = proposals[order, :]
        proposals_kp = proposals_kp[order, :]
        scores = scores[order]

        det = np.hstack((proposals, scores, proposals_kp)).astype(np.float32)

        # if np.shape(det)[0] == 0:
        #    print("Something wrong with the input image(resolution is too low?), generate fake proposals for it.")
        #    proposals = np.array([[1.0, 1.0, 2.0, 2.0]]*post_nms_topN, dtype=np.float32)
        #    scores = np.array([[0.9]]*post_nms_topN, dtype=np.float32)
        #    det = np.array([[1.0, 1.0, 2.0, 2.0, 0.9]]*post_nms_topN, dtype=np.float32)

        if self.nms_threshold < 1.0:
            keep = self.nms(det)
            det = det[keep, :]
        if threshold > 0.0:
            keep = np.where(det[:, 4] >= threshold)[0]
            det = det[keep, :]
        return det

    @staticmethod
    def _filter_boxes(boxes, min_size):
        """ Remove all boxes with any side smaller than min_size """
        ws = boxes[:, 2] - boxes[:, 0] + 1
        hs = boxes[:, 3] - boxes[:, 1] + 1
        keep = np.where((ws >= min_size) & (hs >= min_size))[0]
        return keep

    @staticmethod
    def _clip_pad(tensor, pad_shape):
        """
        Clip boxes of the pad area.
        :param tensor: [n, c, H, W]
        :param pad_shape: [h, w]
        :return: [n, c, h, w]
        """
        H, W = tensor.shape[2:]
        h, w = pad_shape

        if h < H or w < W:
            tensor = tensor[:, :, :h, :w].copy()

        return tensor


================================================
FILE: test_kpoint.py
================================================
import cv2
import sys
import numpy as np
import datetime
#sys.path.append('.')
from ssha_detector import SSHDetector

scales = [1200, 1600]
# scales = [200, 600]
t = 2
detector = SSHDetector('./kmodel/e2e', 0)



f = '../sample-images/t1.jpg'
f = 'test_image/test_2.jpg'
if len(sys.argv)>1:
  f = sys.argv[1]
img = cv2.imread(f)
im_shape = img.shape
print(im_shape)
target_size = scales[0]
max_size = scales[1]
im_size_min = np.min(im_shape[0:2])
im_size_max = np.max(im_shape[0:2])
# cv2.copyMakeBorder()
img = cv2.copyMakeBorder(img, 5, 5, 5, 5, borderType=cv2.BORDER_CONSTANT, value=[0,0,0])
if im_size_min>target_size or im_size_max>max_size:
  im_scale = float(target_size) / float(im_size_min)
  # prevent bigger axis from being more than max_size:
  if np.round(im_scale * im_size_max) > max_size:
      im_scale = float(max_size) / float(im_size_max)
  img = cv2.resize(img, None, None, fx=im_scale, fy=im_scale)
  print('resize to', img.shape)
# for i in xrange(t-1): #warmup
#   faces = detector.detect(img)
timea = datetime.datetime.now()
faces = detector.detect(img, threshold=0.8)
timeb = datetime.datetime.now()
for num in range(faces.shape[0]):
  bbox = faces[num, 0:4]
  cv2.rectangle(img, (bbox[0],bbox[1]),(bbox[2], bbox[3]), (0,255, 0), 2)
  kpoint = faces[num, 5:15]
  for knum in range(5):
      cv2.circle(img, (kpoint[2*knum], kpoint[2*knum+1]), 1, [0,0,255], 2)

cv2.imwrite("res.jpg", img[5:-5,5:-5,:])
diff = timeb - timea
print('detection uses', diff.total_seconds(), 'seconds')
print('find', faces.shape[0], 'faces')
Download .txt
gitextract_ddu7n4mp/

├── Makefile
├── README.md
├── __init__.py
├── kmodel/
│   ├── e2e-0000.params
│   └── e2e-symbol.json
├── rcnn/
│   ├── __init__.py
│   ├── cython/
│   │   ├── .gitignore
│   │   ├── __init__.py
│   │   ├── anchors.pyx
│   │   ├── bbox.pyx
│   │   ├── cpu_nms.pyx
│   │   ├── gpu_nms.hpp
│   │   ├── gpu_nms.pyx
│   │   ├── nms_kernel.cu
│   │   └── setup.py
│   └── processing/
│       ├── __init__.py
│       ├── bbox_regression.py
│       ├── bbox_transform.py
│       ├── generate_anchor.py
│       └── nms.py
├── ssha_detector.py
└── test_kpoint.py
Download .txt
SYMBOL INDEX (33 symbols across 6 files)

FILE: rcnn/cython/setup.py
  function find_in_path (line 16) | def find_in_path(name, path):
  function locate_cuda (line 27) | def locate_cuda():
  function customize_compiler_for_nvcc (line 74) | def customize_compiler_for_nvcc(self):
  class custom_build_ext (line 113) | class custom_build_ext(build_ext):
    method build_extensions (line 114) | def build_extensions(self):

FILE: rcnn/processing/bbox_regression.py
  function compute_bbox_regression_targets (line 12) | def compute_bbox_regression_targets(rois, overlaps, labels):
  function add_bbox_regression_targets (line 50) | def add_bbox_regression_targets(roidb):
  function expand_bbox_regression_targets (line 101) | def expand_bbox_regression_targets(bbox_targets_data, num_classes):

FILE: rcnn/processing/bbox_transform.py
  function bbox_overlaps (line 5) | def bbox_overlaps(boxes, query_boxes):
  function bbox_overlaps_py (line 9) | def bbox_overlaps_py(boxes, query_boxes):
  function clip_boxes (line 32) | def clip_boxes(boxes, im_shape):
  function clip_points (line 49) | def clip_points(points, im_shape):
  function nonlinear_transform (line 70) | def nonlinear_transform(ex_rois, gt_rois):
  function nonlinear_pred (line 99) | def nonlinear_pred(boxes, box_deltas):
  function kpoint_pred (line 138) | def kpoint_pred(boxes, point_deltas):
  function iou_transform (line 184) | def iou_transform(ex_rois, gt_rois):
  function iou_pred (line 190) | def iou_pred(boxes, box_deltas):

FILE: rcnn/processing/generate_anchor.py
  function anchors_plane (line 11) | def anchors_plane(feat_h, feat_w, stride, base_anchor):
  function generate_anchors (line 14) | def generate_anchors(base_size=16, ratios=[0.5, 1, 2],
  function generate_anchors_fpn (line 27) | def generate_anchors_fpn(base_size=[64,32,16,8,4], ratios=[0.5, 1, 2],
  function _whctrs (line 46) | def _whctrs(anchor):
  function _mkanchors (line 58) | def _mkanchors(ws, hs, x_ctr, y_ctr):
  function _ratio_enum (line 73) | def _ratio_enum(anchor, ratios):
  function _scale_enum (line 87) | def _scale_enum(anchor, scales):

FILE: rcnn/processing/nms.py
  function py_nms_wrapper (line 9) | def py_nms_wrapper(thresh):
  function cpu_nms_wrapper (line 15) | def cpu_nms_wrapper(thresh):
  function gpu_nms_wrapper (line 21) | def gpu_nms_wrapper(thresh, device_id):
  function nms (line 30) | def nms(dets, thresh):

FILE: ssha_detector.py
  class SSHDetector (line 15) | class SSHDetector:
    method __init__ (line 16) | def __init__(self, prefix, epoch, ctx_id=0, test_mode=False):
    method detect (line 58) | def detect(self, img, threshold=0.5, scales=[1.0]):
    method _filter_boxes (line 195) | def _filter_boxes(boxes, min_size):
    method _clip_pad (line 203) | def _clip_pad(tensor, pad_shape):
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (94K chars).
[
  {
    "path": "Makefile",
    "chars": 266,
    "preview": "all:\n\tcd rcnn/cython/; python setup.py build_ext --inplace; rm -rf build; cd ../../\n\t#cd rcnn/pycocotools/; python setup"
  },
  {
    "path": "README.md",
    "chars": 416,
    "preview": "# SSHA, SSH with Alignment\n\n## Result\n\n![img0](res2.jpg)\n![img1](res1.jpg)\n![img2](res0.jpg)\n\n## How To Use\n#### 0. inst"
  },
  {
    "path": "__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "kmodel/e2e-symbol.json",
    "chars": 39339,
    "preview": "{\n  \"nodes\": [\n    {\n      \"op\": \"null\", \n      \"name\": \"data\", \n      \"inputs\": []\n    }, \n    {\n      \"op\": \"null\", \n "
  },
  {
    "path": "rcnn/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "rcnn/cython/.gitignore",
    "chars": 15,
    "preview": "*.c\n*.cpp\n*.so\n"
  },
  {
    "path": "rcnn/cython/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "rcnn/cython/anchors.pyx",
    "chars": 1185,
    "preview": "cimport cython\nimport numpy as np\ncimport numpy as np\n\nDTYPE = np.float32\nctypedef np.float32_t DTYPE_t\n\ndef anchors_cyt"
  },
  {
    "path": "rcnn/cython/bbox.pyx",
    "chars": 1763,
    "preview": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under "
  },
  {
    "path": "rcnn/cython/cpu_nms.pyx",
    "chars": 2241,
    "preview": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under "
  },
  {
    "path": "rcnn/cython/gpu_nms.hpp",
    "chars": 146,
    "preview": "void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num,\n          int boxes_dim, float nms_overla"
  },
  {
    "path": "rcnn/cython/gpu_nms.pyx",
    "chars": 1110,
    "preview": "# --------------------------------------------------------\n# Faster R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed unde"
  },
  {
    "path": "rcnn/cython/nms_kernel.cu",
    "chars": 5064,
    "preview": "// ------------------------------------------------------------------\n// Faster R-CNN\n// Copyright (c) 2015 Microsoft\n//"
  },
  {
    "path": "rcnn/cython/setup.py",
    "chars": 5748,
    "preview": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under "
  },
  {
    "path": "rcnn/processing/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "rcnn/processing/bbox_regression.py",
    "chars": 4734,
    "preview": "\"\"\"\nThis file has functions about generating bounding box regression targets\n\"\"\"\n\nimport numpy as np\n\nfrom ..logger impo"
  },
  {
    "path": "rcnn/processing/bbox_transform.py",
    "chars": 7890,
    "preview": "import numpy as np\nfrom ..cython.bbox import bbox_overlaps_cython\n\n\ndef bbox_overlaps(boxes, query_boxes):\n    return bb"
  },
  {
    "path": "rcnn/processing/generate_anchor.py",
    "chars": 2830,
    "preview": "\"\"\"\nGenerate base anchors on index 0\n\"\"\"\nfrom __future__ import print_function\nimport sys\n#from builtins import range\nim"
  },
  {
    "path": "rcnn/processing/nms.py",
    "chars": 1550,
    "preview": "import numpy as np\nfrom ..cython.cpu_nms import cpu_nms\ntry:\n    from ..cython.gpu_nms import gpu_nms\nexcept ImportError"
  },
  {
    "path": "ssha_detector.py",
    "chars": 9086,
    "preview": "from __future__ import print_function\nimport sys\nimport cv2\nimport mxnet as mx\nfrom mxnet import ndarray as nd\nimport nu"
  },
  {
    "path": "test_kpoint.py",
    "chars": 1545,
    "preview": "import cv2\nimport sys\nimport numpy as np\nimport datetime\n#sys.path.append('.')\nfrom ssha_detector import SSHDetector\n\nsc"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the ElegantGod/SSHA GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (75.6 MB), approximately 28.5k tokens, and a symbol index with 33 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!