행복한 하루

[교육후기] OpenCV와 TensorFlow Lite를 활용한 라즈베리 파이 지능형 비전 서비스 개발 - 3일 차 본문

Artificial Intelligence/Basic

[교육후기] OpenCV와 TensorFlow Lite를 활용한 라즈베리 파이 지능형 비전 서비스 개발 - 3일 차

변화의 물결 2023. 3. 7. 11:47

 

 

안녕하세요.

 

 이번에는 교육 마지막 날로 TF Lite 사용을 좀 더 활용하고 웹서비스와 연동하는 내용들을 진행되었습니다. 그리고 마지막 궁금한 사항들에 대해 질문하고 테스트본 소스들을 정리하는 시간으로 마무리했습니다.


1. node.js 사용해 보기

1.1 node.js 간략 설명

  - V8엔진으로 빌드된 이벤트 기반 자바스크립트 런타임 플랫폼(JS를 기계어로 변환)

  - js 엔진을 서버 쪽에도 추가해서 양쪽에서 js를 사용할 수 있도록 한 것이다.

  - npm: Node.js용 패키지 매니저

  - libuv : 비동기라이브러리, Node.js는 싱글 스레드이지만, libuv 라이브러리를 통해 스레드 처리가능, 콜백기반 모델로 동작할 수 있도록 설계

  - 응답성이 좋고, 여러 라이브러리 많음, 개발자 입장에서 프런트와 백엔드를 스크립트로 둘 다 제작 가능

 

1.2 OnOff 라이브러리 사용

  - node.js를 이용한 GPIO와 Interrupt에 접근할 수 있는 라이브러리로 LED제어 테스트

  - 간단한 led 제어 소스 테스트 (gpio 4번 핀에 led 연결) 

'use strcit';

const Gpio = require('onoff').Gpio;
const led = new Gpio(4, 'out');
// 주기를 맞추기 위해서 동기방식으로 설정, 콜백함수 등록
const iv = setInterval( _ => led.writeSync(led.readSync() ^ 1), 200);

setTimeout( _ => {
	clearInterval(iv);
	led.unexport();
}, 5000);

- 실행 : node led_onoff.js

 

1.3 express framework 이해하기

  - node.js를 사용한 REST 서버를 간편하게 구현하게 해주는 프레임워크

  - 프로젝트 디렉터리를 생성한 후 프로젝트를 생성한 후 구조 확인 

 express --ejs prj_led
 cd prj_led
 npm i

  - express 프로젝트 구조

    app.js : 프로그램 구성 설명, 메타, Manifest 같은 개념 파일 (기능 보여줄지 여부 선택)

    package.json : 모듈 안에 설치되어야 할 패키지 리스트

    routes : 서버 노드 주소, 기능 파일 추가 디렉터리

    public : 이미지 등 데이터 디렉터리

    views : 화면 html 단 파일 추가 디렉터리

    bin : www 웹서버 실행 파일 디렉터리

  - express에서 생성한 프로젝트에서 LED 제어를 하기 위해서 디렉터리별 파일들 추가

    view 디렉터리에  led.ejs 추가 (HTML)

    routes 디렉터리에 led.js 추가 (기능수행)

    최상위 디렉터리에 app.js 수정 (routes에 대한 내용 추가)

 

-  led.js 소스 내용 

var express = require('express');
	var router = express.Router()

	/* GET home page. */
	router.get('/', function(req, res, next) {
	  res.render('led', { title: 'LED Control' });
	});

	router.get('/:value', function(req, res, next) {
		var led = req.params.value;
		switch(led) {
			case('on'): ctrlLED(0); break;
			case('off'): ctrlLED(1); break;
			default: break;
		}
	  res.render('led', { title: 'LED Control '+ req.params.value });
	});
	module.exports = router;



	const Gpio = require('onoff').Gpio;
	const led = [new Gpio(4, 'out')];

	function ctrlLED(par) {
		switch(par) {
			case(0): led[0].writeSync(1); break;
			case(1): led[0].writeSync(0); break;
			default: break;
		}
	}

  -  ./bin/www 웹서버 실행하면 라즈베리라이 IP Address로 접속하면 웹서비스가 작동되는 것을 확인할 수 있습니다.

  - 웹서버에 제어를 하게 되면 console 창에 메시지가 나타납니다.

