Files
NutritionMaster/README.md
2020-07-15 09:15:02 +08:00

406 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 营养大师
一款基于数据分析的智能饮食推荐APP
仓库地址: https://github.com/wangtianrui/NutritionMaster
### 数据分析
* 人体健康信息
* 体重
* 身高
* 年龄
* 菜品信息
* 菜的名称
* 卡路里
* 蛋白质,脂肪等
* 推荐的食用量
* 某个人群对应的改善体质(减肥,塑性,增肌等)的方案
* 菜谱
* 运动方式
### 数据集和api
**赵励志收集的资料**
* 图像识别食物,获取卡路里: https://cloud.baidu.com/product/imagerecognition/fine_grained
* **nutrition facts** from food : https://www.kaggle.com/openfoodfacts/world-food-facts#en.openfoodfacts.org.products.tsv
* https://world.openfoodfacts.org/ 数据集官网
* 456赞,目前为止发现的最高的相关数据集
* nutrition facts for **McDonalds** : https://www.kaggle.com/mcdonalds/nutrition-facts
* Calories, fat, and sugar for every cheeseburger, fries, and milkshake on menu
* 更牛逼的食材分析和菜谱推荐: http://pic2recipe.csail.mit.edu/ 加强版百度API
* 莫须有数据集
* 糖尿病 时间-血糖含量关系数据 : https://archive.ics.uci.edu/ml/datasets/diabetes
* GPA和饮食习惯的关系 : https://www.kaggle.com/borapajo/food-choices
**王天锐收集的资料**
0、9种体质 //暂定
1、根据用户的体质来进行推荐菜谱与制定营养计划 ---- 两种模式9体模式和普通健身模式
2、用户可以随时输入自己当前吃的食物的名字与量 ---- 随时记
3、动态爬虫——http://www.boohee.com/ 每种食材的卡路里等信息优先kaggle
4、卡路里累加器及其可视化、每天个人信息可视化
5、https://www.xinshipu.com/ 菜谱信息
6、通过照片提取出食物的卡路里等信息 百度api
7、http://www.zyyssl.com/cookbook.html //中药食材信息、药膳信息、9体、各种病针对的药膳
8、照片识菜帮
9、http://www.ttmeishi.com/CaiXi/YaoShan/ //病人对应的食谱
10、测算http://www.chinacaipu.com/zt/sccs.html 体质算法
11、http://www.chinacaipu.com/menu/jianya/ 特殊人群(压力之类的)
### 需求分析
* 登陆、注册
* 输入基本信息信息(身高、体重、性别、年龄)
* 额外信息(工作、周均运动时间、睡眠段、九体、病史)
* 针对没有填写额外信息的用户:选择减肥、增肌、塑形 、保持
* 可视化(自己的信息和目标标准的比较、根据上述选择改变)每天的量(手环、手机计步器),近几天的曲线
* 推荐菜谱两个tab一个定制菜谱一个是随机智能推送
* 单一菜推荐
* 组合推荐
* 一周大菜谱推荐(根据每日你自己加的一些信息动态改变)
* 如果填了额外信息的,就是药膳推荐(一周药膳、周二普通、周三药膳。。。。)(注意可能不想减肥啥的)
* 百度api->动态录入每顿饭的信息(防抖处理,这里吹牛逼算法,推测吃了多少卡路里),识别后把,动态改变一周定制计划
* 做菜环节加入识菜帮所有功能,并加入详细食材信息卡路里等
* 针对特殊人群,混到推荐里推送有利于健康的**方法**信息(敷黄瓜方法)
* 特殊病人群体每日相关东西的摄取量的一个限定区间显示
* ocr体检单信息录入
* **针对照片中菜的数量分析吃了多少菜,包含多少卡路里**
### 10-6更新小细节
* BMI小数
* 需不需要为每个用户加一个用于存放一周定制的类,(这个应该不是特别需要,只是想想)
* 模糊搜索
* 食材对应menu
#### 24日更新内容
粉尘接触得多的 吃纤维素
* 职业,某种病对各种物质的需求
* 修改职业,病(一些菜谱分类),体质 表
* 把职业分为几类(多动的,少动的)用于BMI标准
* https://www.google.com/search?q=%E8%90%A5%E5%85%BB%E5%85%83%E7%B4%A0%E9%9C%80%E6%B1%82&oq=%E8%90%A5%E5%85%BB%E5%85%83%E7%B4%A0&aqs=chrome.1.69i57j69i59j0l4.5781j0j1&sourceid=chrome&ie=UTF-8
* 职业\病\九体\体质(BMI) 结合起来的**物质需求标准** (要求有 **卡路里** 六芒星),以周为单位计算需求量
* 特殊职业(比如运动员)对身体素质(BMI)标准
* 早 中晚餐分类:
* 早: 饼 粥 羹 面 奶
* **加入季节方案(比如夏天就推荐防暑的,冬天推荐暖身的)**
* 蒋:
* 补充菜谱: url补充缺失值,卡路里,热量,脂肪,蛋白质等
* 爬卡路里时,原来的菜名是一列,新爬到的是一列,后面几列就是卡路里,脂肪等,注意数据规整
* 爬不到就先空下,根据食材的信息计算
* 食材的信息(包括卡路里等)
* http://www.boohee.com/food/search?keyword=%E8%8C%B6%E5%8F%B6%EF%BC%88%E7%BA%A650%E5%85%8B%EF%BC%89
* 菜谱的简单介绍
* 浏览记录(post username和menuname和时间)
王:定制( 需要蒋给我比如:蛋白质在100-200范围内的菜谱)
蒋:
* 体质表: 添加几列对某种物质的需求 √
* 职业表: 添加几列对某种物质的需求,添加一列BMI的需求 √
* user表: 添加综合对物质的需求 √
* 菜单表:
* 添加一列早/午晚餐,早为1,else为0. 根据 饼 粥 羹 面 奶 判断
* 补充一下缺失的url,卡路里 √
* 添加几列各种物质的需求 √
* 有一部分数据是爬下的csv里面直接读取,一部分缺失的用food_material的组合来计算
* **对接任务**: 接口使用方法可以参尻main函数里面的注释和数据库ER图
* WebUtil改成了单例,一些方法注意一下
* 注册: `createUser`.注意年龄应该让用户填出生年,获取年龄时每次都根据年份计算一下
* 直接set设置用户的各种信息,不需要的就空着不用set,特殊的一点是病有多个值,要用一个List
![](http://ww1.sinaimg.cn/large/0077h8xtly1fvu5tfi47aj30mv0gg403.jpg)
* 修改用户信息 `changeUserInfo`,注意username必须设置,其他的是需要改的值.**修改会覆盖之前的内容**.比如用户之前illness是健忘食谱,想增加一个高血压食谱, 就需要把之前的也写上,就是一起传 `健忘食谱,高血压食谱`这两个参数.写到List里面. 具体参考main函数里面的
* 获取九体信息 `getPhysique`方法
* 获取用户营养元素所需的量: 先`getUser`获取到用户的病/职业/体质名字,然后根据这些名字查询每个 病/职业/体质信息对应的元素需求,最后加权计算 (这里是不是麻烦了点?)
* 用户职业BMI分类 3多动,2中等,1少动 先 `getUser`获取到用户的职业名字.然后`getOccupation`获取到该职业的BMI分类
* 动态改变用户已吃的营养元素的量: 在用户表添加element参数,每周自动清空一次
* Map的可选参数: `[calorie,carbohydrate,fat ,protein,cellulose,vitaminA,vitaminB1,vitaminB2,vitaminB6,vitaminC,vitaminE,carotene,cholesterol,Mg,Ca,Fe,Zn,Cu,Mn,K ,P ,Na,Se,niacin ,thiamine]`
```java
public static void main(String[] args) {
//只传入变动的参数就行.
//比如 这顿饭摄入了100卡路里,10脂肪.就这样写.
Map<String, Double> params = new HashMap<>();
params.put("calorie", 100.0);
params.put("fat", 10.0);
//第一个参数是username,第二个参数是摄入的营养元素值.可以看函数的源码,有注释
WebUtil.getInstance().eatenElements("test5", params, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println(new Gson().fromJson(response.body().string(), MyUser.class));
}
});
}
```
* 获取用户本周已摄入的营养元素的量: `getUser`得到当前用户的信息,解析后用`MyUser`的`getEaten_elements()`获取到Element对象.里面有各种元素信息
* 根据多个食材组合来搜菜
```java
List<String> materialList = new ArrayList<>();
materialList.add("黄瓜");
materialList.add("茄子");
// materialList.add("鸡蛋");
WebUtil.getInstance().getMenusByMaterials(materialList, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//必须判断状态码,如果为200说明正常,如果为404,说明这几个食材组合查询不到可以做的菜
if (response.code() == 200) {
String json = response.body().string();
FoodMenu[] menus = new Gson().fromJson(json, FoodMenu[].class);
System.out.println(menus);
for (FoodMenu menu : menus) {
System.out.println(menu.getName());
}
} else {
System.out.println("查不到组合食材可以做的菜");
}
}
});
```
* 用户的浏览历史: 添加用户和菜谱的多对多关系
```java
//获取历史记录 传入username
WebUtil.getInstance().getEatenHistory("test5", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
History[] histories = new Gson().fromJson(json, History[].class);
System.out.println(Arrays.toString(histories));
}
});
//添加历史记录 传入username 和 Menu的名字
WebUtil.getInstance().addEatenHistory("test5", "多味茄子泥", new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
History history = new Gson().fromJson(json, History.class);
System.out.println(history);
}
});
```
* 菜名搜索: `getMenu`方法,传入菜名(菜名通过其他的各种关联方式获取) (menu.calorie是直接爬到的卡路里值,营养元素里的menu.elements.calorie卡路里是根据每个食材的卡路里计算的,相对来说,menu.calorie的值更准确)
* 功效搜菜 `getMenuClassification`传入分类(功效)参数,比如川菜.搜到所有的川菜名字.然后可以用菜名搜索搜某个菜的详细信息
* **点赞或评论来影响推荐顺序**
* **晒图区域**
* 营养量搜菜 : 搜索某个营养量范围内的菜
可选参数: `[calorie,carbohydrate,fat ,protein,cellulose,vitaminA,vitaminB1,vitaminB2,vitaminB6,vitaminC,vitaminE,carotene,cholesterol,Mg,Ca,Fe,Zn,Cu,Mn,K ,P ,Na,Se,niacin ,thiamine]`
```java
public static void main(String[] args) {
//首先构造一个Map, key是参数的名字,value是参数的值.用不到的参数不用写.
//我在服务器端根据这些参数构造一个sql,就是 ... WHERE key1 <= val1 AND ...这样的.
//所以你只传入需要作为搜索条件的参数就可以了.
Map<String, Double> params = new HashMap<>();
params.put("calorie", 100.0);
params.put("fat", 10.0);
WebUtil.getInstance().getMenusByElements(params, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
System.out.println(json);
//用轻量级的菜单类MenuLight解析json,这个类只有Menu的[名字,卡路里,元素对象的主码id]这三个域.想获取详细信息可以用getMenu方法获取
//这样是为了查询更快
FoodMenuLight[] foodMenuLights = new Gson().fromJson(json, FoodMenuLight[].class);
System.out.println(Arrays.toString(foodMenuLights));
}
});
}
```
* **季节搜菜**
* 小知识获取 : `getRandomTricks`
![1538310994730](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1538310994730.png)
![1538313835249](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1538313835249.png)
#### 又想到的补充内容
- 根据口味推荐,或者口味混合搭配推荐
- 注意冬天不推荐夏天的菜谱
### 数据库设计
![](http://ww1.sinaimg.cn/large/0077h8xtly1fvu67fbm8qj312f0sux6p.jpg)
**加下划线为主码,加粗为外码,默认not null**
* **菜谱**(<u>str菜名</u>, **nullable str体质_名称**(对应最优菜谱的效果) ,int卡路里,int制作时间(分钟),str口味,str工艺,str做法,str图片url)
* menu
* **食材**( <u>str名称</u>)
* material
* **体质**(<u>str体质名称</u>,str体质特点,str运动调理方式)
* physique
* **体质性状**(<u>str性状名称</u>)
* Physical properties
* **菜谱功能和分类**( <u>str分类名称</u>)
* menu classification
* **用户**( <u>str用户名</u>,str密码, **nullable str 体质-名称**,**nullable str特殊职业**)
* User
* **特殊职业**( <u>str职业名称</u>)
* Occupation
* 菜谱功能分类_可治愈的职业\_特殊职业( <u> **特殊职业-str职业名称**</u>, <u> **菜谱功能和分类-str分类名称**</u>)
* 菜谱\_做菜_食材 ( <u>**str菜谱-菜名**</u>,**<u>str食材-名称**</u>,int用量)
* cook quantity
* 食材\_效果_体质(<u> **str食材-名称**</u>,<u> **nullable str体质-名称**</u>,int效果(1有利于,0不利于))
* Material effect
* 体质\_身体状态_体质性状( <u> **str体质-名称**</u>, <u> **str体质性状-性状名称**</u>)
* physical_state
* 菜谱\_菜谱效果_菜谱功能和分类( <u> **str菜谱-菜名**</u>, <u> **str菜谱功能和分类-分类名称**</u>)
* menu_effect
### 服务器请求
| 说明 | 方法 | 请求示例 | 备注 |
| ------ | ---- | ---------------------------------------- | ----------------------------- |
| 查询菜单信息 | GET | http://120.77.182.38/menus/某菜名/ | 不加菜名默认请求所有菜单(服务器可能扛不住) |
| 查询食材信息 | GET | http://120.77.182.38/foodmaterial/西红柿/ | 同上 |
| 查询用户信息 | GET | http://120.77.182.38/myuser/zhaolizhi/ | 同上 |
| 新建用户信息 | POST | http://120.77.182.38/myuser/ | 参数见下图 |
| 查询菜谱分类 | GET | http://120.77.182.38/menuclassification/糖尿病食谱/ | 不加分类名默认请求所有分类(和对应的菜谱),响应时间较长 |
| 查询职业信息 | GET | http://120.77.182.38/occupation/电力工程师/ | 不加职业名默认查询所有,响应较快 返回职业对应的菜单分类 |
| 查询体质信息 | GET | http://120.77.182.38/physique/气虚质/ | 返回体质需要的食材 |
| | | | |
| | | | |
* POST新建用户信息`params`示例
* 1♂ 0♀
* `occupation_name`,`physical_name`的值必须和数据库对应
![](http://ww1.sinaimg.cn/large/0077h8xtly1fvjbfh6vm1j30r70eh3zj.jpg)
## 国赛阶段
### 代码
* 优化了`getRandomMenus方法`,传入username参数.会根据user的体质,职业,病理推荐菜
```java
public void getRandomMenus(int count, String username, Callback callback)
```
这个方法之前的版本没有username参数,**现在弃用原来的版本,原来的方法仍然可以调用,需要把项目的所有getRandomMenus方法调用加上一个username参数**
### 问题
* ~~连续识别,出现错误的,点一下消去 锐!~~
* ~~bug: 连续拍照后 点了一周定制 锐~~
* ~~*食材模糊识别 ok*~~
* ~~通过食材组合,搜索菜 ,菜要符合username的信息 蒋和锐 `getMenusByMaterials`~~
* 卡路里不对
* ~~*早餐晚餐的搜索不随机 shuffle了一下.ok*~~
* ~~`get_menus_by_elements` django随机一下~~
* 周定制下面的两个按钮 锐
* ~~*搜菜如果搜不到 把name减一下再搜 ok*~~
* getRandomMenus的调用里面加上username参数 锐
* 吃饭的时候没拍照,吃饭完了才想添加,但是菜图片没有了.需要输入添加 (王)
* 口味信息采集
* 历史记录
* 社交功能: 点赞,晒图,评论
### 时间安排
* 周日上午答辩
* 周五排练
### PPT安排
* 小组分工介绍
* 产品背景 秦
* 量身定制 林
* 周定制 林
* 动态添加 智能定量 赵
* 拍食材做菜(食菜帮) 赵
* 菜谱推荐 秦
* 产品亮点 秦
* 产品难点 王
* 未来展望 王
* 相信在不就得将来,在AI智能定制膳食的帮助下,人们不再为职业病,慢性病所烦恼,享受科学膳食带来的健康生活.
### 需要演示的功能
* 拍照 菜品识别 识别 烤鸭 土豆丝 鱼香肉丝 红烧肉 炒面 (动态调量,修改当天余额)
* 拍照 食材识别 胡萝卜 白萝卜 姜 长条茄子 菜花 (根据用户的信息,并且是多搜索)
* 周定制(最左边的fragment)