Hand the json file to list in python - python

I have the JSON file :
{
"relationships":
[
{
"predicate": "wears",
"object": {"name": "sneakers", "h": 26, "w": 52, "y": 489, "x": 243, "id": 38207},
"id": 15928,
"subject": {"name": "man", "h": 262, "w": 60, "y": 249, "x": 238, "id": 38206}
}
],
"id" = 1
},
{"relationships":
[
{
"predicate": "on",
"object": {"name": "street", "h": 262, "w": 714, "y": 328, "x": 77, "id": 38204},
"id": 15927,
"subject": {"name": "shade", "h": 192, "w": 274, "y": 338, "x": 119, "id": 38205}
}
],
"id" = 1
}
How to extract the all "object name" and "id" as a list or output in two columns?

Related

Sort list of dict with random exception (without sorting)

I have a list of dictionaries, I sort it by a certain parameter (EPС). Now I need to randomly select from this list 20-30% of dictionaries that do not need to be sorted. So it should be sort 1-2-3-4-5 by EPC, and then 20-30% of objects selected at random, and then the rest sorted by EPC.
For example: We have 10 records, take 30% (3 records) randomly (before
sorting), then sort the rest of 7, then place 3 randomly selected
records in the n-place of sorted (for example in the middle of the
sorted list)
My list example
OFFERS = [
{
"id":"43136bb6-c5e5-4d34-acff-605ff64e4d85",
"impressions":2000,
"clicks":481,
"leads":1,
"payout":1768,
"epc":3
},
{
"id":"f7025432-e7c3-414a-b817-833c0a520c69",
"impressions":3241,
"clicks":467,
"leads":48,
"payout":2486,
"epc":255
},
{
"id":"53c567be-86aa-4eb1-8448-2a701bc9bff0",
"impressions":1083,
"clicks":588,
"leads":19,
"payout":3195,
"epc":103
},
{
"id":"0d45d6cd-ead9-407c-aa13-3e9e9ed2898d",
"impressions":2670,
"clicks":569,
"leads":24,
"payout":2801,
"epc":118
},
{
"id":"fd470c97-a9c2-4171-8327-a7e2151a6d76",
"impressions":3975,
"clicks":592,
"leads":39,
"payout":2410,
"epc":158
},
{
"id":"a8f8b25a-b52b-4d76-b3e0-0c517d75d9dd",
"impressions":1917,
"clicks":317,
"leads":5,
"payout":3443,
"epc":54
},
{
"id":"1ce96ecc-b034-4809-a990-c2279cd78e66",
"impressions":3531,
"clicks":411,
"leads":22,
"payout":1681,
"epc":89
},
{
"id":"d634df9b-5dd2-484c-8298-1788f66891df",
"impressions":2959,
"clicks":489,
"leads":19,
"payout":1106,
"epc":42
},
{
"id":"1169d632-25f2-4241-a6e5-37ba94469d0e",
"impressions":2201,
"clicks":566,
"leads":16,
"payout":1773,
"epc":50
},
{
"id":"683842d4-e212-4f66-a729-2e70ef0c2837",
"impressions":3875,
"clicks":511,
"leads":49,
"payout":3289,
"epc":315
},
{
"id":"fbe95639-e03d-4a65-89b8-c7c21628b744",
"impressions":4070,
"clicks":409,
"leads":61,
"payout":1965,
"epc":293
},
{
"id":"54f4dfa5-dbd5-439f-a6a6-534214a60b45",
"impressions":2728,
"clicks":223,
"leads":15,
"payout":2906,
"epc":195
},
{
"id":"e751efb9-ad53-4635-89db-b7eee4b9c586",
"impressions":2005,
"clicks":506,
"leads":2,
"payout":1457,
"epc":5
},
{
"id":"467cbed3-121c-4c8e-a094-d43b371a677f",
"impressions":3320,
"clicks":286,
"leads":45,
"payout":3136,
"epc":493
},
{
"id":"8d726f55-4570-4827-99b4-909ebd9dd166",
"impressions":3913,
"clicks":588,
"leads":20,
"payout":3436,
"epc":116
}
]
Now im sorting by epc
sorted_data = sorted(OFFERS, key=lambda d: d['epc'], reverse=True)
Can someone help with the implementation of random selection without sorting?
Try:
import random
# select N offers:
N = int(len(OFFERS) * 0.3)
selected = list(random.sample(range(len(OFFERS)), N))
# sort the remaining by EPC
out = sorted(
[o for i, o in enumerate(OFFERS) if i not in selected],
key=lambda k: k["epc"],
reverse=True,
)
# put selected in some place (in the middle):
place = len(out) // 2
for s in selected:
out.insert(place, OFFERS[s])
print(out)
Prints (for example):
[
{
"id": "467cbed3-121c-4c8e-a094-d43b371a677f",
"impressions": 3320,
"clicks": 286,
"leads": 45,
"payout": 3136,
"epc": 493,
},
{
"id": "54f4dfa5-dbd5-439f-a6a6-534214a60b45",
"impressions": 2728,
"clicks": 223,
"leads": 15,
"payout": 2906,
"epc": 195,
},
{
"id": "fd470c97-a9c2-4171-8327-a7e2151a6d76",
"impressions": 3975,
"clicks": 592,
"leads": 39,
"payout": 2410,
"epc": 158,
},
{
"id": "0d45d6cd-ead9-407c-aa13-3e9e9ed2898d",
"impressions": 2670,
"clicks": 569,
"leads": 24,
"payout": 2801,
"epc": 118,
},
{
"id": "8d726f55-4570-4827-99b4-909ebd9dd166",
"impressions": 3913,
"clicks": 588,
"leads": 20,
"payout": 3436,
"epc": 116,
},
{
"id": "683842d4-e212-4f66-a729-2e70ef0c2837",
"impressions": 3875,
"clicks": 511,
"leads": 49,
"payout": 3289,
"epc": 315,
},
{
"id": "f7025432-e7c3-414a-b817-833c0a520c69",
"impressions": 3241,
"clicks": 467,
"leads": 48,
"payout": 2486,
"epc": 255,
},
{
"id": "a8f8b25a-b52b-4d76-b3e0-0c517d75d9dd",
"impressions": 1917,
"clicks": 317,
"leads": 5,
"payout": 3443,
"epc": 54,
},
{
"id": "fbe95639-e03d-4a65-89b8-c7c21628b744",
"impressions": 4070,
"clicks": 409,
"leads": 61,
"payout": 1965,
"epc": 293,
},
{
"id": "53c567be-86aa-4eb1-8448-2a701bc9bff0",
"impressions": 1083,
"clicks": 588,
"leads": 19,
"payout": 3195,
"epc": 103,
},
{
"id": "1ce96ecc-b034-4809-a990-c2279cd78e66",
"impressions": 3531,
"clicks": 411,
"leads": 22,
"payout": 1681,
"epc": 89,
},
{
"id": "1169d632-25f2-4241-a6e5-37ba94469d0e",
"impressions": 2201,
"clicks": 566,
"leads": 16,
"payout": 1773,
"epc": 50,
},
{
"id": "d634df9b-5dd2-484c-8298-1788f66891df",
"impressions": 2959,
"clicks": 489,
"leads": 19,
"payout": 1106,
"epc": 42,
},
{
"id": "e751efb9-ad53-4635-89db-b7eee4b9c586",
"impressions": 2005,
"clicks": 506,
"leads": 2,
"payout": 1457,
"epc": 5,
},
{
"id": "43136bb6-c5e5-4d34-acff-605ff64e4d85",
"impressions": 2000,
"clicks": 481,
"leads": 1,
"payout": 1768,
"epc": 3,
},
]

