python 과 node express 사이 이미지 주고 받기 구현

Client 는 Python 으로 작성 되었으며 Server 는 node express 로 된 시스템입니다. 양쪽 모두 웹소켓을 사용했습니다. 이미지를 서로 주고 받는데 한참을 헤메었네요. 일단 이미지를 base64 로 변환해서 json 으로 패키징 하여 서버에 전송하고 서버에서 받은 base64 데이터를 이미지로 변환하여 저장하는 로직입니다. python 에서 이미지를 data에 가져오는 방법입니다. data = io. BytesIO () picam2.capture_file(data, format = ' jpeg ' ) print (data. getbuffer ().nbytes) 가져온 이미지를 base64 로 변환한 후 다시 전송을 위한 데이터로 변환합니다. img_base64 = base64. b64encode (data. getbuffer ()). decode ( ' utf-8 ' ) 전송할 데이터로 패키징 합니다. responseData = { " type " : " camera " , " device_id " : device_id, " data " : img_base64 } 이제 웹소켓을 이용해서 전송합니다. responseStr = json. dumps (responseData) ws .send(responseStr) 이제 node express 에서 전송된 데이터를 받아서 이미지 처리하는 로직입니다. 받은 데이터로 이미지로 변환합니다. const image = Buffer. from (data, ' base64 ' ) 변환된 이미지를 저장합니다. writeFileSync ( ' image.jpg ' , image ) 정리해놓고 보니 간단하지만 로직을 이렇게도 해보고 저렇게도 해보고 한참을 헤메었습니다. 나중에 다시 참고할 때 편하도록....

라즈베리 파이에서 인터넷 연결 후 자동실행 설정하기

라즈베리 파이에서 인터넷 연결 후 자동실행하는 방법입니다. 파이썬으로 프로그램을 만들었습니다. 웹소켓으로 서버와 연결하여 메시지를 받아서 처리하는 모듈입니다. /home/pi/PythonProjects/websocketClient.py 이 파일을 라즈베리 파이가 구동된 후 인터넷이 연결된 후에 실행하고 싶어서 시도한 결과를 정리한 내용입니다. 결론부터 말하자면 다음과 같은 방법이 최고입니다. 1. 모듈을 실행할 스크립트를 작성합니다. & vi /home/pi/run_websocket.sh #!/bin/bash python /home/pi/PythonProjects/websocketClient.py 2. 생성한 모듈의 실행권한을 준다 $ chmod +x /home/pi/run_websocket.sh 3. 자동 구동할 desktop 파일을 생성한다. $ sudo vi /etc/xdg/autostart/websocket.desktop [Desktop Entry] Name=WebsocketClient Exec=/home/pi/run_websocket.sh 4. 재부팅한다 $ sudo reboot 저는 이와 같이 하니 자동실행되었습니다.

Flutter 에서 yolov8 사용하기 - 마무리

이번에 진행하면서 느낀 점은 "샘플 소스가 너무 없다" 주로 찾은 소스는 2년 전 지원이 끊긴 라이브러리 소스였으며 ssd_mobilenet 소스는 제공이 잘 되었는데 카메라 해상도를 높이면 작동이 되지 않았다. 나중에 공부가 깊어지다 보니 input 텐서의 값을 수정했어야 했는데 샘플소스에 input & output 텐서 속성이 박혀 있어서 그런 오류가 났었다. 혹시나 이 글이 뒤에 오는 사람에게 도움이 될까 하여 기록으로 남긴다. 전체 소스는 다음에서 볼 수 있다. https://github.com/whenyourapprun/AreYouElf.git

Flutter 에서 yolov8 사용하기 - 3

이제 카메라를 구동하고 거기서 모델을 생성하여 결과를 추출하는 모듈을 만들 것이다. 카메라 구동은 기존에 하는 방법과 비슷하다. 모델을 생성하여 탐지하는 모듈은 스레드를 4개를 설정하여 비동기 독립으로 실행하도록 한다. isolate 를 사용한다. 이렇게 하면 속도가 빠르다. 대부분 정형화 된 상태로 샘플 코드가 되어 있으니 이걸 사용하면 된다. 이제 다음과 같이 사용한다.

