Skip to content

chojaework/MadCamp-Week2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

80 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Pyeo

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

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์†Œ๊ฐœ

Tab 1 - ์ปค๋ฎค๋‹ˆํ‹ฐ

Community

์ฃผ์š” ๊ธฐ๋Šฅ

  • ์‹œ๊ฐ„ ๋นŒ๊ฒŒ์ด์ธ ๋“ค์„ ์œ„ํ•œ ์ž์œ ๊ฒŒ์‹œํŒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ฒŒ์‹œ๊ธ€์„ ๋‚จ๊ธฐ๊ณ  ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ฒŒ์‹œ๊ธ€์˜ ์ˆ˜์ •/์‚ญ์ œ, ๋Œ“๊ธ€์˜ ์‚ญ์ œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ฐจํ›„ ์ถ”๊ฐ€๋  ๊ธฐ๋Šฅ

  • ๋งˆ์ด ํŽ˜์ด์ง€
  • ๋Œ“๊ธ€์— ๋Œ€ํ•œ ๋‹ต๊ธ€
  • ํ‚ค๋ณด๋“œ ๋ฐฐํ‹€์„ ์œ„ํ•œ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…

Tab 2 - ๊ฑฐ๋ถ๋ชฉ ๊ฐ์ง€

์ฃผ์š” ๊ธฐ๋Šฅ

  • ์นด๋ฉ”๋ผ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ์ž์„ธ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ๊ฒฝ๊ณ ์Œ์„ ์šธ๋ฆฝ๋‹ˆ๋‹ค.
    • ์‚ฌ์šฉ์ž์˜ ์–ด๊นจ, ๋’ท๋ชฉ, ์ •์ˆ˜๋ฆฌ ์„ธ ์ ์„ detectํ•˜๊ณ  ๊ฐ๋„๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. (MediaPipe ์‚ฌ์šฉ)
    • ๊ฐ๋„๊ฐ€ 10๋„๊ฐ€ ๋„˜์„ ๊ฒฝ์šฐ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ์ ๋“ค์„ ๋ถ‰์€ ์ƒ‰์œผ๋กœ ๋ฐ”๊พธ์–ด ํ‘œ์‹œํ•˜๊ณ  ๊ฒฝ๊ณ ์Œ์„ ์šธ๋ฆฝ๋‹ˆ๋‹ค.

์ฐจํ›„ ์ถ”๊ฐ€๋  ๊ธฐ๋Šฅ

  • ๊ณต๋ถ€/์—…๋ฌด์— ์ง‘์ค‘ํ•˜๋Š” ์ •๋„๋ฅผ finetuned Neural Network๋ฅผ ํ†ตํ•ด ์ธก์ •
  • ๊ณต๋ถ€์— ์ง‘์ค‘ํ•œ ์‹œ๊ฐ„์„ Database์— ์ €์žฅ
  • Database์— ์ €์žฅ๋œ ๊ณต๋ถ€ ์‹œ๊ฐ„์„ ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ธ์ฆ

Tab 3 - ์ŠคํŠธ๋ ˆ์นญ ์˜์ƒ ์ œ๊ณต

์ฃผ์š”๊ธฐ๋Šฅ

  • ๋ชฉ, ์–ด๊นจ๊ฐ€ ๋ป๊ทผํ•  ๋•Œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ์ŠคํŠธ๋ ˆ์นญ ์˜์ƒ๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์˜์ƒ ์•„๋ž˜์˜ ์นด๋ฉ”๋ผ๋ฅผ ํ†ตํ•ด ๋‚ด ์ŠคํŠธ๋ ˆ์นญ ์ž์„ธ๋ฅผ ์ ๊ฒ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐจํ›„ ์ถ”๊ฐ€๋  ๊ธฐ๋Šฅ

  • Tab 2์—์„œ ์‚ฌ์šฉํ•œ Pose detect model์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜์ƒ๊ณผ ์‚ฌ์šฉ์ž ๊ฐ„์˜ ์ž์„ธ ์œ ์‚ฌ์„ฑ์„ ์ œ๊ณต
  • ์ž์„ธ ์œ ์‚ฌ ์ •๋„๋ฅผ ์ถ”์ ํ•˜์—ฌ ์ŠคํŠธ๋ ˆ์นญ์˜ ์™„์„ฑ๋„ ์ œ๊ณต
  • ๋” ๋‹ค์–‘ํ•œ ์˜์ƒ์„ ๋ถ„๋ฅ˜ํ•˜์—ฌ ์ œ๊ณต

๊ธฐ์ˆ  ์„ค๋ช…

1. ์นด๋ฉ”๋ผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์บก์ฒ˜

์ฝ”๋“œ ๋ณด๊ธฐ
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;
        }
    }
}

2. ์œ ํŠœ๋ธŒ ์˜์ƒ ๋กœ๋”

์ฝ”๋“œ ๋ณด๊ธฐ
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);
    }
});

3. Custom BottomNavigationView

์ฝ”๋“œ ๋ณด๊ธฐ
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);
    }
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages