Skip to content

Commit dcbdd83

Browse files
committed
Merge commit 'bb0c5a7bc83aea6f2d79ba1bc8f1f0311afa6f68' into deploy
2 parents 3a89585 + bb0c5a7 commit dcbdd83

31 files changed

+1159
-174
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
__pycache__
22
config.yml
33

4+
src/static/webpack/*
45
.DS_Store
5-
6+
.venv

README.md

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,70 @@
1-
# サンプル(プロダクト名)
1+
# にこトレ!
2+
3+
![ogp](https://user-images.githubusercontent.com/63311737/139258315-50e6f3f6-6d3b-4649-b5f0-4668fd451664.png)
24

3-
[![IMAGE ALT TEXT HERE](https://jphacks.com/wp-content/uploads/2021/07/JPHACKS2021_ogp.jpg)](https://www.youtube.com/watch?v=LUPQFB4QyVo)
45

56
## 製品概要
7+
ミライ小町ちゃんと一緒に表情筋のトレーニングができるアプリケーションです.
8+
9+
顔認識機能を搭載し,リアルタイムにミライ小町ちゃんからアドバイスをしてもらえます!
10+
611
### 背景(製品開発のきっかけ、課題等)
12+
コロナ禍で人と会う機会が減り,表情筋を使う機会が大幅に減ってしまっています.
13+
14+
しかし表情筋が衰えると顔が老けて見えてしまったりするなど様々なデメリットがあります.
15+
16+
そんな悩みを解消するために,自宅で簡単に楽しく表情筋を鍛えることができれば良いと考え制作しました.
717
### 製品説明(具体的な製品の説明)
18+
19+
実際にミライ小町ちゃんと一緒に「あいうえお体操」と呼ばれる表情筋全体を鍛えることができるトレーニングを行います.
20+
顔認識機能を搭載しており,小町ちゃんからアドバイスをもらいながらトレーニングができます.
21+
- 初心者モード
22+
- あいうえお体操のやり方が分からない人に向けてミライ小町ちゃんがやり方を教えてくれながらトレーニングをすることができます
23+
- 経験者モード
24+
- 慣れてきた人向けに実際にサクサクトレーニングを行えるモードです.
25+
26+
827
### 特長
9-
####1. 特長1
10-
####2. 特長2
11-
####3. 特長3
28+
29+
#### 1. ミライ小町ちゃんと一緒にトレーニングができる!
30+
#### 2. 顔認識機能を搭載しリアルタイムにミライ小町ちゃんからアドバイスをもらいながらトレーニングできる!
1231

1332
### 解決出来ること
33+
にこトレ!はコロナ禍で使われにくい表情筋のトレーニングをすることができ,顔の老け防止や小顔効果を期待することができます.
1434
### 今後の展望
35+
現状はあいうえお体操にとどまっていますが,今後さらなる体操などを搭載したい他,
36+
37+
顔の表情でコマンドを入力しミライ小町ちゃん遊べるようなミニゲーム等を搭載し,より楽しくトレーニングができるようにしたいと考えています.
1538
### 注力したこと(こだわり等)
16-
*
17-
*
39+
* ミライ小町ちゃんと一緒にトレーニングができる!という世界観
40+
* 扱いやすいUI
1841

1942
## 開発技術
2043
### 活用した技術
2144
#### API・データ
22-
*
23-
*
45+
* バンダイナムコ研究所さん提供
46+
- ミライ小町の3Dデータ
47+
- ミライ小町のボイスサンプルデータ
48+
2449

2550
#### フレームワーク・ライブラリ・モジュール
26-
*
27-
*
51+
* HTML
52+
* CSS(Sass)
53+
* JavaScript( jQuery / Three.js / Vue.js )
54+
* TypeScript
55+
* python(Flask)
56+
* webpack
57+
* Heroku
58+
* Unity
2859

2960
#### デバイス
30-
*
61+
* なし
3162
*
3263

3364
### 独自技術
3465
#### ハッカソンで開発した独自機能・技術
35-
* 独自で開発したものの内容をこちらに記載してください
36-
* 特に力を入れた部分をファイルリンク、またはcommit_idを記載してください。
66+
* JSのclmtrackrによる顔ランドマーク推定機能
67+
* Three.jsによる3Dモデルの制御
3768

3869
#### 製品に取り入れた研究内容(データ・ソフトウェアなど)(※アカデミック部門の場合のみ提出必須)
3970
*

src/app.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,19 @@ def index():
88
return render_template("top.html", pageTitle='TopPage', css='top')
99

1010

11+
@app.route("/top", methods=["POST"])
12+
def move_top():
13+
return render_template("top.html", pageTitle='TopPage', css='top')
14+
15+
1116
@app.route('/face', methods=['POST'])
17+
def face():
18+
return render_template("face.html", pageTitle='FacePage', css='face')
19+
20+
21+
@app.route('/faceTest')
1222
def face_test():
13-
return render_template("test_face.html", pageTitle='FacePage', css='face')
23+
return render_template("test_face.html", pageTitle='FaceTestPage', css='face_test')
1424

1525

1626
@app.route('/emotion')

src/entry/js/components/face_func.js

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,27 @@ function drawLoop() {
3333
requestAnimationFrame(drawLoop);
3434

3535
// 比較用変数に値が入っているか確認
36-
if (positionStorage != null) {
37-
console.log(positionStorage[3][0]);
38-
}
36+
/*if (positionStorage != null) {
37+
console.log(positionStorage[3][0]);}
38+
*/
3939
// 顔部品の現在位置の取得
4040
var positions = tracker.getCurrentPosition();
41-
console.log(positions[3][0]);
42-
/*
43-
ここで現在位置と前回位置の計算を行う
44-
*/
41+
42+
//ここで現在位置と前回位置の計算を行う
43+
//x方向の値を計算する
44+
var faceWidth = positions[11][0]-positions[3][0]
45+
var lipWidth = positions[50][0] - positions[44][0]
46+
var xMouth = lipWidth/faceWidth
47+
48+
var faceHeight = positions[37][1] - positions[7][1]
49+
var lipHeightLeft = positions[44][1] - positions[7][1]
50+
var lipHeightRight = positions[50][1] - positions[7][1]
51+
var yMouthLeft = lipHeightLeft/faceHeight
52+
var yMouthRight = lipHeightRight/faceHeight
53+
4554
// 顔部品の現在位置を比較用変数に代入して値を更新する
46-
positionStorage = positions
47-
console.log(positionStorage[3][0]);
55+
var positionStorage = positions
56+
//console.log(positionStorage[3][0]);
4857