Modifiy Json File with Key Values

Hello i need to modify json file with the key values of outcomeType>displayName. My code only shows one key value of displayName; however need to create 2 key with key values.
Json:
{ "18916": [ { "id": 2275920175, "eventId": 16, "minute": 0, "second": 51, "teamId": 223, "playerId": 18916, "x": 66.6, "y": 81.2, "expandedMinute": 0, "period": { "value": 1, "displayName": "FirstHalf" }, "type": { "value": 1, "displayName": "Pass" }, "outcomeType": { "value": 1, "displayName": "Successful" }, "qualifiers": [ { "type": { "value": 213, "displayName": "Angle" }, "value": "2.8" }, { "type": { "value": 56, "displayName": "Zone" }, "value": "Left" }, { "type": { "value": 212, "displayName": "Length" }, "value": "12.4" }, { "type": { "value": 140, "displayName": "PassEndX" }, "value": "55.3" }, { "type": { "value": 141, "displayName": "PassEndY" }, "value": "86.6" } ], "satisfiedEventsTypes": [ 90, 118, 116, 29, 34, 36, 215, 217 ], "isTouch": true, "endX": 55.3, "endY": 86.6 }, { "id": 2275920577, "eventId": 29, "minute": 1, "second": 24, "teamId": 223, "playerId": 18916, "x": 75, "y": 80.2, "expandedMinute": 1, "period": { "value": 1, "displayName": "FirstHalf" }, "type": { "value": 1, "displayName": "Pass" }, "outcomeType": { "value": 1, "displayName": "Successful" }, "qualifiers": [ { "type": { "value": 212, "displayName": "Length" }, "value": "22.1" }, { "type": { "value": 141, "displayName": "PassEndY" }, "value": "76.4" }, { "type": { "value": 56, "displayName": "Zone" }, "value": "Center" }, { "type": { "value": 213, "displayName": "Angle" }, "value": "6.2" }, { "type": { "value": 140, "displayName": "PassEndX" }, "value": "95.9" } ], "satisfiedEventsTypes": [ 90, 118, 116, 29, 204, 35, 37, 216, 217 ], "isTouch": true, "endX": 95.9, "endY": 76.4 }, { "id": 2275921705, "eventId": 49, "minute": 3, "second": 11, "teamId": 223, "playerId": 18916, "x": 73.5, "y": 79.7, "expandedMinute": 3, "period": { "value": 1, "displayName": "FirstHalf" }, "type": { "value": 1, "displayName": "Pass" }, "outcomeType": { "value": 0, "displayName": "Unsuccessful" }, "qualifiers": [ { "type": { "value": 56, "displayName": "Zone" }, "value": "Center" }, { "type": { "value": 3, "displayName": "HeadPass" } }, { "type": { "value": 212, "displayName": "Length" }, "value": "19.1" }, { "type": { "value": 140, "displayName": "PassEndX" }, "value": "89.7" }, { "type": { "value": 213, "displayName": "Angle" }, "value": "5.8" }, { "type": { "value": 141, "displayName": "PassEndY" }, "value": "66.9" } ], "satisfiedEventsTypes": [ 90, 119, 28, 138, 35, 37, 216, 217 ], "isTouch": true, "endX": 89.7, "endY": 66.9 }]}
Code:
for js in data_passes[18916]:
icdType = js["outcomeType"]["displayName"]
if icdType in pass_type:
pass_type[icdType].append(js)
else:
pass_type[icdType] = [js]
data_pass_type = json.dumps(pass_type)
data_pass_type = json.loads(data_pass_type)
with open('test.json', 'w') as json_file:
json.dump(data_pass_type, json_file)
Result:
Result Json
Expected Result: Both Successful and UnSuccessful key values. (UnSuccessful missing)
Your code works for me, after changing the integer to a string:
import json
data_passes = json.load(open("x.txt"))
pass_type = {}
for js in data_passes["18916"]:
icdType = js["outcomeType"]["displayName"]
if icdType in pass_type:
pass_type[icdType].append(js)
else:
pass_type[icdType] = [js]
with open('test.json', 'w') as json_file:
json.dump(pass_type, json_file)
Result:
{
"Successful": [
{
"id": 2275920175,
...
},
{
"id": 2275920577,
...
}
],
"Unsuccessful": [
{
"id": 2275921705,
...
}
]
}

