Closed eamorgado closed 4 years ago
For either type of user (authenticated and anonymous) we want to support real-time food calorie info, as such and since our model will return text labels we can use the Nutritionix service to get general caloric info for each of our items after we convert the response into a JSON file with the assistance of a simple pattern script, once the file is generated we add it as an android system resource and load its keys when the model predicts a label instead of displaying only the label it will display both the label and small caloric info, as shown in the picture below (app design, camera performance/quality and model accuracy may not be the final version and may contain some errors)
Once the user is authenticated the camera provides a take photo button where it will request the data of all predicted foods to the server which then will query the Nutritionx endpoint, the responses from the Nutritionx are as follows (in the headers we are adding our app id and key):
Post request:
{
"query": "Meatballs"
}
Response body:
{
"foods": [
{
"food_name": "meatballs",
"brand_name": null,
"serving_qty": 4,
"serving_unit": "medium meatballs",
"serving_weight_grams": 113.4,
"nf_calories": 324.32,
"nf_total_fat": 25.19,
"nf_saturated_fat": 8.65,
"nf_cholesterol": 74.84,
"nf_sodium": 755.24,
"nf_total_carbohydrate": 9.14,
"nf_dietary_fiber": 2.61,
"nf_sugars": 3.93,
"nf_protein": 16.33,
"nf_potassium": 335.66,
"nf_p": 271.03,
"full_nutrients": [
{
"attr_id": 203,
"value": 16.3296
},
{
"attr_id": 204,
"value": 25.1861
},
{
"attr_id": 205,
"value": 9.14
},
{
"attr_id": 207,
"value": 2.9938
},
{
"attr_id": 208,
"value": 324.324
},
{
"attr_id": 209,
"value": 2.5515
},
{
"attr_id": 210,
"value": 0.5443
},
{
"attr_id": 211,
"value": 1.8257
},
{
"attr_id": 212,
"value": 0.2381
},
{
"attr_id": 213,
"value": 0.9866
},
{
"attr_id": 214,
"value": 0.3062
},
{
"attr_id": 221,
"value": 0
},
{
"attr_id": 255,
"value": 60.8618
},
{
"attr_id": 262,
"value": 0
},
{
"attr_id": 263,
"value": 0
},
{
"attr_id": 268,
"value": 1356.264
},
{
"attr_id": 269,
"value": 3.935
},
{
"attr_id": 287,
"value": 0.0454
},
{
"attr_id": 291,
"value": 2.6082
},
{
"attr_id": 301,
"value": 90.72
},
{
"attr_id": 303,
"value": 2.0072
},
{
"attr_id": 304,
"value": 35.154
},
{
"attr_id": 305,
"value": 271.026
},
{
"attr_id": 306,
"value": 335.664
},
{
"attr_id": 307,
"value": 755.244
},
{
"attr_id": 309,
"value": 1.8824
},
{
"attr_id": 312,
"value": 0.1395
},
{
"attr_id": 315,
"value": 0.3198
},
{
"attr_id": 317,
"value": 17.3502
},
{
"attr_id": 318,
"value": 82.782
},
{
"attr_id": 319,
"value": 24.948
},
{
"attr_id": 320,
"value": 24.948
},
{
"attr_id": 321,
"value": 0
},
{
"attr_id": 322,
"value": 0
},
{
"attr_id": 323,
"value": 0.4763
},
{
"attr_id": 324,
"value": 2.268
},
{
"attr_id": 326,
"value": 0.1134
},
{
"attr_id": 328,
"value": 0.1134
},
{
"attr_id": 334,
"value": 0
},
{
"attr_id": 337,
"value": 0
},
{
"attr_id": 338,
"value": 0
},
{
"attr_id": 341,
"value": 0.1701
},
{
"attr_id": 342,
"value": 0.2835
},
{
"attr_id": 343,
"value": 0.0454
},
{
"attr_id": 344,
"value": 0
},
{
"attr_id": 345,
"value": 0
},
{
"attr_id": 346,
"value": 0
},
{
"attr_id": 347,
"value": 0
},
{
"attr_id": 401,
"value": 0
},
{
"attr_id": 404,
"value": 0.1542
},
{
"attr_id": 405,
"value": 0.2608
},
{
"attr_id": 406,
"value": 3.5245
},
{
"attr_id": 410,
"value": 1.0478
},
{
"attr_id": 415,
"value": 0.2291
},
{
"attr_id": 417,
"value": 40.824
},
{
"attr_id": 418,
"value": 1.134
},
{
"attr_id": 421,
"value": 51.2568
},
{
"attr_id": 428,
"value": 31.8654
},
{
"attr_id": 429,
"value": 0
},
{
"attr_id": 430,
"value": 9.2988
},
{
"attr_id": 431,
"value": 0
},
{
"attr_id": 432,
"value": 40.824
},
{
"attr_id": 435,
"value": 40.824
},
{
"attr_id": 601,
"value": 74.844
},
{
"attr_id": 605,
"value": 0.6543
},
{
"attr_id": 606,
"value": 8.649
},
{
"attr_id": 607,
"value": 0.0068
},
{
"attr_id": 608,
"value": 0.0034
},
{
"attr_id": 609,
"value": 0.0057
},
{
"attr_id": 610,
"value": 0.0284
},
{
"attr_id": 611,
"value": 0.025
},
{
"attr_id": 612,
"value": 0.4321
},
{
"attr_id": 613,
"value": 5.2255
},
{
"attr_id": 614,
"value": 2.6751
},
{
"attr_id": 615,
"value": 0.0363
},
{
"attr_id": 617,
"value": 9.3725
},
{
"attr_id": 618,
"value": 3.3623
},
{
"attr_id": 619,
"value": 0.1905
},
{
"attr_id": 620,
"value": 0.0748
},
{
"attr_id": 621,
"value": 0.0045
},
{
"attr_id": 624,
"value": 0.0102
},
{
"attr_id": 625,
"value": 0.0941
},
{
"attr_id": 626,
"value": 0.7099
},
{
"attr_id": 627,
"value": 0
},
{
"attr_id": 628,
"value": 0.1429
},
{
"attr_id": 629,
"value": 0.0057
},
{
"attr_id": 630,
"value": 0.0034
},
{
"attr_id": 631,
"value": 0.0147
},
{
"attr_id": 645,
"value": 10.4192
},
{
"attr_id": 646,
"value": 3.7944
},
{
"attr_id": 652,
"value": 0.0556
},
{
"attr_id": 653,
"value": 0.1418
},
{
"attr_id": 654,
"value": 0.0034
},
{
"attr_id": 662,
"value": 0.0374
},
{
"attr_id": 663,
"value": 0.525
},
{
"attr_id": 664,
"value": 0
},
{
"attr_id": 670,
"value": 0.0783
},
{
"attr_id": 671,
"value": 0
},
{
"attr_id": 672,
"value": 0.0794
},
{
"attr_id": 673,
"value": 0.6736
},
{
"attr_id": 674,
"value": 8.8475
},
{
"attr_id": 675,
"value": 3.1922
},
{
"attr_id": 676,
"value": 0.0034
},
{
"attr_id": 685,
"value": 0.0057
},
{
"attr_id": 687,
"value": 0.0964
},
{
"attr_id": 689,
"value": 0.0386
},
{
"attr_id": 693,
"value": 0.5625
},
{
"attr_id": 695,
"value": 0.0919
},
{
"attr_id": 697,
"value": 0
},
{
"attr_id": 851,
"value": 0.1848
},
{
"attr_id": 852,
"value": 0.0136
},
{
"attr_id": 853,
"value": 0.025
},
{
"attr_id": 858,
"value": 0.0227
}
],
"nix_brand_name": null,
"nix_brand_id": null,
"nix_item_name": null,
"nix_item_id": null,
"upc": null,
"consumed_at": "2020-05-13T10:39:36+00:00",
"metadata": {
"is_raw_food": false
},
"source": 1,
"ndb_no": 7972,
"tags": {
"item": "meatball",
"measure": null,
"quantity": "4.0",
"food_group": 0,
"tag_id": 1212
},
"alt_measures": [
{
"serving_weight": 56,
"measure": "pieces",
"seq": 2,
"qty": 3
},
{
"serving_weight": 85,
"measure": "oz",
"seq": 1,
"qty": 3
},
{
"serving_weight": 113.4,
"measure": "medium meatballs",
"seq": 80,
"qty": 4
},
{
"serving_weight": 100,
"measure": "g",
"seq": null,
"qty": 100
}
],
"lat": null,
"lng": null,
"meal_type": 1,
"photo": {
"thumb": "https://nix-tag-images.s3.amazonaws.com/1212_thumb.jpg",
"highres": "https://nix-tag-images.s3.amazonaws.com/1212_highres.jpg",
"is_user_uploaded": false
},
"sub_recipe": null
}
]
}
As seen before we can now parse the Nutritionx response to our liking, as of this moment we are not parsing the full list of nutrients but support is rather easy, in each nutrient the "attrr_id" is the id on Nutritionx's nutrient database.
In our integration, the user can send one or several labels/foods for processing and we return the calorie info for each food in a sequential list which then can be parsed on the app, we also save the post in our server.
Here is an example consider server URL as localhost and consider a valid user token:
{
"token": "{USER_TOKEN}",
"foods": ["Meatballs","Wine"]
}
{
"status": "success",
"total_calories": 446.33,
"processed": [
{
"name": "Meatballs",
"Serving quantity": 4,
"Serving unit": "medium meatballs",
"Serving weight (grams)": 113.4,
"Total calories": 324.32,
"Total fat": 25.19,
"Total saturated fat": 8.65,
"Cholestrol": 74.84,
"Sodium": 755.24,
"Total carbs": 9.14,
"Fiber": 2.61,
"Sugar": 3.93,
"Protein": 16.33,
"Potassium": 335.66
},
{
"name": "Wine",
"Serving quantity": 1,
"Serving unit": "glass",
"Serving weight (grams)": 147,
"Total calories": 122.01,
"Total fat": 0,
"Total saturated fat": null,
"Cholestrol": null,
"Sodium": null,
"Total carbs": 3.82,
"Fiber": null,
"Sugar": null,
"Protein": 0.1,
"Potassium": null
}
]
}
In order to increase user experience and app functionality, we will integrate food analysis into the app, to do so we require a database for all our predicted labels. We will be using the Nutritionix API since we want to keep our project costs as low as possible we will only be using the free key per account therefor we cannot perform the request from our app but from the server where we will store our credentials and redirect and parse user requests for food data.