Flutter 에서 yolov8 사용하기 - 2

이제 생성된 모델을 가져왔으니 모델에서 값을  추출하는 nms 함수를 살펴보아야 한다. 3차원 배열로 들어온 값에서 각각 맞는 값을 추출해야 한다. 이 부분은 텐서에서 추출한 값으로 설정되도록 함수를 조정하였다. 소스는 다음과 같으니 참고하기 바란다. 이 함수에서 주목할 점은 텐서로 전달 받은 값에서 각 항목을 지정하여 추출하는 방법이다.

Flutter 에서 yolov8 사용하기 - 1

Flutter 에서 yolov8 을 사용하려면 이 방법이 가장 주효하다. 물론 더 나은 라이브러리가 제공된다면 좋을 것이다. tflite_flutter 라이브러리가 현재 공식 지원이다. 예제 등을 찾아보면 없을 것이다. 어찌하여 이미지를 추론하는 것은 찾을 수 있다. 문제는 동영상을 추론하는 게 필요하다. 그에 대한 예제는 ssd_mobilenet 모델을 제공하고 있다. ultralytics 에서 제공하는 export 방법을 사용하여 모바일용 모델을 생성한다. format='tflite' 옵션을 사용하면 3가지 속성이 default 로 설정된다. half=False, int8=False, imgsz=640 이다. 각각의 설정을 변경하면서 테스트 하여 속도를 체감해보길 권장한다. 나의 경우는 half 와 int8 은 양자화인데 속도에 크게 좌우되지 않고 정밀도를 낮추는거 같았다. imgsz 를 조정하였는데 224, 320, 4800, 640 순으로 진행하였는데 224 가 속도가 가장 빨랐다. export 하는 중에 input 텐서의 속성을 알려주는데 이게 중요하다. [1, 224, 224, 3] 으로 나올 것이다. output 텐서는 [1, 6, 1029] 이런 식으로 나올 것이다. 이 텐서의 3 ~ 4차원 행렬을 무시해서 삽질을 오래 하였다. 그리고 이런 부분에 대한 설명이 자세하지 않아서 인공지능 및 딥러닝을 전공하지 않은 개발자들에게 허들로 작용할 수 있다. 모델은 여기서 가져와서 이렇게 사용한다.

부품 인식에 관하여 그동안 일 정리

스마트폰을 활용하여 부품인식을진행하고 있다. 현재 우리 회사의 문제점은 경험 많은 퇴직자와 신입 사원 사이에 중간 사원이 없다. 그리하여 많은 문제점들이 발생하고 있다. 그에 대한 대안으로 부품 인식을 진행하고 있다. yolov8 을 활용하여 부품에 대한 이미지와 라벨링을 한다. 그 결과 .pt 파일이라는 파이토치 모델 파일을 얻는다. yolov8n.pt 를 기준으로 새로 취득한 이미지와 라벨링을 통해 학습을 진행해보았다. 처음엔 13개의 부품으로 진행했다. 이미지는 부품당 20장 정도 찍었다. 학습를 300회 정도 진행하니 그 이상은 무의미 하다 하여 그 모델 파일을 가지고 테스트 모듈을 만들었다. 테스트 모듈은 opencv 를 활용하니 잘 되었다. 하지만 한글로 부품 명칭을 보여주자는 의견에 opencv 한글 표시 하는 걸 시도하였다. 이게 조금 어려웠다. 어찌하여 그렇게 개발하여 발표를 하게 되었다. 이제 모바일에 적용 하는 게 관건이었다. 노트북에서는 GPU 환경이라 그런지 속도가 정말 빨랐다. 주로 많이 걸리는 시간이 inference 라 불리는 추론 시간인데  GPU 환경에서 20ms 정도 걸렸다. 모바일 환경으로 가니 3500ms 정도 걸려서 사용할 수 없을 정도 였다. 속도는 둘째이고 정확도도 엉망이었다. 예제 소스도 없었다. 진짜 어렵게 진행해서 이런 문제들을 해결하였다. 이제 그걸 하나 씩 정리하고자 한다.