2. TensorFlow Lite 실습

2.1 object-detection 소스 확인

  - 구글에서 제공해 주는 object-detection 예제 관련된 모델과 정답파일 등 자료를 다운로드합니다.

 

  - 사진에 있는 물체를 인식할 수 있고, 소스 중 하나는 Raspberry영상에 나타나는 물체도 실시간으로 인식하는 것을 확인할 수 있습니다.     

python3 classify_picamera.py --model /tmp/mobilenet_v1_1.0_224_quant.tflite  --labels /tmp/labels_mobilenet_quant_v1_224.txt

 

2.2 object-detection와 pipe 구조 연동

  - 파이프 구조를 이용해서 detection 프로세서, 판단 프로세서로 나누어 처리하는 소스 확인

  - 하나의 프로세서에서 객체를 인식하고 파이프로 다른 프로세서에 전달한 후 처리를 기다리는 것을 내용

 

  - 간단히 소스를 보면 파이프 경로 하나를 만들고 그 경로에 인식된 물체의 이름을 write 합니다. 다른 프로세서에서는 동일한 경로를 확인하고 있다가 mouse가 인식되면 종료하는 내용으로 테스트합니다.

  

  < classify_picamera_pipe.py 일부분 > 

path = 'pipe'
  if os.path.exists(path) == False:
      os.mkfifo(path)

  pre_label = ''

  with picamera.PiCamera(resolution=(640, 480), framerate=30) as camera:
    preview = camera.start_preview()
    preview.fullscreen = False
    preview.window=(0,0,640,480)

    try:
      stream = io.BytesIO()
      for _ in camera.capture_continuous(
          stream, format='jpeg', use_video_port=True):
        stream.seek(0)
        image = Image.open(stream).convert('RGB').resize((width, height),
                                                         Image.ANTIALIAS)
        start_time = time.time()
        results = classify_image(interpreter, image)
        elapsed_ms = (time.time() - start_time) * 1000
        label_id, prob = results[0]
        stream.seek(0)
        stream.truncate()
        cur_label = labels[label_id]
        msg = '%s %.2f\n%.1fms\n' % (cur_label, prob, elapsed_ms)
        camera.annotate_text = msg
        if pre_label != cur_label:
            print(msg)
            fifo = open(path, 'w')
            fifo.write(cur_label)
            fifo.close()

        pre_label = cur_label

 

  < quit.py 일부분 > 

def read_pipe():
	path='pipe'
	pipe=os.open(path, os.O_RDONLY)
	fifo=os.read(pipe,100).decode('ascii')
	if fifo != '':
		print(fifo)
		if fifo == 'mouse' :
			os.system('sudo killall -9 python3')
		os.close(pipe)

while True:
	try:
		read_pipe()
	except OSError as err:
		if err.errno == 11:
			continue
	time.sleep(0.5)

2.3. pose_estimation 소스 확인

  - pip3 install pandas   라이브러리를 추가로 설치

  - 제공해 주는 사이트의 기반으로 설명, 해주면 포즈 예측은 얼굴부터 파트 아이디가 부여되어 있습니다.

https://www.tensorflow.org/lite/examples/pose_estimation/overview?hl=ko

 - 실행시키면 Pi Camera에서 보이는 사람의 포즈에 따라 움직이는 것을 확인할 수 있습니다.   

python3 pose_estimation.py --model posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite --output_path pose_images

 

2.4 bird Object Detection 후 결과를 웹서비스

  - express로 웹서버 구조를 만들 후 lite 모델과 js 파일들을 옮겨서 테스트 환경을 만듭니다. 

