어쩌다보니 12시가 넘어서 16일까지의 캡스톤 일지가 되어버림
회사에서 퍼블리셔분들이 퍼블 나올때마다 표로 정리해주신게 생각나서 해본 테스트 페이지 꾸미기 및 폴더 정리..
블로그 포스팅 제쳐두고 한시간 남짓 했는디 시험기간에는 공부빼고 다 재밌는듯
어제까지 고민하던 것들이 오늘 잘 풀려서 기분이 조타
통시 공부는 내일부터 할꺼다.. 증말루..
저번 포스팅에 썼던 해결방법 3은 스크립트로 불가한 마우스 조작 기능을 파이썬으로 구현하여 노드에 연결하는 것이다.
새로 가상환경 만들어서 미디어파이프를 다시 설치해볼까 하였지만.. 역시나 잘 안돼서 깔끔히 포기했다.
노드에서 미디어파이프 적용하여 검지 손가락의 포인트 알아냄
-> 파이썬 함수로 좌표값을 전달 (혹은 파이썬 파일에 바로 전달하여 .py 실행)
-> 전달받은 좌표값으로 마우스 커서 이동
* 실시간으로 계속 이어져야함!
파이썬 라이브러리 pyautogui
[위키독스] https://wikidocs.net/85581
import pyautogui
import sys
x = sys.argv[1]
y = sys.argv[2]
def move_mouse(x, y):
pyautogui.moveTo(x, y)
print(x, y)
if __name__ == '__main__':
// 파이썬 파일 실행 시 바로 실행됨
x = sys.argv[1]
y = sys.argv[2]
print(x, y)
pyautogui.moveTo(x, y)
노드에서 파이썬 실행을 위한 노드 기본 내장 모듈 child_process
[참고] https://curryyou.tistory.com/225
const result = cp.spawn('python', ['test.py'], x, y);
result.stdout.on('data', (result)=>{
console.log(result.toString());
});
x, y 좌표가 생길때마다 바로 파이썬 파일을 실행시켜보기도 하고, 파이썬 실행을 연결한 api를 만들어 이를 호출하는 식으로도 했는데 안된다..
(.py의 로그는 남는데 마우스 조작이 안됐던걸로 기억)
파이썬 라이브러리 쓰다 생각난.. 노드.. 노드에도 비슷한 라이브러리가 있지 않을까하고 찾아보다 발견한 모듈 robotjs
npm install robotjs
공식 문서에 나와있는 코드 예제
var robot = require("robotjs");
// Speed up the mouse.
robot.setMouseDelay(2);
var twoPI = Math.PI * 2.0;
var screenSize = robot.getScreenSize();
var height = (screenSize.height / 2) - 10;
var width = screenSize.width;
for (var x = 0; x < width; x++) {
y = height * Math.sin((twoPI * x) / width) + height;
robot.moveMouse(x, y);
}
실행하면 마우스 커서를 움직이지 않아도 혼자 빙글빙글 돈다!
이제 미디어파이프를 통해 얻은 검지손가락의 x와 y의 좌표를 robotjs의 moveMouse 메서드로 넘겨주면 되는데..
var robot = require("robotjs");
function move(x, y) {
var screenSize = robot.getScreenSize();
var height = (screenSize.height / 2) - 10;
var width = screenSize.width;
x = x * width;
y = y * height;
robot.moveMouse(x, y);
}
문제 1) 이상하게 html파일에서 스크립트가 안불러와진다..
문제 2) 기억이 잘 안나지만 위의 문제를 어찌어찌 해결했는데 이번엔 스크립트 파일의 require가 안먹는다.
ReferenceError: require is not defined.
[참고] https://stackoverflow.com/questions/50011068/javascript-require-doesnt-work-inside-html
노드 실행이 아니라 브라우저에 스크립트로 불러왔을 때는 require()를 못쓰는것 같다.
문제 3) 파이썬 연동할때처럼 api 호출방식으로 바꿔봤다.
app.post('/robo', (req, res) => {
var screenSize = robot.getScreenSize();
var height = (screenSize.height / 2) - 10;
var width = screenSize.width;
var x = req.body['locx'] * width;
var y = req.body['locy'] * height;
console.log(x, y);
robot.moveMouse(x, y);
});
되긴하는데.. 처음에 잠깐 버벅이고 그게 끝이다.. 사실 하면서도 실시간으로 마우스 위치가 변해야하는걸 api 요청으로 처리하는게 맞나 싶긴 했다.
문제 4) 미디어파이프처럼 cdn으로 robotjs를 읽어오려고 하였지만 이 방법도 실패..
https://www.jsdelivr.com/package/npm/robotjs?tab=collection
<script src="https://cdn.jsdelivr.net/npm/robotjs@0.6.0/index.min.js"></script>
그러다 생각난 방법이 바로 소켓 통신!!
npm install socket.io
[참고] https://fred16157.github.io/node.js/nodejs-socketio-communication-basic/
위의 블로그를 따라하며 감을 좀 잡고 필요한 부분만 골라서 썼다.
0) app.js 수정 및 추가
모듈 require 추가
var robot = require("robotjs");
var io = require('socket.io')(server);
앱과 소켓 서버 생성
const port = 3000;
const app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
서버 구동
// 이전 app 실행 코드
app.listen(port, () => {
console.log(`Server is Running! http://localhost:${port}`)
});
// 바뀐 코드
server.listen(3000, function() {
console.log(`Server is Running! http://localhost:${port}`);
});
1) 클라이언트에서 서버로 미디어파이프 결과값 전달
socket.io 스크립트 태그 추가
<script src="/socket.io/socket.io.js"></script>
서버 데이터 전송 스크립트
var socket = io();
...
function onResults(results) {
// 이전과 동일
drawConnectors(canvasCtx, landmarks, HAND_CONNECTIONS, {color: '#4badb3', lineWidth: 5});
drawLandmarks(canvasCtx, landmarks, {color: '#e04e04', lineWidth: 2});
var x = landmarks[8]['x']; // 검지손가락의 좌표(전체 대비 비율값으로 나옴)
var y = landmarks[8]['y'];
var location = [x, y];
socket.emit('location', location); // 소켓 이용하여 위치 정보 전달
...
}
2) 서버(node)에서 robotjs를 이용해 마우스 조작
io.on('connection', (socket) => { // 소켓 연결이 들어오면 실행
// 클라이언트에서 수신받은 정보
socket.on('location', (msg) => {
// console.log('Message received: ' + msg);
var screenSize = robot.getScreenSize();
var height = (screenSize.height / 2) - 10;
var width = screenSize.width;
// 마우스 커서 이동시킬 좌표
var x = (width - msg[0] * width);
var y = msg[1] * height;
robot.moveMouse(x, y);
});
});
* 마우스 커서의 이동할 위치를 설정할 때 전체 가로 길이에서 전달받은 가로 길이를 빼는 이유는 카메라를 좌우반전한 상태로 쓰고있기 때문
결과는 두둥
허허 성공했다 드디어 🥳
다행히 회의 전까지 끝내서 팀원들에게 행복하고 뿌듯한 마음으로 공유할 수 있었다,,
현지도 지난 회의때 더 해보기로했던 캔버스 위 메뉴판 레이아웃과 나아가 선택하는 모션 인식까지 성공했다!
커서 이동도 안되고 동적 제스처 모델학습이 안되서 눈앞이 깜깜하고 요 며칠 너무 스트레스였는데.. 어찌저찌 잘 풀려서 증말 다행ㅠㅠ
시험 끝나고 어서 주문 시스템 기능 개발을 마무리져야겠다
오늘은 블로그 쓰고 깃 정리하고 엄마랑 아란이랑 장보고 하루 끝!
아 깃 주소도 올려야쥥
[GIT] https://github.com/ijo0r98/capstone
[캡스톤 일지] ~10.26 미디어파이프 오류 해결과 노드 socket.io 예제 (0) | 2021.10.27 |
---|---|
[캡스톤 일지] ~10.21 NodeJS TDD 웹개발 훑어보기(2) (0) | 2021.10.23 |
[캡스톤 일지] ~10.13 미디어파이프 이용한 정적제스처 인식과 문제 발생 (0) | 2021.10.14 |
[캡스톤 일지] ~10.05 NodeJS TDD 웹개발 훑어보기(1) (0) | 2021.10.10 |
[캡스톤 일지] ~10.04 생활코딩로 간단히 살펴본 Tensorflow.js (0) | 2021.10.05 |
댓글 영역