상세 컨텐츠

본문 제목

[캡스톤 일지] ~10.16 robotjs 이용한 마우스 커서 이동

학부/캡스톤(a.k.a 졸작)

by ranlan 2021. 10. 16. 03:18

본문

728x90

어쩌다보니 12시가 넘어서 16일까지의 캡스톤 일지가 되어버림

 

기능 테스트 모아둔 페이지

회사에서 퍼블리셔분들이 퍼블 나올때마다 표로 정리해주신게 생각나서 해본 테스트 페이지 꾸미기 및 폴더 정리..

블로그 포스팅 제쳐두고 한시간 남짓 했는디 시험기간에는 공부빼고 다 재밌는듯

어제까지 고민하던 것들이 오늘 잘 풀려서 기분이 조타

통시 공부는 내일부터 할꺼다.. 증말루..

 


 

해결방법3. 파이썬 마우스 조작 기능 개발

저번 포스팅에 썼던 해결방법 3은 스크립트로 불가한 마우스 조작 기능을 파이썬으로 구현하여 노드에 연결하는 것이다.

새로 가상환경 만들어서 미디어파이프를 다시 설치해볼까 하였지만.. 역시나 잘 안돼서 깔끔히 포기했다.

 

노드에서 미디어파이프 적용하여 검지 손가락의 포인트 알아냄

-> 파이썬 함수로 좌표값을 전달 (혹은 파이썬 파일에 바로 전달하여 .py 실행)

-> 전달받은 좌표값으로 마우스 커서 이동

* 실시간으로 계속 이어져야함!

 

파이썬 라이브러리  pyautogui 

[위키독스] https://wikidocs.net/85581

 

2.1 마우스 자동화 - pyautogui 사용법 (1)

지금부터 유산소운동 1단계입니다! ----- 여러분은 지금 컴퓨터 앞에 앉아계시죠? 컴퓨터를 사용할 때 가장 많이 쓰는 2가지가 뭘까요? 그렇죠, 바로 마우스와 키보 ...

wikidocs.net

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

 

[Node.js] 자바스크립트로 파이썬 연동 실행 방법(함수 매개변수 전달 호출 : child-process)

# Node.js환경에서 javascript로 python 스크립트를 실행하는 방법 => node의 기본 내장 모듈인 "child-process" 를 사용하면 된다. (python-shell 등의 외부 라이브러리를 사용할 수도 있긴 하다.) 이번 글에서..

curryyou.tistory.com

const result = cp.spawn('python', ['test.py'], x, y);
  result.stdout.on('data', (result)=>{
    console.log(result.toString());
});

x, y 좌표가 생길때마다 바로 파이썬 파일을 실행시켜보기도 하고, 파이썬 실행을 연결한 api를 만들어 이를 호출하는 식으로도 했는데 안된다..

(.py의 로그는 남는데 마우스 조작이 안됐던걸로 기억)

 

 

노드 마우스 커서 조작하기 robotjs

http://robotjs.io/

 

RobotJS - Node.js Desktop Automation

Automate Anything Control the mouse, keyboard, and read the screen. Easy to use Prebuilt binaries allow you to install without compiling! Open Source Licened under MIT and hosted on GitHub. Cross Platform Mac, Windows, and Linux supported!

robotjs.io

파이썬 라이브러리 쓰다 생각난.. 노드.. 노드에도 비슷한 라이브러리가 있지 않을까하고 찾아보다 발견한 모듈   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

 

javascript require doesn't work inside html

I'm writing html code that involves js code. Below a simple example:

Use JavaScript to Change Text

This example

stackoverflow.com

노드 실행이 아니라 브라우저에 스크립트로 불러왔을 때는 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 

 

jsDelivr - A free, fast, and reliable CDN for Open Source

Supports npm, GitHub, WordPress, Deno, and more. Largest network and best performance among all CDNs. Serving more than 80 billion requests per month. Built for production use.

www.jsdelivr.com

<script src="https://cdn.jsdelivr.net/npm/robotjs@0.6.0/index.min.js"></script>

 

그러다 생각난 방법이 바로 소켓 통신!!

 

 

노드 socket.io 실시간 통신을 이용한 마우스 조작

npm install socket.io

[참고] https://fred16157.github.io/node.js/nodejs-socketio-communication-basic/

 

Node.js 서버에서 Socket.IO로 실시간 통신하기 - 기초

Node.js로 사용자와 HTTP로 통신하는 것은 Express나 내장된 http 모듈로 해본 적이 있을 것이다. 하지만 채팅같은 실시간으로 데이터를 주고받아야 하는 서비스는 어떻게 구현해야 할 것인지 막막할

fred16157.github.io

위의 블로그를 따라하며 감을 좀 잡고 필요한 부분만 골라서 썼다.

 

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

 

GitHub - ijo0r98/capstone: 2021학년도 2학기 캡스톤디자인 3조

2021학년도 2학기 캡스톤디자인 3조. Contribute to ijo0r98/capstone development by creating an account on GitHub.

github.com

 

 

728x90

관련글 더보기

댓글 영역