Flow Week2 4๋ถ๋ฐ Team Turtle
- ์ฑ ์ ์์ ์ค๋ ์์์๋ ํ๋์ธ๋ค์ ์ํ Android ์ดํ๋ฆฌ์ผ์ด์ ์ ๋๋ค.
- ์ผํ๊ธฐ ์ซ์ ์ง์ฅ์ธ๋ค๊ณผ ๊ณต๋ถํ๊ธฐ ์ซ์ ํ์๋ค์๊ฒ ์ปค๋ฎค๋ํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์กฐ๊ธ์ด๋ผ๋ ๊ฑฐ๋ถ๋ชฉ์ด ๋ ๋์๊ฐ ๋ณด์ด๋ฉด ์๋์ ์ธ๋ฆฝ๋๋ค.
- ์ฌ๋ฐ๋ฅธ ์์ธ๋ฅผ ์ ์งํ๊ธฐ ์ํ ์คํธ๋ ์นญ ์์์ ์ ๊ณตํฉ๋๋ค.
- OS: Android (minSdk: 24, targetSdk: 34)
- Language: Java
- IDE: Android Studio
- Server: Django
- Database: Mysql
- Target Device: Galaxy S10
- ์๊ฐ ๋น๊ฒ์ด์ธ ๋ค์ ์ํ ์์ ๊ฒ์ํ์ ์ ๊ณตํฉ๋๋ค.
- ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ๊ฒ์๊ธ์ ๋จ๊ธฐ๊ณ ๋๊ธ์ ์์ฑํ ์ ์์ต๋๋ค.
- ๊ฒ์๊ธ์ ์์ /์ญ์ , ๋๊ธ์ ์ญ์ ๋ฅผ ์ง์ํฉ๋๋ค.
- ๋ง์ด ํ์ด์ง
- ๋๊ธ์ ๋ํ ๋ต๊ธ
- ํค๋ณด๋ ๋ฐฐํ์ ์ํ ์ค์๊ฐ ์ฑํ
- ์นด๋ฉ๋ผ๋ฅผ ํตํด ์ฌ์ฉ์์ ์์ธ๋ฅผ ๊ฐ์งํ์ฌ ๊ฒฝ๊ณ ์์ ์ธ๋ฆฝ๋๋ค.
- ์ฌ์ฉ์์ ์ด๊นจ, ๋ท๋ชฉ, ์ ์๋ฆฌ ์ธ ์ ์ detectํ๊ณ ๊ฐ๋๋ฅผ ๊ณ์ฐํฉ๋๋ค. (MediaPipe ์ฌ์ฉ)
- ๊ฐ๋๊ฐ 10๋๊ฐ ๋์ ๊ฒฝ์ฐ ํ๋ฉด์ ํ์๋๋ ์ ๋ค์ ๋ถ์ ์์ผ๋ก ๋ฐ๊พธ์ด ํ์ํ๊ณ ๊ฒฝ๊ณ ์์ ์ธ๋ฆฝ๋๋ค.
- ๊ณต๋ถ/์ ๋ฌด์ ์ง์คํ๋ ์ ๋๋ฅผ finetuned Neural Network๋ฅผ ํตํด ์ธก์
- ๊ณต๋ถ์ ์ง์คํ ์๊ฐ์ Database์ ์ ์ฅ
- Database์ ์ ์ฅ๋ ๊ณต๋ถ ์๊ฐ์ ์ปค๋ฎค๋ํฐ์ ์ธ์ฆ
- ๋ชฉ, ์ด๊นจ๊ฐ ๋ป๊ทผํ ๋ ๊ฐ๋จํ๊ฒ ํ ์ ์๋ ์คํธ๋ ์นญ ์์๋ค์ ์ ๊ณตํฉ๋๋ค.
- ์์ ์๋์ ์นด๋ฉ๋ผ๋ฅผ ํตํด ๋ด ์คํธ๋ ์นญ ์์ธ๋ฅผ ์ ๊ฒํ ์ ์์ต๋๋ค.
- Tab 2์์ ์ฌ์ฉํ Pose detect model์ ์ฌ์ฉํ์ฌ ์์๊ณผ ์ฌ์ฉ์ ๊ฐ์ ์์ธ ์ ์ฌ์ฑ์ ์ ๊ณต
- ์์ธ ์ ์ฌ ์ ๋๋ฅผ ์ถ์ ํ์ฌ ์คํธ๋ ์นญ์ ์์ฑ๋ ์ ๊ณต
- ๋ ๋ค์ํ ์์์ ๋ถ๋ฅํ์ฌ ์ ๊ณต
์ฝ๋ ๋ณด๊ธฐ
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
SurfaceHolder holder;
Camera camera = null;
public CameraSurfaceView(Context context) {
super(context);
init(context);
}
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
//์ด๊ธฐํ๋ฅผ ์ํ ๋ฉ์๋
holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//๋ง๋ค์ด์ง๋์์
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);//์นด๋ฉ๋ผ ๊ฐ์ฒด ์ฐธ์กฐ
try{
camera.setPreviewDisplay(holder);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//๋ณ๊ฒฝ
camera.startPreview(); //๋ ์ฆ๋ก ๋ถํฐ ๋ค์ด์ค๋ ์์์ ๋ฟ๋ ค์ค
camera.stopPreview();
camera.setDisplayOrientation(90);//์นด๋ฉ๋ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ค๋ฅธ์ชฝ ์ผ๋ก 90 ๋ํ์
camera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//์๋ฉธ
camera.stopPreview();//๋ฏธ๋ฆฌ๋ณด๊ธฐ์ค์ง
camera.release();
camera = null;
}
public boolean capture(Camera.PictureCallback callback){
if(camera != null){
camera.takePicture(null,null,callback);
return true;
}
else{
return false;
}
}
}
์ฝ๋ ๋ณด๊ธฐ
YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);
getLifecycle().addObserver(youTubePlayerView);
youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
@Override
public void onReady(@NonNull YouTubePlayer youTubePlayer) {
super.onReady(youTubePlayer);
String videoId = "S0Q4gqBUs7c";
youTubePlayer.loadVideo(videoId, 0);
}
});
์ฝ๋ ๋ณด๊ธฐ
public class CustomBottomNavigationView extends BottomNavigationView {
private Path mPath = new Path();
private Paint mPaint = new Paint();
private static final int CURVE_CIRCLE_RADIUS = 190 / 2;
private Point mFirstCurveStartPoint = new Point();
private Point mFirstCurveEndPoint = new Point();
private Point mFirstCurveControlPoint1 = new Point();
private Point mFirstCurveControlPoint2 = new Point();
private Point mSecondCurveStartPoint = new Point();
private Point mSecondCurveEndPoint = new Point();
private Point mSecondCurveControlPoint1 = new Point();
private Point mSecondCurveControlPoint2 = new Point();
private int mNavigationBarWidth = 0;
private int mNavigationBarHeight = 0;
public CustomBottomNavigationView(Context context) {
super(context);
init();
}
public CustomBottomNavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(ContextCompat.getColor(getContext(), R.color.black));
setBackgroundColor(Color.TRANSPARENT);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mNavigationBarWidth = getWidth();
mNavigationBarHeight = getHeight();
mFirstCurveStartPoint.set(mNavigationBarWidth / 2 - CURVE_CIRCLE_RADIUS * 2 - CURVE_CIRCLE_RADIUS / 3, 0);
mFirstCurveEndPoint.set(mNavigationBarWidth / 2, CURVE_CIRCLE_RADIUS + CURVE_CIRCLE_RADIUS / 4);
mSecondCurveStartPoint = mFirstCurveEndPoint;
mSecondCurveEndPoint.set(mNavigationBarWidth / 2 + CURVE_CIRCLE_RADIUS * 2 + CURVE_CIRCLE_RADIUS / 3, 0);
mFirstCurveControlPoint1.set(mFirstCurveStartPoint.x + CURVE_CIRCLE_RADIUS + CURVE_CIRCLE_RADIUS / 4, mFirstCurveStartPoint.y);
mFirstCurveControlPoint2.set(mFirstCurveEndPoint.x - CURVE_CIRCLE_RADIUS * 2 + CURVE_CIRCLE_RADIUS, mFirstCurveEndPoint.y);
mSecondCurveControlPoint1.set(mSecondCurveStartPoint.x + CURVE_CIRCLE_RADIUS * 2 - CURVE_CIRCLE_RADIUS, mSecondCurveStartPoint.y);
mSecondCurveControlPoint2.set(mSecondCurveEndPoint.x - (CURVE_CIRCLE_RADIUS + CURVE_CIRCLE_RADIUS / 4), mSecondCurveEndPoint.y);
mPath.reset();
mPath.moveTo(0F, 0F);
mPath.lineTo(mFirstCurveStartPoint.x, mFirstCurveStartPoint.y);
mPath.cubicTo(mFirstCurveControlPoint1.x, mFirstCurveControlPoint1.y, mFirstCurveControlPoint2.x, mFirstCurveControlPoint2.y, mFirstCurveEndPoint.x, mFirstCurveEndPoint.y);
mPath.cubicTo(mSecondCurveControlPoint1.x, mSecondCurveControlPoint1.y, mSecondCurveControlPoint2.x, mSecondCurveControlPoint2.y, mSecondCurveEndPoint.x, mSecondCurveEndPoint.y);
mPath.lineTo(mNavigationBarWidth, 0F);
mPath.lineTo(mNavigationBarWidth, mNavigationBarHeight);
mPath.lineTo(0F, mNavigationBarHeight);
mPath.close();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mPath, mPaint);
}
}