前提・実現したいこと
ここに質問の内容を詳しく書いてください。
Face APIによる顔認識をPythonで行っています。
サンプルプログラムを実行したところ構文エラーが出て解決できずに困っています。
発生している問題・エラーメッセージ
Traceback(most recent call last): File "プログラム名.py", line 41, in <module> fr = face["faceRectangle"] TypeError: string indices must be integers
該当のソースコード
python
1 2import requests 3# If you are using a Jupyter notebook, uncomment the following line. 4#%matplotlib inline 5import matplotlib.pyplot as plt 6from PIL import Image 7from matplotlib import patches 8from io import BytesIO 9 10# Replace <Subscription Key> with your valid subscription key. 11subscription_key = "<Subscription Key>" 12assert subscription_key 13 14# You must use the same region in your REST call as you used to get your 15# subscription keys. For example, if you got your subscription keys from 16# westus, replace "westcentralus" in the URI below with "westus". 17# 18# Free trial subscription keys are generated in the westcentralus region. 19# If you use a free trial subscription key, you shouldn't need to change 20# this region. 21face_api_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect' 22 23# Set image_url to the URL of an image that you want to analyze. 24image_url = 'https://how-old.net/Images/faces2/main007.jpg' 25 26headers = {'Ocp-Apim-Subscription-Key': subscription_key} 27params = { 28 'returnFaceId': 'true', 29 'returnFaceLandmarks': 'false', 30 'returnFaceAttributes': 'age,gender,headPose,smile,facialHair,glasses,' + 31 'emotion,hair,makeup,occlusion,accessories,blur,exposure,noise' 32} 33data = {'url': image_url} 34response = requests.post(face_api_url, params=params, headers=headers, json=data) 35faces = response.json() 36 37# Display the original image and overlay it with the face information. 38image = Image.open(BytesIO(requests.get(image_url).content)) 39plt.figure(figsize=(8, 8)) 40ax = plt.imshow(image, alpha=0.6) 41for face in faces: 42 fr = face["faceRectangle"] 43 fa = face["faceAttributes"] 44 origin = (fr["left"], fr["top"]) 45 p = patches.Rectangle( 46 origin, fr["width"], fr["height"], fill=False, linewidth=2, color='b') 47 ax.axes.add_patch(p) 48 plt.text(origin[0], origin[1], "%s, %d"%(fa["gender"].capitalize(), fa["age"]), 49 fontsize=20, weight="bold", va="bottom") 50_ = plt.axis("off") 51 52 53<<追記 JSONの中身>> 54[ 55 { 56 "faceId": "35102aa8-4263-4139-bfd6-185bb0f52d88", 57 "faceRectangle": { 58 "top": 208, 59 "left": 228, 60 "width": 91, 61 "height": 91 62 }, 63 "faceAttributes": { 64 "smile": 1, 65 "headPose": { 66 "pitch": 0, 67 "roll": 4.3, 68 "yaw": -0.3 69 }, 70 "gender": "female", 71 "age": 27, 72 "facialHair": { 73 "moustache": 0, 74 "beard": 0, 75 "sideburns": 0 76 }, 77 "glasses": "NoGlasses", 78 "emotion": { 79 "anger": 0, 80 "contempt": 0, 81 "disgust": 0, 82 "fear": 0, 83 "happiness": 1, 84 "neutral": 0, 85 "sadness": 0, 86 "surprise": 0 87 }, 88 "blur": { 89 "blurLevel": "low", 90 "value": 0 91 }, 92 "exposure": { 93 "exposureLevel": "goodExposure", 94 "value": 0.65 95 }, 96 "noise": { 97 "noiseLevel": "low", 98 "value": 0 99 }, 100 "makeup": { 101 "eyeMakeup": true, 102 "lipMakeup": true 103 }, 104 "accessories": [], 105 "occlusion": { 106 "foreheadOccluded": false, 107 "eyeOccluded": false, 108 "mouthOccluded": false 109 }, 110 "hair": { 111 "bald": 0.06, 112 "invisible": false, 113 "hairColor": [ 114 { 115 "color": "brown", 116 "confidence": 1 117 }, 118 { 119 "color": "blond", 120 "confidence": 0.5 121 }, 122 { 123 "color": "black", 124 "confidence": 0.34 125 }, 126 { 127 "color": "red", 128 "confidence": 0.32 129 }, 130 { 131 "color": "gray", 132 "confidence": 0.14 133 }, 134 { 135 "color": "other", 136 "confidence": 0.03 137 } 138 ] 139 } 140 } 141 }, 142 { 143 "faceId": "42502166-31bb-4ac8-81c0-a7adcb3b3e70", 144 "faceRectangle": { 145 "top": 109, 146 "left": 125, 147 "width": 79, 148 "height": 79 149 }, 150 "faceAttributes": { 151 "smile": 1, 152 "headPose": { 153 "pitch": 0, 154 "roll": 1.7, 155 "yaw": 2.1 156 }, 157 "gender": "male", 158 "age": 32, 159 "facialHair": { 160 "moustache": 0.4, 161 "beard": 0.4, 162 "sideburns": 0.4 163 }, 164 "glasses": "NoGlasses", 165 "emotion": { 166 "anger": 0, 167 "contempt": 0, 168 "disgust": 0, 169 "fear": 0, 170 "happiness": 1, 171 "neutral": 0, 172 "sadness": 0, 173 "surprise": 0 174 }, 175 "blur": { 176 "blurLevel": "low", 177 "value": 0.11 178 }, 179 "exposure": { 180 "exposureLevel": "goodExposure", 181 "value": 0.74 182 }, 183 "noise": { 184 "noiseLevel": "low", 185 "value": 0 186 }, 187 "makeup": { 188 "eyeMakeup": false, 189 "lipMakeup": true 190 }, 191 "accessories": [], 192 "occlusion": { 193 "foreheadOccluded": false, 194 "eyeOccluded": false, 195 "mouthOccluded": false 196 }, 197 "hair": { 198 "bald": 0.02, 199 "invisible": false, 200 "hairColor": [ 201 { 202 "color": "brown", 203 "confidence": 1 204 }, 205 { 206 "color": "blond", 207 "confidence": 0.94 208 }, 209 { 210 "color": "red", 211 "confidence": 0.76 212 }, 213 { 214 "color": "gray", 215 "confidence": 0.2 216 }, 217 { 218 "color": "other", 219 "confidence": 0.03 220 }, 221 { 222 "color": "black", 223 "confidence": 0.01 224 } 225 ] 226 } 227 } 228 } 229] 230 231 232
試したこと
プログラムの見直し
補足情報(FW/ツールのバージョンなど)
ラズベリーパイ2使用
提示ソースにエラー行「fr = face[~」が含まれていないようです。ソースとエラーに相違はないでしょうか?
ご指摘ありがとうございます。誤ったものを記載しておりましたので、修正致しました。
修正ありがとうございます。「faces = response.json()」の実際のfaceの中身(どんなデータ構造になっているか)を提示されると回答得られやすくなります。
ご指摘ありがとうございます。ソースコード下部に追記させていただきました。
ちょっと腑に落ちないエラーですが回答してみました。
ご回答ありがとうございます。「faces = response.json()」の後に回答にあった3文追加したところエラーが出てしまいました。こちらの対処法分かりますでしょうか。 <type 'dict'> Traceback (most recent call last): File "emotion4.py", line 39, in <module> faces = json.loads(faces) File "/usr/lib/python2.7/json/__init__.py", line 339, in loads return _default_decoder.decode(s) File "/usr/lib/python2.7/json/decoder.py", line 364, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) TypeError: expected string or buffer
やはりfacesは文字列ではなかったようですね。「faces = response.json()」の後に「print(faces)」で出力された結果を提示ください。