본문 바로가기

개인공부/python

나 혼자 하는 프로젝트 3탄 - 업무자동화(RPA) 데스크탑 2장 - 스크린과 이미지 처리

pyautogui.screensho()을 활용하면 바로 해당 화면을 캡쳐할 수 있다.

스크린 정보가 중요한 이유는, 해당 작업을 반복 실행하게 했을때, 오작동을 최대한 막기 위해서 이다.

예를 들어, VS CODE 프로그램의 좌측 상단 아이콘을 클릭하는 프로그램을 작성한다고 보면,

마우스가 해당 위치로 이동 하였을때, 해당 좌표의 RGB값을 비교하여 정확한 위치인지 다시 한번 판단하게 만들 수 있다.

pyautogui.pixel()에 해당 좌표를 전달하면 그 좌표의 RGB값을 가져 올 수 있다. 

pyautogui.pixelMatchesColor에 해당 좌표와 RGB값(튜플형)을 입력하면 서로 값을 비교하여 True, False 를 반환한다.

 

이제 다른 방법으로 이미지와 스크린을 비교하는걸 확인해보자.

이번엔 마우스 좌표가 아닌 pyautogui.locateOnScreen()을 통해 해당 이미지 파일과 현재 스크린의 동일한 이미지를 찾아 해당 좌표와 크기를 확인해 보자.

(가끔 None 으로 출력되는 경우가 있는데, 해당 아이콘을 캡쳐 후 그림판에서 자르기를 통해 빈 여백없이 맞춰주면 된다.)

이제 click()에 해당 변수를 전달하면, 마우스가 해당 좌표로 이동 후 바로 클릭되는 걸 볼수있다.

 

만약 화면내에 동일한 이미지들이 여러개 존재하는 경우에는 어떤 순서로 작동하게 될까?

체크박스가 3개가 있고, 모두 누르고 싶다...

먼저 체크박스 이미지를 저장하여, 코드를 작성하자.

동일한 모든 이미지를 찾을때에는 locateAllOnScreen()을 사용한다. 이때 반복작업을 하기 위해서는 for문을 이용해서 작업하면 된다.

만약 locateOnscreen()으로 찾을 경우, 위치상 가장 위쪽 또는 가장 왼쪽의 이미지의 위치 또는 가장 처음에 발견되는 이미지만 찾은 뒤 종료하게 된다.

 

이렇게 locateOnscreen() 또는 locateAllOnScreen()을 사용할 경우, 찾는 속도가 상당히 늦어진다.

이를 개선하기 위한 방법이 있다.

1. GrayScale

해당 이미지를 흑백으로 처리하여 작업하게 되며, 공식 문서에 따르면 약 30% 정도 작업이 빨라진다고 한다.

체감상 50%인 경우도 있고, 비슷하다고 느껴지는 경우도 있다.

이 경우 주의할점은 정확도가 떨어질 가능성이 있다.

2. 범위 지정

말 그대로 찾을 범위를 지정해주어, 해당 작업을 좀더 빨리 마무리하게 하는 방법이다.

region=()에 전달되는 값은 찾기 시작할 x,y 의 좌표와 그 기준점으로 부터 옆 너비와 높이 순서로 작성한다.

3. 정확도 조정

정확도 조정을 위해서는 새로운 라이브러리를 설치해야 한다.

confidence= 값 1은 100% 이다. 위와 같이 0.1 (10%) 로 조정하면, 마우스는 엉뚱한 곳으로 이동하게 된다.

(실제 0.1로 작동시키면 좌측 상단의 VS CODE 아이콘으로 마우스가 이동한다. 즉 좌측 상단부터 이미지를 찾기 때문에 10% 정확도로는 해당 "실행"버튼을 제대로 인식하지 못하게 된다.)

 

다른 예로, 대상 이미지를 바로 찾을 수 없는 경우도 발생한다.

이는 이미지가 없는게 아닌, 아직 프로그램이 실행되지 않았거나, 해당 프로그램이 로딩 중이기 때문에 찾을 수 없는 경우다. 

코드는 실행을 누르는 순간 바로 실행되지만, 우리가 흔히 엑셀 파일을 열거나 인터넷 브라우저를 열게되면 짧게는 0.1초, 길게는 수초에 걸려 페이지를 로드하게 된다. 이 때, 사용 가능한게 while문을 이용 하는 것이다.

하지만 while문의 경우 해당 이미지를 스크린에서 찾을때까지 무한 반복하기에, 이는 올바른 대기 방법은 아니다.

이때 필요한게 time 라이브러리와 sys 라이브러리 이다.

start = time.time() 즉 코드를 실행하는 순간의 시간이 저장된다.

그리고 while 문 안의 end = time.time()은 while문이 한바퀴 돌때마다 시간이 증가하게 된다.

이를 이요해 end와 start의 차이가 처음 설정한 timeout(10)보다 커질경우,해당 함수는 강제로 종료되게 된다.

만약 해당 이미지를 찾을 경우 해당 while문은 종료되고 다음 코드인 click으로 이동하게 된다.

이를 함수로 미리 만들어두면, 필요할때 좀더 편하게 코드를 작성 할 수 있다.

함수가 제법 길어 보이지만, 그 내용을 살펴보면 그렇지 않다.

불러와서 사용할 함수는 my_click()이다. 이때 전달값으로 파일이름과 시간 두가지를 전달받아 작동한다.

이때 target이란 변수는 find_target()이란 함수에서 return받은 값인데, True 와 False 두가지만 가진다.

만약 find_target()함수에서 해당 이미지를 찾을 경우 my_click()함수내 if True로 이동하여 pyautogui.click()이 실행되고 그렇지 않으면 콘솔창에 안내 메세지를 띄운 후 sys.exit()에 의해 프로그램이 종료된다.

지금은 해당 이미지("file_menu_note.png")를 스크린에서 찾을 수 없기에, 콘솔창에 다음과 같은 종료 메세지가 출력 되었다.