00001
00002
00003
00004
00005
00006
00007 import os
00008 import chainer
00009 import chainer.functions as F
00010 import chainer.links as L
00011
00012
00013 base_url = 'http://posefs1.perception.cs.cmu.edu/OpenPose/models/hand/'
00014 models = {
00015 'auto': 'pose_iter_102000.chainermodel',
00016 }
00017
00018
00019 class HandNet(chainer.Chain):
00020
00021 def __init__(self, pretrained_model='auto'):
00022 super(HandNet, self).__init__()
00023 with self.init_scope():
00024 self.conv1_1 = L.Convolution2D(
00025 in_channels=3, out_channels=64, ksize=3, stride=1, pad=1)
00026 self.conv1_2 = L.Convolution2D(
00027 in_channels=64, out_channels=64, ksize=3, stride=1, pad=1)
00028 self.conv2_1 = L.Convolution2D(
00029 in_channels=64, out_channels=128, ksize=3, stride=1, pad=1)
00030 self.conv2_2 = L.Convolution2D(
00031 in_channels=128, out_channels=128, ksize=3, stride=1, pad=1)
00032 self.conv3_1 = L.Convolution2D(
00033 in_channels=128, out_channels=256, ksize=3, stride=1, pad=1)
00034 self.conv3_2 = L.Convolution2D(
00035 in_channels=256, out_channels=256, ksize=3, stride=1, pad=1)
00036 self.conv3_3 = L.Convolution2D(
00037 in_channels=256, out_channels=256, ksize=3, stride=1, pad=1)
00038 self.conv3_4 = L.Convolution2D(
00039 in_channels=256, out_channels=256, ksize=3, stride=1, pad=1)
00040 self.conv4_1 = L.Convolution2D(
00041 in_channels=256, out_channels=512, ksize=3, stride=1, pad=1)
00042 self.conv4_2 = L.Convolution2D(
00043 in_channels=512, out_channels=512, ksize=3, stride=1, pad=1)
00044 self.conv4_3 = L.Convolution2D(
00045 in_channels=512, out_channels=512, ksize=3, stride=1, pad=1)
00046 self.conv4_4 = L.Convolution2D(
00047 in_channels=512, out_channels=512, ksize=3, stride=1, pad=1)
00048 self.conv5_1 = L.Convolution2D(
00049 in_channels=512, out_channels=512, ksize=3, stride=1, pad=1)
00050 self.conv5_2 = L.Convolution2D(
00051 in_channels=512, out_channels=512, ksize=3, stride=1, pad=1)
00052 self.conv5_3_CPM = L.Convolution2D(
00053 in_channels=512, out_channels=128, ksize=3, stride=1, pad=1)
00054
00055 self.conv6_1_CPM = L.Convolution2D(
00056 in_channels=128, out_channels=512, ksize=1, stride=1, pad=0)
00057 self.conv6_2_CPM = L.Convolution2D(
00058 in_channels=512, out_channels=22, ksize=1, stride=1, pad=0)
00059
00060 self.Mconv1_stage2 = L.Convolution2D(
00061 in_channels=150, out_channels=128, ksize=7, stride=1, pad=3)
00062 self.Mconv2_stage2 = L.Convolution2D(
00063 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00064 self.Mconv3_stage2 = L.Convolution2D(
00065 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00066 self.Mconv4_stage2 = L.Convolution2D(
00067 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00068 self.Mconv5_stage2 = L.Convolution2D(
00069 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00070 self.Mconv6_stage2 = L.Convolution2D(
00071 in_channels=128, out_channels=128, ksize=1, stride=1, pad=0)
00072 self.Mconv7_stage2 = L.Convolution2D(
00073 in_channels=128, out_channels=22, ksize=1, stride=1, pad=0)
00074
00075 self.Mconv1_stage3 = L.Convolution2D(
00076 in_channels=150, out_channels=128, ksize=7, stride=1, pad=3)
00077 self.Mconv2_stage3 = L.Convolution2D(
00078 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00079 self.Mconv3_stage3 = L.Convolution2D(
00080 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00081 self.Mconv4_stage3 = L.Convolution2D(
00082 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00083 self.Mconv5_stage3 = L.Convolution2D(
00084 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00085 self.Mconv6_stage3 = L.Convolution2D(
00086 in_channels=128, out_channels=128, ksize=1, stride=1, pad=0)
00087 self.Mconv7_stage3 = L.Convolution2D(
00088 in_channels=128, out_channels=22, ksize=1, stride=1, pad=0)
00089
00090 self.Mconv1_stage4 = L.Convolution2D(
00091 in_channels=150, out_channels=128, ksize=7, stride=1, pad=3)
00092 self.Mconv2_stage4 = L.Convolution2D(
00093 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00094 self.Mconv3_stage4 = L.Convolution2D(
00095 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00096 self.Mconv4_stage4 = L.Convolution2D(
00097 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00098 self.Mconv5_stage4 = L.Convolution2D(
00099 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00100 self.Mconv6_stage4 = L.Convolution2D(
00101 in_channels=128, out_channels=128, ksize=1, stride=1, pad=0)
00102 self.Mconv7_stage4 = L.Convolution2D(
00103 in_channels=128, out_channels=22, ksize=1, stride=1, pad=0)
00104
00105 self.Mconv1_stage5 = L.Convolution2D(
00106 in_channels=150, out_channels=128, ksize=7, stride=1, pad=3)
00107 self.Mconv2_stage5 = L.Convolution2D(
00108 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00109 self.Mconv3_stage5 = L.Convolution2D(
00110 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00111 self.Mconv4_stage5 = L.Convolution2D(
00112 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00113 self.Mconv5_stage5 = L.Convolution2D(
00114 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00115 self.Mconv6_stage5 = L.Convolution2D(
00116 in_channels=128, out_channels=128, ksize=1, stride=1, pad=0)
00117 self.Mconv7_stage5 = L.Convolution2D(
00118 in_channels=128, out_channels=22, ksize=1, stride=1, pad=0)
00119
00120 self.Mconv1_stage6 = L.Convolution2D(
00121 in_channels=150, out_channels=128, ksize=7, stride=1, pad=3)
00122 self.Mconv2_stage6 = L.Convolution2D(
00123 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00124 self.Mconv3_stage6 = L.Convolution2D(
00125 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00126 self.Mconv4_stage6 = L.Convolution2D(
00127 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00128 self.Mconv5_stage6 = L.Convolution2D(
00129 in_channels=128, out_channels=128, ksize=7, stride=1, pad=3)
00130 self.Mconv6_stage6 = L.Convolution2D(
00131 in_channels=128, out_channels=128, ksize=1, stride=1, pad=0)
00132 self.Mconv7_stage6 = L.Convolution2D(
00133 in_channels=128, out_channels=22, ksize=1, stride=1, pad=0)
00134
00135 if pretrained_model in models.keys():
00136 data_dir = chainer.dataset.get_dataset_directory('openpose/hand')
00137 model_path = os.path.join(data_dir, models[pretrained_model])
00138 try:
00139 os.makedirs(os.path.dirname(model_path))
00140 except OSError:
00141 pass
00142 chainer.dataset.cache_or_load_file(
00143 model_path,
00144 lambda f: _download_pretrained_model(pretrained_model, f),
00145 lambda f: f)
00146 chainer.serializers.load_npz(model_path, self)
00147 elif pretrained_model is not None:
00148 if not os.path.exists(pretrained_model):
00149 raise OSError('model does not exists: "%s"' % pretrained_model)
00150 chainer.serializers.load_npz(pretrained_model, self)
00151
00152 def __call__(self, x):
00153 heatmaps = []
00154
00155 h = F.relu(self.conv1_1(x))
00156 h = F.relu(self.conv1_2(h))
00157 h = F.max_pooling_2d(h, ksize=2, stride=2)
00158 h = F.relu(self.conv2_1(h))
00159 h = F.relu(self.conv2_2(h))
00160 h = F.max_pooling_2d(h, ksize=2, stride=2)
00161 h = F.relu(self.conv3_1(h))
00162 h = F.relu(self.conv3_2(h))
00163 h = F.relu(self.conv3_3(h))
00164 h = F.relu(self.conv3_4(h))
00165 h = F.max_pooling_2d(h, ksize=2, stride=2)
00166 h = F.relu(self.conv4_1(h))
00167 h = F.relu(self.conv4_2(h))
00168 h = F.relu(self.conv4_3(h))
00169 h = F.relu(self.conv4_4(h))
00170 h = F.relu(self.conv5_1(h))
00171 h = F.relu(self.conv5_2(h))
00172 h = F.relu(self.conv5_3_CPM(h))
00173 feature_map = h
00174
00175
00176 h = F.relu(self.conv6_1_CPM(h))
00177 h = self.conv6_2_CPM(h)
00178 heatmaps.append(h)
00179
00180
00181 h = F.concat((h, feature_map), axis=1)
00182 h = F.relu(self.Mconv1_stage2(h))
00183 h = F.relu(self.Mconv2_stage2(h))
00184 h = F.relu(self.Mconv3_stage2(h))
00185 h = F.relu(self.Mconv4_stage2(h))
00186 h = F.relu(self.Mconv5_stage2(h))
00187 h = F.relu(self.Mconv6_stage2(h))
00188 h = self.Mconv7_stage2(h)
00189 heatmaps.append(h)
00190
00191
00192 h = F.concat((h, feature_map), axis=1)
00193 h = F.relu(self.Mconv1_stage3(h))
00194 h = F.relu(self.Mconv2_stage3(h))
00195 h = F.relu(self.Mconv3_stage3(h))
00196 h = F.relu(self.Mconv4_stage3(h))
00197 h = F.relu(self.Mconv5_stage3(h))
00198 h = F.relu(self.Mconv6_stage3(h))
00199 h = self.Mconv7_stage3(h)
00200 heatmaps.append(h)
00201
00202
00203 h = F.concat((h, feature_map), axis=1)
00204 h = F.relu(self.Mconv1_stage4(h))
00205 h = F.relu(self.Mconv2_stage4(h))
00206 h = F.relu(self.Mconv3_stage4(h))
00207 h = F.relu(self.Mconv4_stage4(h))
00208 h = F.relu(self.Mconv5_stage4(h))
00209 h = F.relu(self.Mconv6_stage4(h))
00210 h = self.Mconv7_stage4(h)
00211 heatmaps.append(h)
00212
00213
00214 h = F.concat((h, feature_map), axis=1)
00215 h = F.relu(self.Mconv1_stage5(h))
00216 h = F.relu(self.Mconv2_stage5(h))
00217 h = F.relu(self.Mconv3_stage5(h))
00218 h = F.relu(self.Mconv4_stage5(h))
00219 h = F.relu(self.Mconv5_stage5(h))
00220 h = F.relu(self.Mconv6_stage5(h))
00221 h = self.Mconv7_stage5(h)
00222 heatmaps.append(h)
00223
00224
00225 h = F.concat((h, feature_map), axis=1)
00226 h = F.relu(self.Mconv1_stage6(h))
00227 h = F.relu(self.Mconv2_stage6(h))
00228 h = F.relu(self.Mconv3_stage6(h))
00229 h = F.relu(self.Mconv4_stage6(h))
00230 h = F.relu(self.Mconv5_stage6(h))
00231 h = F.relu(self.Mconv6_stage6(h))
00232 h = self.Mconv7_stage6(h)
00233 heatmaps.append(h)
00234
00235 return heatmaps
00236
00237
00238 def _download_pretrained_model(model_type, dest_path):
00239 from chainer.links import caffe
00240
00241 if os.path.exists(dest_path):
00242 raise OSError('destination already exists: %s' % dest_path)
00243
00244 basename, ext = os.path.splitext(models[model_type])
00245 url = base_url + basename + '.caffemodel'
00246 caffe_model_path = chainer.dataset.cached_download(url)
00247 if not os.path.exists(caffe_model_path):
00248 raise OSError('caffe model does not exist: %s' % caffe_model_path)
00249
00250 print('Converting to chainer model')
00251 caffe_model = caffe.CaffeFunction(caffe_model_path)
00252 chainer_model = HandNet(pretrained_model=None)
00253 for link in chainer_model.links():
00254 if not isinstance(link, chainer.Link) or not link.name:
00255 continue
00256 if eval('chainer_model.{0}.b.shape == caffe_model["{0}"].b.shape'.format(link.name)) and\
00257 eval('chainer_model.{0}.W.shape == caffe_model["{0}"].W.shape'.format(link.name)):
00258 exec('chainer_model.{0}.W.data = caffe_model["{0}"].W.data'.format(link.name))
00259 exec('chainer_model.{0}.b.data = caffe_model["{0}"].b.data'.format(link.name))
00260 print('Copied layer {0}'.format(link.name))
00261 else:
00262 print('Failed to copy layer {0}'.format(link.name))
00263
00264 chainer.serializers.save_npz(dest_path, chainer_model)
00265 return True