express --ejs 
prj_web_tflite 
cd prj_web_tflite
npm i

  - 웹페이지에서 새(bird) 이미지를 업로드하면 upload.js 파일에서 bird.source로 저장한 후 분류하는 python 파일을 실행시키고 대기상태로 있다가 그 결과는 text파일로 완료되면 json으로 화면에 출력해 주는 구조로 되어 있습니다. (동기화 방식으로 처리한 코드로 단순하게 테스트하기 위한 코드라 보완이 조금 필요합니다.)

   - 경로가 하드코딩 되어 있어 새로 프로젝트를 만들어주면 수정해주어야 했습니다.

  (upload.js, bird_classification.py)

  - 정답지 목록에 분류된 새는 많이 있지만, 학습량이 부족해 보여 인식률이 조금 낮은 듯합니다. 실행결과는 새 정보와 추정값이 나타납니다.

2.5 MediaPipe 실습

  - 구글에서 인체를 대상으로 하는 인식에 대해 다양한 형태로 기능과 모델까지 제공하는 서비스

  - 실행하기 위한 라이브러리를 설치합니다.   

 pip3 install protobuf==3.20.1
 pip3 install mediapipe-rpi4

 

  - 기본적으로 제공해 주는 모델을 가지고 예제들을 테스트합니다.

  - 손과 손가락 인식

  - 가위바위보 인식하기

   - 신발 인식해서 사각박스 그리기

3. 인공지능 설명

  - 마무리 겸 인공지능 개념에 대해서 간단하게 설명해 줍니다.

  - 딥러닝과 병렬처리되기 시작하면서 빠르게 발전하기 시작한다.

  - 기본 기계학습에서 은닉계층 수를 늘림으로써 딥러닝으로 발전

  - 기계학습 모델(Random forest, Bayesian models, CNN, RNN)

  - 지연 최적화, 코드 최적화, 연산 최적화, 에너지 최적화

4. 최종 후기

  - 실습 위주로 빠르게 OpenCV와 TensorFlow, mqtt 훑어본 느낌이 들었습니다. 그리고 개별적으로 선행학습이 있었다면, 질문해서 궁금증을 조금이나마 해소할 수 있는 과정이라고 생각됩니다.

 

  - 이론 강좌가 아니다 보니, OpenCV, 인공지능, 기계학습 등 깊은 내용은 들을 수가 없습니다. 시간적 한계와 수학적 이론 등 선행되어야 하는 것들이 많기 때문이라고 생각됩니다. 그래서 조금 AI에 대해서 학습해 보고 교육을 받는 다면, 교육과정에 추가적인 실습도 가능해 보였습니다. 그리고 AI 모델 학습하는 부분은 특히 시간이 오래 걸리는 부분이 있다 보니 제외되어 있습니다. 그래서 추가적인 다른 교육을 받을 필요가 있었습니다. 사실, 간단하게 라도 하는 방법을 알려주면 좋지 않을까 생각을 했습니다.

 

  - 기본적으로는 RaspberryPi에 맞게 Lite 버전을 설치해서 테스트했지만, IO제어가 아니라면, 리눅스가 설치된 장치에 기본적인 소스들은 문제없이 테스트해 볼 수 있을 거라고 생각되었습니다.

 

  - 실습해 보면서는 구글에서 제공해 주는 라이브러리 등으로 쉽게 테스트해 보았지만, 완벽하다고 말할 수 없지만, 이 정도까지 해볼 수 있다는 것이 대단했고, 이렇게 종속적으로 개발하다 보면 나중에는 구글이나 대기업에서 만든 모델과 자료들 이외의 개발이 가능할까 의문이 들었습니다.  Nvidia, MS 들도 마찬가지고 대기업의 기술과 데이터에 빠져나오지 못할까 봐 염려가 되었습니다.

  

감사합니다.

 

 

<참고 자료>

1. "OpenCV와 TensorFlow Lite를 활용한 라즈베리파이 지능형 비전 서비스 개발"  교육 자료 - 한국지능형사물인터넷협회

 

 

Comments