diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..73d94f4 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,61 @@ +name: Docker Test + +on: + push: + branches: [ main ] + +env: + DOCKER_IMAGE: ghcr.io/swthewhite/myproject + VERSION: ${{ github.sha }} + NAME: newdevelop + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup docker buildx + id: buildx + uses: docker/setup-buildx-action@v1 + + - name: Cache docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ env.VERSION }} + restore-keys: | + ${{ runner.os }}-buildx- + - name: Login to ghcr + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GHCR_TOKEN }} + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + push: true + tags: ${{ env.DOCKER_IMAGE }}:latest + + deploy: + needs: build + name: Deploy + runs-on: [ self-hosted ] + steps: + - name: Login to ghcr + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GHCR_TOKEN }} + + - name: Docker run + run: | + docker stop ${{ env.NAME }} && docker rm ${{ env.NAME }} && docker rmi ${{ env.DOCKER_IMAGE }}:latest + docker run -d -p 3000:3000 --name ${{ env.NAME }} --restart always ${{ env.DOCKER_IMAGE }}:latest diff --git a/CamDevice/main.py b/CamDevice/main.py index 60ea185..67e3852 100644 --- a/CamDevice/main.py +++ b/CamDevice/main.py @@ -2,7 +2,7 @@ if __name__ == "__main__": # 클래스 인스턴스 생성 및 실행 - upload_url = 'http://localhost:8000/uploadfile' + upload_url = 'http://localhost:3000/uploadfile' upload_filename = 'photo.jpg' image_sender = ImageSender(upload_url, upload_filename, "cv") image_sender.run() diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..37192e9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3.11.1 + +WORKDIR /code + +COPY ./requirements.txt /code/requirements.txt + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get install -y tzdata +RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime + +RUN apt-get update +RUN apt-get -y install libgl1-mesa-glx wget +RUN pip install --no-cache-dir -r /code/requirements.txt + +COPY . /code + +WORKDIR /code/WebServer/yolo_data + +RUN wget https://pjreddie.com/media/files/yolov3.weights + +WORKDIR /code/WebServer + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3000"] diff --git a/README.md b/README.md index ec99d9e..709583a 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,43 @@ -# SSCCounter-v0.1.0 +# 📃 SSCCounter README
-image - + +image + + [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=http%3A%2F%2Fssccounter.shop&count_bg=%2379C83D&title_bg=%23555555&icon=airplayvideo.svg&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) +
-# SSCCounter Web Page v0.1.0 -> **숭실대학교 컴퓨터 동아리 (SSCC: SoongSil ComputingClub)**
**개발기간: 2022.06 ~ 2023.05** +> **숭실대학교 컴퓨터 동아리 (SoongSil ComputingClub)**
+> **개발기간: 2022.06~**
+> **Version: 0.2.0** ## 배포 주소 +> **웹페이지** : [http://ssccounter.sscc.run/](http://www.ssccounter.sscc.run/)
+> **프론트 서버** : [http://ssccounter.sscc.run/uploadfile/](http://www.ssccounter.sscc.run/uploadfile/)
+> **Json 요청** : [http://ssccounter.sscc.run/ssccounter.json/](http://www.ssccounter.sscc.run/ssccounter.json/) -> **웹페이지** : [http://www.ssccounter.shop/](http://www.ssccounter.shop/)
-> **프론트 서버** : [http://www.ssccounter.shop/uploadfile/](http://www.ssccounter.shop/uploadfile/)
-> **Json 요청** : [http://www.ssccounter.shop/ssccounter.json/](http://www.ssccounter.shop/ssccounter.json/) - -## 웹개발팀 소개 - +## 팀원 구성
- -| 백승우 | 원영진 | -| :------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------: | -| | | -| [@SWtheWhite](https://github.com/SWtheWhite) | [@AI-WonYJ](https://github.com/AI-WonYJ) | -| 숭실대학교 전자정보공학부 (it융합전공) 4학년 | 숭실대학교 AI융합학부 2학년 | -| SSCC 36th | SSCC 40th | -| Design & Front | HardWare & Web Server | + +| 백승우 | 원영진 | 이종인 | +| :------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| | | | +| [@SWtheWhite](https://github.com/SWtheWhite) | [@AI-WonYJ](https://github.com/AI-WonYJ) | [@bell-person-ii](https://github.com/bell-person-ii) | +| SSCC 36th | SSCC 40th | SSCC 39th | +| PM & WEB | HardWare & WEB | WEB | +
- -## 프로젝트 소개 -SSCCounter은 동아리방 인원수 카운터 머신입니다. 기존에 많은 사람들이 동아리방에 몇명이나 있는지 문의하는 글이 자주 올라왔었는데, 하루에도 2~3번 씩 올라오는 문의 글로 인해, 중요한 공지 글을 확인하기 힘들었다. 이를 해결하기 위해 동아리방 사용 인원수를 알려주는 머신이 있으면 좋겠다는 요청에 진행된 '2022 여름방학 Smart동방 프로젝트' 중 'nCnt' 개발 프로젝트에서 시작되었습니다. 현재는 Smart동방 프로젝트가 종료됨에 따라 'SSCCounter'라는 이름으로 변경되었으며, 매일 평균 30명 이상이 서비스를 이용하는 동아리 핵심 프로젝트로 진행되고 있습니다. +## 프로젝트 소개 +SSCCounter은 동아리방 인원수 카운터 머신입니다. 기존에 많은 사람들이 동아리방에 몇명이나 있는지 문의하는 글이 자주 올라왔었는데, 하루에도 2~3번 씩 올라오는 문의 글로 인해, 중요한 공지 글을 확인하기 힘들었다. 이를 해결하기 위해 동아리방 사용 인원수를 알려주는 머신이 있으면 좋겠다는 요청에 진행된 '2022 여름방학 Smart동방 프로젝트' 중 'nCnt' 개발 프로젝트에서 시작되었습니다. 현재는 Smart동방 프로젝트가 종료됨에 따라 'SSCCounter'라는 이름으로 변경되었으며, 매일 평균 30명 이상이 서비스를 이용하는 동아리 핵심 프로젝트로 진행되고 있습니다. -#### SSCCounter uses 'YOLOv3 Object Detection Neural Network'. +### SSCCounter uses 'YOLOv3 Object Detection Neural Network'. You can easily check the number of people using the club room by analyzing the images processed by YOLOv3. Thanks to real-time analysis of the club room images, you can instantly verify the number of people without any delays. -#### SSCCounter's website will give you a check-friendly environment. +### SSCCounter's website will give you a check-friendly environment. Our website supports the following component. 1. Last refresh time. @@ -52,21 +53,26 @@ For building and running the application you need: ### Installation ``` bash -$ git clone https://github.com/AI-WonYJ/SSCCounter.git -$ cd SSCCounter/Newest_Version +$ git clone https://github.com/SoongSilComputingClub/SSCCounter.git +$ cd SSCCounter +$ apt-get update +$ apt-get -y install libgl1-mesa-glx wget $ pip install -r requirements.txt -``` -#### YOLOv3 Model -``` -$ cd YOLO_Folder -``` -#### Frontend +$ cd WebServer/yolo_data +$ wget https://pjreddie.com/media/files/yolov3.weights ``` -$ uvicorn SSCCounter_WebServer:app --reload --port=8000 --host=0.0.0.0 +#### CamDevice +```bash +$ cd CamDevice +$ python3 main.py ``` ---- +#### WebServer +```bash +$ cd WebServer +$ uvicorn main:app --reload --port=3000 --host=0.0.0.0 +``` ## Stacks 🐈 @@ -106,92 +112,125 @@ $ uvicorn SSCCounter_WebServer:app --reload --port=8000 --host=0.0.0.0 ## 주요 기능 📦 ### ⭐️ 동아리 인원수를 숫자와 이미지로 확인 가능 -- 숫자뿐만 아니라 이미지 또한 인원수에 따라 변하게 하여 한눈에 확인 가능 +* [x] 숫자뿐만 아니라 이미지 또한 인원수에 따라 변하게 하여 한눈에 확인 가능 ### ⭐️ 동아리 홍보 페이지 연계 -- 아이콘을 클릭하면 동아리 홍보 페이지나, 소셜 네트워크 페이지로 연결 +* [x] 아이콘을 클릭하면 동아리 홍보 페이지나, 소셜 네트워크 페이지로 연결 ### ⭐️ 새로고침 버튼 -- 간편하게 버튼 하나로 동아리방 인원수를 새로고침 +* [x] 간편하게 버튼 하나로 동아리방 인원수를 새로고침 + +--- +## 릴리즈 버젼 +### Version 0.1.0 +* [x] Device: capture image +* [x] Analysis: get people count from image +* [x] WebServer: show people count +### Version 0.2.0 +* [x] Refactor: e.v.e.r.y.(Divide and Unite) +* [x] Add: Dockerfile +* [x] Add: Requirements.txt +* [x] Feat: Github Action +* [x] Update: README.md +* [x] Fix: 307error +* [x] Fix: upload port + --- ## 도입 예정 기능 및 성능 개선 📝 -### ⭐️ Web Page 개편 -* [ ] UX/UI를 더욱 눈에 띄도록 메인 페이지를 개편 +### 0. log 기능 추가 +* [ ] logging 기능 추가 -### ⭐️ APP 출시 +### 1. Database 추가 +* [ ] log 기록을 위한 Database 추가 + +### 2. 인터페이스 개선 +* [ ] UX/UI를 더욱 눈에 띄도록 메인 페이지를 개선 + +### 3. API 활용 계획 수립 * [ ] URL 접속이 아닌, APP을 통해 확인할 수 있는 APP 서비스 출시 * [ ] PUSH 알림 등으로 더욱 간편하게 확인 -### ⭐️ 동아리방 환경 정보 제공 기능 추가 -* [ ] 온도 및 습도 정보와 공기 오염도를 확인할 수 있는 기능 추가 - -### ⭐️ 로그인 기능 추가 +### 4. 로그인 기능 추가 * [ ] 동아리 외부인이 접속할 수 없도록 로그인 기능 추가 -### ⭐️ AI 인원수 예측 기능 추가 +### 5. 동아리방 환경 정보 제공 기능 추가 +* [ ] 온도 및 습도 정보와 공기 오염도를 확인할 수 있는 기능 추가 + +### 6. AI 인원수 예측 기능 추가 * [ ] 요일과 날씨, 학교 행사 정보 등을 이용해 동아리방 인원수를 예측 -### ⭐️ YOLO 모델 업그레이드 +### ~~7. YOLO 모델 업그레이드~~ * [ ] YOLOv3 -> YOLOv4, 5, ... 8 중 상위 모델로 업그레이드 --- ## 아키텍쳐 ### 디렉토리 구조 -```bash +``` +. ├── README.md +├── Dockerfile +├── LICENSE ├── requirements.txt -├── photo.jpg -├── SSCCounter webpage image.jpg -├── Arduino_Serial_test.py -├── SSCCounter_RP4.py -├── SSCCounter_Analysis.py -├── SSCCounter_WebServer.py -├── Module -│   ├── data_handler.py -│   ├── yolov3.py -├── Data_Folder -│   ├── nCnt.txt -├── Yolo_Folder -│   ├── yolov3.cfg -│   ├── yolov3.md : yolov3.weight 다운로드 방법 -├── templates -│   ├── index(Ver_8).html : 메인 webpage -│   ├── docs.html : 개발자용 webpage -│   ├── image.html -│   ├── manager.html -│   ├── new.html -│   ├── test.html -└── static - ├── css - │   ├── main(Ver_2).css - │   ├── main.css - │   └── new.css - └── images - ├── 0 people.png - ├── 1 people.png - ├── 2 people.png - ├── 3 people.png - ├── 4 people.png - ├── 5 people.png - ├── 6 people.png - ├── people.png - ├── Kakao_lion.png - ├── SSCC_logo.png - ├── SSCC_logo_rev.png - ├── discord.png - ├── facebook.png - ├── humidity.png - ├── instagram.png - ├── kakao.png - ├── logo.png - ├── notion.png - ├── temperature.png - ├── analysis.jpg - ├── analysis3.jpg - ├── analysis_outdoor.jpg - └── photo_out.jpg - +├── CamDevice +│   ├── main.py +│   └── utils +│   ├── image_creater +│   │   ├── cv2.py +│   │   └── pi.py +│   └── image_sender.py +└── WebServer +    ├── main.py +    ├── static +    │   ├── css +    │   │   ├── contribute.css +    │   │   ├── contribute2 +    │   │   ├── main(Ver_2).css +    │   │   ├── main.css +    │   │   └── new.css +    │   └── images +    │   ├── 0 people.png +    │   ├── 1 people.png +    │   ├── 2 people.png +    │   ├── 3 people.png +    │   ├── 3analysis.jpg +    │   ├── 4 people.png +    │   ├── 5 people.png +    │   ├── 6 people.png +    │   ├── Kakao_lion.png +    │   ├── SSCC_logo.png +    │   ├── SSCC_logo_rev.png +    │   ├── analysis.jpg +    │   ├── analysis_outdoor.jpg +    │   ├── discord.png +    │   ├── facebook.png +    │   ├── humidity.png +    │   ├── instagram.png +    │   ├── kakao.png +    │   ├── logo.png +    │   ├── notion.png +    │   ├── people.png +    │   ├── photo_out.jpg +    │   └── temperature.png +    ├── temp +    │   ├── analysis.jpg +    │   └── photo.jpg +    ├── templates +    │   ├── Contribute.html +    │   ├── docs.html +    │   ├── image.html +    │   ├── index(Ver_8).html +    │   ├── manager.html +    │   ├── new.html +    │   └── test.html +    ├── utils +    │   └── count +    │   ├── yolo.py +    │   └── yolo_test.py +    └── yolo_data +    ├── yolov3.cfg + ├── yolov3.weights +    └── yolov3.md ``` diff --git a/WebServer/main.py b/WebServer/main.py index 5f985d7..5e672e5 100644 --- a/WebServer/main.py +++ b/WebServer/main.py @@ -24,12 +24,13 @@ async def count(): except: print( f"시간: {datetime.now()} >>> SSCCount: Error!") + # 2초마다 갱신 await asyncio.sleep(2) ## Backend ## -#app = FastAPI(docs_url=None, redoc_url=None) -app = FastAPI() +app = FastAPI(docs_url=None, redoc_url=None) +#app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="templates") @@ -49,7 +50,7 @@ async def Page(request: Request): else: countable = 0 - # FastAPI로 new.html에 변수 값 전달 + # index.html에 변수 값 전달 return templates.TemplateResponse("index(Ver_8).html", {"request": request, "People_Count": int(SSCCount), "Countable": countable, "last_time": current_time, "get_time": current_time, "Get_Time": Standard_Time}) @@ -60,13 +61,13 @@ async def ContributorPage(request: Request): @app.get("/SSCCounter.json") async def nCnt(): - Standard_Time, SSCCount = yolo_machine.run_machine() + SSCCount, Standard_Time = status["people_count"], status["analysis_time"] print(SSCCount) return {"people_count": SSCCount, "analysis_time": Standard_Time} -@app.post("/uploadfile/") +@app.post("/uploadfile") async def create_upload_file(file: UploadFile = File(...)): contents = await file.read() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f2651c2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +annotated-types==0.6.0 +anyio==3.7.1 +click==8.1.7 +exceptiongroup==1.1.3 +fastapi==0.104.1 +h11==0.14.0 +idna==3.4 +Jinja2==3.1.2 +MarkupSafe==2.1.3 +numpy==1.26.1 +opencv-python==4.8.1.78 +pydantic==2.4.2 +pydantic_core==2.10.1 +python-multipart==0.0.6 +sniffio==1.3.0 +starlette==0.27.0 +typing_extensions==4.8.0 +uvicorn==0.24.0.post1