Find dictionaries with same values and add new keys to them

have such a question. I have a list with dictionaries, which contain information about words, which were recognized from image using Google API. So my list looks like:
test_list = [
{
"value": "68004,",
"location": {
"TL": {
"x": 351,
"y": 0
},
"TR": {
"x": 402,
"y": 0
},
"BR": {
"x": 402,
"y": 12
},
"BL": {
"x": 351,
"y": 12
}
},
"type": 1
},
{
"value": "Чорномор",
"location": {
"TL": {
"x": 415,
"y": 0
},
"TR": {
"x": 493,
"y": 0
},
"BR": {
"x": 493,
"y": 12
},
"BL": {
"x": 415,
"y": 12
}
},
"type": 1
},
{
"value": "вулиця,",
"location": {
"TL": {
"x": 495,
"y": 14
},
"TR": {
"x": 550,
"y": 10
},
"BR": {
"x": 551,
"y": 22
},
"BL": {
"x": 496,
"y": 26
}
},
"type": 1
},
{
"value": "140,",
"location": {
"TL": {
"x": 557,
"y": 8
},
"TR": {
"x": 576,
"y": 7
},
"BR": {
"x": 577,
"y": 20
},
"BL": {
"x": 558,
"y": 21
}
},
"type": 1
},
{
"value": "кв.",
"location": {
"TL": {
"x": 581,
"y": 6
},
"TR": {
"x": 605,
"y": 4
},
"BR": {
"x": 606,
"y": 21
},
"BL": {
"x": 582,
"y": 23
}
},
"type": 1
},
{
"value": "77",
"location": {
"TL": {
"x": 607,
"y": 5
},
"TR": {
"x": 628,
"y": 4
},
"BR": {
"x": 629,
"y": 19
},
"BL": {
"x": 608,
"y": 21
}
},
"type": 1
},
]
So I want to find, if some dictionaries have the same location parameters and if it is true, add a new key "string_number" with the same index to these dictionaries. As example in the above code two first dictionaries have the same ["location"]["TL"]["y"] and ["location"]["TR"]["y"] == 0px, and also ["location"]["BR"]["y"] and ["location"]["BL"]["y"] == 12px.
So that means that these words are placed in a one string in a real document, so I want to add to them new key "string_number" with index 0. That will look like:
test_list = [
{
"value": "68004,",
"location": {
"TL": {
"x": 351,
"y": 0
},
"TR": {
"x": 402,
"y": 0
},
"BR": {
"x": 402,
"y": 12
},
"BL": {
"x": 351,
"y": 12
}
},
"type": 1
"string_number": 0
},
{
"value": "Чорномор",
"location": {
"TL": {
"x": 415,
"y": 0
},
"TR": {
"x": 493,
"y": 0
},
"BR": {
"x": 493,
"y": 12
},
"BL": {
"x": 415,
"y": 12
}
},
"type": 1
"string_number": 0
},
Then going through the rest of a list I want to find every such a duplication and set the same string index to them.
However, sometimes pixels can di ffer by 1-2 points less or more (so as example "y": 12 or 10 or 14 probably still say that word is on the same line in a document). So is it real to make an extra check for this difference?
EDIT: so I used the help of Aleksa Svitlica and created a class, which makes all work about searching for words on the same line.
So it looks like:
class WordParser():
def __init__(self):
self.list_wbw = self.load_json()
self.next_new_string_number = 0
def load_json(self):
with io.open(calc_paths(status="now", path_type=PathType.OCR_JSON_WBW), 'r', encoding='utf-8') as content:
self.list_wbw = json.load(content)
content.close()
return self.list_wbw
def mark_images_on_same_line(self):
number_of_images = len(self.list_wbw)
for i in range(number_of_images):
for j in range(i + 1, number_of_images):
image1 = self.list_wbw[i]
image2 = self.list_wbw[j]
on_same_line = self._check_if_images_on_same_line(image1, image2)
if on_same_line:
self._add_string_number_to_images(image1, image2)
def print_images(self):
print(json.dumps(self.list_wbw, indent=3, sort_keys=False, ensure_ascii=False))
def _check_if_images_on_same_line(self, image1, image2):
image1_top_left = image1["location"]["TL"]["y"]
image1_top_right = image1["location"]["TR"]["y"]
image1_bot_left = image1["location"]["BL"]["y"]
image1_bot_right = image1["location"]["BR"]["y"]
image2_top_left = image2["location"]["TL"]["y"]
image2_top_right = image2["location"]["TR"]["y"]
image2_bot_left = image2["location"]["BL"]["y"]
image2_bot_right = image2["location"]["BR"]["y"]
same_top_left_position = self._pixel_heights_match_within_threshold(image1_top_left, image2_top_left)
same_top_right_position = self._pixel_heights_match_within_threshold(image1_top_right, image2_top_right)
same_bot_left_position = self._pixel_heights_match_within_threshold(image1_bot_left, image2_bot_left)
same_bot_right_position = self._pixel_heights_match_within_threshold(image1_bot_right, image2_bot_right)
if same_top_left_position and same_top_right_position and same_bot_left_position and same_bot_right_position:
self._add_string_number_to_images(image1, image2)
def _add_string_number_to_images(self, image1, image2):
string_number = self._determine_string_number(image1, image2)
image1["string_number"] = string_number
image2["string_number"] = string_number
def _determine_string_number(self, image1, image2):
string_number = self.next_new_string_number
image1_number = image1.get("string_number")
image2_number = image2.get("string_number")
if image1_number is not None:
string_number = image1_number
elif image2_number is not None:
string_number = image2_number
else:
self.next_new_string_number += 1
return string_number
def _pixel_heights_match_within_threshold(self, height1, height2, threshold=4):
return abs(height1 - height2) <= threshold
And in my another module, where I call these methods:
word_parser = WordParser()
word_parser.mark_images_on_same_line()
word_parser.print_images()
Adding the following code after your test_list I got the output you can see below. My code currently just checks that the heights of TR and TL are within a threshold (defaults to 2 pixel threshold). But you could modify it depending on your requirements. In _check_if_images_on_same_line you can change the rules as you like.
import json
#-------------------------------------------------------------------
#---Classes---------------------------------------------------------
#-------------------------------------------------------------------
class ImageParser():
def __init__(self, list_of_images):
self.list_of_images = list_of_images
self.next_new_string_number = 0
# ----------------------------------------------------------------------------
# ---Public-------------------------------------------------------------------
# ----------------------------------------------------------------------------
def mark_images_on_same_line(self):
number_of_images = len(self.list_of_images)
for i in range(number_of_images):
for j in range(i+1, number_of_images):
image1 = self.list_of_images[i]
image2 = self.list_of_images[j]
on_same_line = self._check_if_images_on_same_line(image1, image2)
if on_same_line:
self._add_string_number_to_images(image1, image2)
def print_images(self):
print(json.dumps(self.list_of_images, indent=True, sort_keys=False, ensure_ascii=False))
# ----------------------------------------------------------------------------
# ---Private------------------------------------------------------------------
# ----------------------------------------------------------------------------
def _check_if_images_on_same_line(self, image1, image2):
image1_top = image1["location"]["TL"]["y"]
image1_bot = image1["location"]["BL"]["y"]
image2_top = image2["location"]["TL"]["y"]
image2_bot = image2["location"]["BL"]["y"]
same_top_position = self._pixel_heights_match_within_threshold(image1_top, image2_top)
same_bot_position = self._pixel_heights_match_within_threshold(image1_bot, image2_bot)
if same_bot_position & same_top_position:
self._add_string_number_to_images(image1, image2)
def _add_string_number_to_images(self, image1, image2):
string_number = self._determine_string_number(image1, image2)
image1["string_number"] = string_number
image2["string_number"] = string_number
def _determine_string_number(self, image1, image2):
string_number = self.next_new_string_number
image1_number = image1.get("string_number")
image2_number = image2.get("string_number")
if image1_number is not None:
string_number = image1_number
elif image2_number is not None:
string_number = image2_number
else:
self.next_new_string_number += 1
return string_number
def _pixel_heights_match_within_threshold(self, height1, height2, threshold=2):
return abs(height1 - height2) <= threshold
#-------------------------------------------------------------------
#---Main------------------------------------------------------------
#-------------------------------------------------------------------
if __name__ == "__main__":
image_parser = ImageParser(test_list)
image_parser.mark_images_on_same_line()
image_parser.print_images()
Gives the following results:
[
{
"value": "68004,",
"location": {
"TL": {
"x": 351,
"y": 0
},
"TR": {
"x": 402,
"y": 0
},
"BR": {
"x": 402,
"y": 12
},
"BL": {
"x": 351,
"y": 12
}
},
"type": 1,
"string_number": 0
},
{
"value": "Чорномор",
"location": {
"TL": {
"x": 415,
"y": 0
},
"TR": {
"x": 493,
"y": 0
},
"BR": {
"x": 493,
"y": 12
},
"BL": {
"x": 415,
"y": 12
}
},
"type": 1,
"string_number": 0
},
{
"value": "вулиця,",
"location": {
"TL": {
"x": 495,
"y": 14
},
"TR": {
"x": 550,
"y": 10
},
"BR": {
"x": 551,
"y": 22
},
"BL": {
"x": 496,
"y": 26
}
},
"type": 1
},
{
"value": "140,",
"location": {
"TL": {
"x": 557,
"y": 8
},
"TR": {
"x": 576,
"y": 7
},
"BR": {
"x": 577,
"y": 20
},
"BL": {
"x": 558,
"y": 21
}
},
"type": 1,
"string_number": 1
},
{
"value": "кв.",
"location": {
"TL": {
"x": 581,
"y": 6
},
"TR": {
"x": 605,
"y": 4
},
"BR": {
"x": 606,
"y": 21
},
"BL": {
"x": 582,
"y": 23
}
},
"type": 1,
"string_number": 1
},
{
"value": "77",
"location": {
"TL": {
"x": 607,
"y": 5
},
"TR": {
"x": 628,
"y": 4
},
"BR": {
"x": 629,
"y": 19
},
"BL": {
"x": 608,
"y": 21
}
},
"type": 1,
"string_number": 1
}
]

Parsing rekognition get_face_search results

I am trying to parse out Face Matches from the results of the get_face_search() AWS Rekognition API. It outputs an array of Persons, within that array is another array of FaceMatches for a given person and timestamp. I want to take information from the FaceMatches array and be able to loop through the array of Face Matches.
I have done something similar before for single arrays and looped successfully, but I am missing something trivial here perhaps.
Here is output from API:
Response:
{
"JobStatus": "SUCCEEDED",
"NextToken": "U5EdbZ+86xseDBfDlQ2u8QhSVzbdodDOmX/gSbwIgeO90l2BKWvJEscjUDmA6GFDCSSfpKA4",
"VideoMetadata": {
"Codec": "h264",
"DurationMillis": 6761,
"Format": "QuickTime / MOV",
"FrameRate": 30.022184371948242,
"FrameHeight": 568,
"FrameWidth": 320
},
"Persons": [
{
"Timestamp": 0,
"Person": {
"Index": 0,
"BoundingBox": {
"Width": 0.987500011920929,
"Height": 0.7764084339141846,
"Left": 0.0031250000465661287,
"Top": 0.2042253464460373
},
"Face": {
"BoundingBox": {
"Width": 0.6778846383094788,
"Height": 0.3819068372249603,
"Left": 0.10096154361963272,
"Top": 0.2654387652873993
},
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.33232420682907104,
"Y": 0.4194057583808899
},
{
"Type": "eyeRight",
"X": 0.5422032475471497,
"Y": 0.41616082191467285
},
{
"Type": "nose",
"X": 0.45633792877197266,
"Y": 0.4843473732471466
},
{
"Type": "mouthLeft",
"X": 0.37002310156822205,
"Y": 0.567118763923645
},
{
"Type": "mouthRight",
"X": 0.5330674052238464,
"Y": 0.5631639361381531
}
],
"Pose": {
"Roll": -2.2475271224975586,
"Yaw": 4.371307373046875,
"Pitch": 6.83940315246582
},
"Quality": {
"Brightness": 40.40004348754883,
"Sharpness": 99.95819854736328
},
"Confidence": 99.87971496582031
}
},
"FaceMatches": [
{
"Similarity": 99.81229400634766,
"Face": {
"FaceId": "4699a1eb-9f6e-415d-8716-eef141d23433a",
"BoundingBox": {
"Width": 0.6262923432480737,
"Height": 0.46972032423490747,
"Left": 0.130435005324523403604,
"Top": 0.13354002343240603
},
"ImageId": "1ac790eb-615a-111f-44aa-4017c3c315ad",
"Confidence": 99.19400024414062
}
}
]
},
{
"Timestamp": 66,
"Person": {
"Index": 0,
"BoundingBox": {
"Width": 0.981249988079071,
"Height": 0.7764084339141846,
"Left": 0.0062500000931322575,
"Top": 0.2042253464460373
}
}
},
{
"Timestamp": 133,
"Person": {
"Index": 0,
"BoundingBox": {
"Width": 0.9781249761581421,
"Height": 0.783450722694397,
"Left": 0.0062500000931322575,
"Top": 0.19894365966320038
}
}
},
{
"Timestamp": 199,
"Person": {
"Index": 0,
"BoundingBox": {
"Width": 0.981249988079071,
"Height": 0.783450722694397,
"Left": 0.0031250000465661287,
"Top": 0.19894365966320038
},
"Face": {
"BoundingBox": {
"Width": 0.6706730723381042,
"Height": 0.3778440058231354,
"Left": 0.10817307233810425,
"Top": 0.26679307222366333
},
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.33244985342025757,
"Y": 0.41591548919677734
},
{
"Type": "eyeRight",
"X": 0.5446155667304993,
"Y": 0.41204410791397095
},
{
"Type": "nose",
"X": 0.4586191177368164,
"Y": 0.479543000459671
},
{
"Type": "mouthLeft",
"X": 0.37614554166793823,
"Y": 0.5639738440513611
},
{
"Type": "mouthRight",
"X": 0.5334802865982056,
"Y": 0.5592300891876221
}
],
"Pose": {
"Roll": -2.4899401664733887,
"Yaw": 3.7596628665924072,
"Pitch": 6.3544135093688965
},
"Quality": {
"Brightness": 40.46360778808594,
"Sharpness": 99.95819854736328
},
"Confidence": 99.89802551269531
}
},
"FaceMatches": [
{
"Similarity": 99.80543518066406,
"Face": {
"FaceId": "4699a1eb-9f6e-415d-8716-eef141d9223a",
"BoundingBox": {
"Width": 0.626294234234737,
"Height": 0.469234234890747,
"Left": 0.130435002334234604,
"Top": 0.13354023423449180603
},
"ImageId": "1ac790eb-615a-111f-44aa-4017c3c315ad",
"Confidence": 99.19400024414062
}
}
]
},
{
"Timestamp": 266,
"Person": {
"Index": 0,
"BoundingBox": {
"Width": 0.984375,
"Height": 0.7852112650871277,
"Left": 0,
"Top": 0.19718310236930847
}
}
}
],
I have isolated the timestamps (just testing my approach) using the following:
timestamps = [m['Timestamp'] for m in response['Persons']]
Output is this, as expected - [0, 66, 133, 199, 266]
However, when I try the same thing with FaceMatches, I get an error.
[0, 66, 133, 199, 266]
list indices must be integers or slices, not str: TypeError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 40, in lambda_handler
matches = [m['FaceMatches']['Face']['FaceId'] for m in response['Persons']]
File "/var/task/lambda_function.py", line 40, in <listcomp>
matches = [m['FaceMatches']['Face']['FaceId'] for m in response['Persons']]
TypeError: list indices must be integers or slices, not str
What I need to end up with is for each face that is matched:
Timestamp
FaceID
Similarity
Can anybody shed some light on this for me?
According to your needs , you have two FaceMatch objects in your response and you can extract required info in this way :
import json
with open('newtest.json') as f:
data = json.load(f)
length =len(data['Persons'])
for i in range(0,length):
try:
print(data['Persons'][i]['FaceMatches'][0]['Similarity'])
print(data['Persons'][i]['FaceMatches'][0]['Face']['FaceId'])
print(data['Persons'][i]['Timestamp'])
except:
continue
I have taken your json object in data variable and i have ignored timestamps where there is no corresponding facematch, if you wish you can extract then the same way

Extract specific data from JSON data from Google Cloud Vision

I am quite new to Raspberry Pi and Python coding but I was successful in configuring Google Cloud Vision. However the JSON dump looks like:
{
"responses": [
{
"faceAnnotations": [
{
"angerLikelihood": "UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"boundingPoly": {
"vertices": [
{
"x": 129
},
{
"x": 370
},
{
"x": 370,
"y": 240
},
{
"x": 129,
"y": 240
}
]
},
"detectionConfidence": 0.99543685,
"fdBoundingPoly": {
"vertices": [
{
"x": 162,
"y": 24
},
{
"x": 337,
"y": 24
},
{
"x": 337,
"y": 199
},
{
"x": 162,
"y": 199
}
]
},
"headwearLikelihood": "VERY_UNLIKELY",
"joyLikelihood": "VERY_UNLIKELY",
"landmarkingConfidence": 0.77542377,
"landmarks": [
{
"position": {
"x": 210.93373,
"y": 92.71409,
"z": -0.00025338508
},
"type": "LEFT_EYE"
},
{
"position": {
"x": 280.00177,
"y": 82.57283,
"z": 0.49017733
},
"type": "RIGHT_EYE"
},
{
"position": {
"x": 182.08047,
"y": 77.89372,
"z": 6.825161
},
"type": "LEFT_OF_LEFT_EYEBROW"
},
{
"position": {
"x": 225.82335,
"y": 72.88091,
"z": -13.963233
},
"type": "RIGHT_OF_LEFT_EYEBROW"
},
{
"position": {
"x": 260.4491,
"y": 66.19005,
"z": -13.798634
},
"type": "LEFT_OF_RIGHT_EYEBROW"
},
{
"position": {
"x": 303.87503,
"y": 59.69522,
"z": 7.8336163
},
"type": "RIGHT_OF_RIGHT_EYEBROW"
},
{
"position": {
"x": 244.57729,
"y": 83.701904,
"z": -15.022567
},
"type": "MIDPOINT_BETWEEN_EYES"
},
{
"position": {
"x": 251.58353,
"y": 124.68004,
"z": -36.52176
},
"type": "NOSE_TIP"
},
{
"position": {
"x": 255.39096,
"y": 151.87607,
"z": -19.560472
},
"type": "UPPER_LIP"
},
{
"position": {
"x": 259.96045,
"y": 178.62886,
"z": -14.095398
},
"type": "LOWER_LIP"
},
{
"position": {
"x": 232.35422,
"y": 167.2542,
"z": -1.0750997
},
"type": "MOUTH_LEFT"
},
{
"position": {
"x": 284.49316,
"y": 159.06075,
"z": -0.078973025
},
"type": "MOUTH_RIGHT"
},
{
"position": {
"x": 256.94714,
"y": 163.11235,
"z": -14.0897665
},
"type": "MOUTH_CENTER"
},
{
"position": {
"x": 274.47885,
"y": 125.8553,
"z": -7.8479633
},
"type": "NOSE_BOTTOM_RIGHT"
},
{
"position": {
"x": 231.2164,
"y": 132.60686,
"z": -8.418254
},
"type": "NOSE_BOTTOM_LEFT"
},
{
"position": {
"x": 252.96692,
"y": 135.81783,
"z": -19.805998
},
"type": "NOSE_BOTTOM_CENTER"
},
{
"position": {
"x": 208.6943,
"y": 86.72571,
"z": -4.8503814
},
"type": "LEFT_EYE_TOP_BOUNDARY"
},
{
"position": {
"x": 223.4354,
"y": 90.71454,
"z": 0.42966545
},
"type": "LEFT_EYE_RIGHT_CORNER"
},
{
"position": {
"x": 210.67189,
"y": 96.09362,
"z": -0.62435865
},
"type": "LEFT_EYE_BOTTOM_BOUNDARY"
},
{
"position": {
"x": 195.00711,
"y": 93.783226,
"z": 6.6310787
},
"type": "LEFT_EYE_LEFT_CORNER"
},
{
"position": {
"x": 208.30045,
"y": 91.73073,
"z": -1.7749802
},
"type": "LEFT_EYE_PUPIL"
},
{
"position": {
"x": 280.8329,
"y": 75.722244,
"z": -4.3266015
},
"type": "RIGHT_EYE_TOP_BOUNDARY"
},
{
"position": {
"x": 295.9134,
"y": 78.8241,
"z": 7.3644505
},
"type": "RIGHT_EYE_RIGHT_CORNER"
},
{
"position": {
"x": 281.82813,
"y": 85.56999,
"z": -0.09711724
},
"type": "RIGHT_EYE_BOTTOM_BOUNDARY"
},
{
"position": {
"x": 266.6147,
"y": 83.689865,
"z": 0.6850431
},
"type": "RIGHT_EYE_LEFT_CORNER"
},
{
"position": {
"x": 282.31485,
"y": 80.471725,
"z": -1.3341979
},
"type": "RIGHT_EYE_PUPIL"
},
{
"position": {
"x": 202.4563,
"y": 66.06882,
"z": -8.493092
},
"type": "LEFT_EYEBROW_UPPER_MIDPOINT"
},
{
"position": {
"x": 280.76108,
"y": 54.08935,
"z": -7.895889
},
"type": "RIGHT_EYEBROW_UPPER_MIDPOINT"
},
{
"position": {
"x": 168.31839,
"y": 134.46411,
"z": 89.73161
},
"type": "LEFT_EAR_TRAGION"
},
{
"position": {
"x": 332.23724,
"y": 109.35637,
"z": 90.81501
},
"type": "RIGHT_EAR_TRAGION"
},
{
"position": {
"x": 242.81676,
"y": 67.845825,
"z": -16.629877
},
"type": "FOREHEAD_GLABELLA"
},
{
"position": {
"x": 264.32065,
"y": 208.95119,
"z": -4.0186276
},
"type": "CHIN_GNATHION"
},
{
"position": {
"x": 183.4723,
"y": 179.30655,
"z": 59.87147
},
"type": "CHIN_LEFT_GONION"
},
{
"position": {
"x": 331.6927,
"y": 156.69931,
"z": 60.93835
},
"type": "CHIN_RIGHT_GONION"
}
],
"panAngle": 0.41165036,
"rollAngle": -8.687789,
"sorrowLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"tiltAngle": 0.2050134,
"underExposedLikelihood": "POSSIBLE"
}
]
}
]
}
Yes, it's an eyesore to look at. I am only wanting to extract the likelihood. Preferably in this format:
Anger likelihood is UNLIKEY
Joy likelihood is VERY_UNLIKELY
Sorrow likelihood is VERY_UNLIKELY
Suprise likelihood is VERY_UNLIKELY
Python code can be found here:
https://github.com/DexterInd/GoogleVisionTutorials/blob/master/camera-vision-face.py
Answered my own question in perhaps the most noobiest way:
print "Anger likelihood is:",
print(response['responses'][0]['faceAnnotations'][0]['angerLikelihood'])
print "Joy likelihood is:",
print(response['responses'][0]['faceAnnotations'][0]['joyLikelihood'])
print "Sorrow likelihood is:",
print(response['responses'][0]['faceAnnotations'][0]['sorrowLikelihood'])
print "Surprise likelihood is:",
print(response['responses'][0]['faceAnnotations'][0]['surpriseLikelihood'])
Came out looking like:
Anger likelihood is: VERY_UNLIKELY
Joy likelihood is: VERY_LIKELY
Sorrow likelihood is: VERY_UNLIKELY
Surprise likelihood is: VERY_UNLIKELY
You can go with dictionary comprehensions. Given that you have your response in variable result, the following code will output exactly what you want.
import json
likelihood = {
attr[:len(attr) - 10].capitalize(): value
for attr, value
in json.loads(result)['responses'][0]['faceAnnotations'][0].items()
if attr.find('Likelihood') != -1
}
print(*[
'{} likelihood is {}'.format(e, p) for e, p in likelihood.items()
], sep='\n')
Keep in mind that this code works correctly if there is only one item in both responses and faceAnnotations arrays. If there's more, the code will handle only the first items. It's also kinda ugly.
In len(attr) - 10, 10 is the length of word "Likelihood".

Categories

Resources