4958
// データの表示
5059
showData(positions);
@@ -58,14 +67,19 @@ drawLoop();
5867

5968
// 顔部品(特徴点)の位置データを表示する showData 関数
6069
function showData(pos) {
70+
/*
6171
//test
6272
console.log('右口角の座標');
6373
console.log('x座標:「'+pos[44][0]+'」y座標:「' + pos[44][1] + '」');
6474
console.log('左口角の座標');
6575
console.log('x座標:「' + pos[50][0] + '」y座標:「' + pos[50][1] + '」');
66-
console.log('2点の差');
67-
console.log('x座標:「' + Math.round(pos[50][0] - pos[44][0]) + '」y座標:「' + Math.round(pos[50][1] - pos[44][1] )+ '」');
68-
76+
*/
77+
//console.log('Xの2点');
78+
//console.log('x座標:「' + Math.round(pos[50][0] - pos[44][0]) + '」y座標:「' + Math.round(pos[50][1] - pos[44][1] )+ '」');
79+
//console.log('x座標:「' + Math.round(pos[11][0] - pos[3][0]) + '」y座標:「' + Math.round(pos[50][1] - pos[3][1] )+ '」');
80+
console.log('頬:「' + Math.round(pos[11][0] - pos[3][0]) + '」くちびる:「' + Math.round(pos[50][0] - pos[44][0] )+ '」');
81+
console.log('鼻下: 「'+Math.round(pos[37][1] - pos[7][1]) + '」唇: 「'+Math.round(pos[44][1] - pos[7][1])+'」');
82+
6983
// データの文字列を入れる変数
7084
var str = "";
7185
// 全ての特徴点(71個)について

src/entry/js/components/face_vue.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const face = new Vue({
2+
el: '#face',
3+
// FlaskとVueを共存させるためにDelimiterを変更する
4+
delimiters: ["[[", "]]"],
5+
data: {
6+
modeChoicePage: true,
7+
beginnerPage: false,
8+
advancedPage: false,
9+
startBtn: true,
10+
nextBtnArea: false,
11+
modelMessage: 'こんにちは!',
12+
tutorialText: ['口を全体に大きく「あ」の形に開け、目を最大限に大きく見開き、眉毛をできるだけ上に上げます。', '口を横に大きく「い」の形に開け、顔全体を横に引っ張る意識で思い切り力を入れます。', '口をできるだけすぼめて「う」の形を作り、目はギュッと閉じ、顔のすべてのパーツを中心に集めるつもりで力を入れます。', '口を横に大きく「え」の形に開け、目は大きく見開き、口角を引き上げた位置でキープします。', '口を縦に大きく「お」の形に開け、目は驚いたときのように大きく見開き、顔全体を縦に引っ張る意識で力を入れます。'],
13+
advancedText: [
14+
{ id: '0', text: '・「あ」', check: 'done' },
15+
{ id: '1', text: '・「い」', check: '' },
16+
{ id: '2', text: '・「う」', check: '' },
17+
{ id: '3', text: '・「え」', check: '' },
18+
{ id: '4', text: '・「お」', check: '' }
19+
],
20+
tutorialCountNum: 0,
21+
nextBtnMessage: '次へ進む',
22+
animationFlag: -5 //ページの初期番号 camera位置修正に使う
23+
},
24+
methods: {
25+
beginnerMode: function () {
26+
this.modeChoicePage=false
27+
this.beginnerPage = true
28+
},
29+
advancedMode: function () {
30+
this.modeChoicePage=false
31+
this.advancedPage=true
32+
},
33+
trainingStart: function () {
34+
this.startBtn = false
35+
this.nextBtnArea = true
36+
this.animationFlag = 1 //進んだら一に戻す
37+
},
38+
replayBtn: function () {
39+
this.nextBtnArea = false
40+
this.startBtn = true
41+
//this.animationFlag = -1 //戻ったらマイナス-1
42+
},
43+
nextTraining: function () {
44+
if (this.tutorialCountNum < 4) {
45+
this.tutorialCountNum += 1
46+
this.replayBtn()
47+
if (this.tutorialCountNum == 4) {
48+
this.nextBtnMessage = 'おわる'
49+
}
50+
} else {
51+
this.tutorialCountNum = 0
52+
this.nextBtnMessage = '次へ進む'
53+
this.modeChoicePage = true
54+
this.beginnerPage =false
55+
}
56+
}
57+
}
58+
});

src/entry/js/pages/face.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
import '../../ts/index.ts';
33

44
// JavaScript
5-
import '../components/face_func.js';
5+
import '../components/test.js';
6+
import '../components/face_vue.js';

src/entry/js/pages/face_test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// TypeScript
2+
import '../../ts/index.ts';
3+
4+
// JavaScript
5+
import '../components/face_func.js';

src/entry/style/components/component.scss

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1+
/* 変数宣言 */
2+
$main-color:#ff943d;
3+
$dark-main-color:#f36d00;
4+
$bg-thin-color:#ffa963;
5+
$sub-color: #FFD655;
6+
$BG-white-thin: #fffffff3;
7+
$text-color: #494949;
8+
$grid-size: 12rem;
9+
110
html {
211
height:100%;
3-
background: #ff943d;
12+
background: $main-color;
413
}
514

615
body {
716
height:100%;
8-
background: repeating-linear-gradient(-45deg, #ffa963, 30px, #ff943d 0, #ff943d 120px);
17+
background: repeating-linear-gradient(-45deg, $bg-thin-color, 30px, $main-color 0, $main-color 120px);
918
}
1019

1120
#modelArea{
@@ -15,6 +24,41 @@ body {
1524
}
1625
}
1726

27+
/* model & dialog */
28+
.modelAndDialogue{
29+
width: unset;
30+
margin: unset;
31+
position: relative;
32+
.modelMessage{
33+
width: fit-content;
34+
max-width: 90%;
35+
position: absolute;
36+
top: 80%;
37+
left: 50%;
38+
transform: translateY(-50%) translateX(-50%);
39+
background-color: $BG-white-thin;
40+
padding: 1.5rem 2rem;
41+
border-radius: 10px;
42+
font-size: 1.1rem;
43+
color: $text-color;
44+
}
45+
}
46+
47+
/* 戻るボタン */
48+
.back2topBtn{
49+
width: fit-content;
50+
position: absolute;
51+
margin: 2rem;
52+
z-index: 500;
53+
color: #fff;
54+
button{
55+
.material-icons{
56+
font-weight: bold;
57+
font-size: 35px;
58+
}
59+
}
60+
}
61+
1862
/* mobileここから */
1963
@media screen and (max-width: 950px) {
2064
body {

0 commit comments

Comments
 (0)