-
오토핫키와 OpenCV] #3. 템플릿매칭오토핫키/OpenCV 2024. 12. 6. 05:16
시작
오우쉣 존나 오랜만이다.
OpenCV 는 거의 2년 만에 다시 하는 것 같은데 예전에 템플릿매칭 관련해서 시도하다가 안되서 걍 포기했었는데
AI 수준이 올라가고 Claude 가 코딩에서는 거의 신적인 능력을 보여주다보니 오류나던 부분을 해결했다.
역시 Claude 가 최고야
어쨋든 이번에는 <그림 1> 과 같은 편지 이미지를
<그림 2> 에 일치하는 이미지들의 결과를 가져오는 내용을 다뤄보려고 한다.
본문
hOpencv := DllCall("LoadLibrary", "str", "opencv_world460.dll", "ptr") hOpencvCom := DllCall("LoadLibrary", "str", "autoit_opencv_com460.dll", "ptr") DllCall("autoit_opencv_com460.dll\DllInstall", "int", 1, "wstr", A_IsAdmin = 0 ? "user" : "", "cdecl") cv := ComObjCreate("OpenCV.cv")
역시 가장 먼저 시작부분에는 이걸 해줘야 하고 (버전이 바뀌었다면 숫자를 바꿔주면 그만)
src := cv.imread("image\ls.png", 0) templ := cv.imread("image\l.png", 0) dst := cv.imread("image\ls.png")
가장 먼저 기본이 될 베이스 이미지를 src 로 선언
뒤에 0 은 GrayScale 을 먹인다는 뜻
templ 에는 작은 편지 한개의 이미지를 선언
dst 에는 나중에 최종적으로 결과를 보여줄 이미지를 선언
threshold := 0.9 result := cv.matchTemplate(src, templ, 5)
오차 범위는 0.9 로 설정 (90% 일치율)
가장 중요한 matchTemplate
대충 보면 알겠지만 cv.matchTemplate(큰 이미지, 작은 이미지, 정수) 이렇게 들어가는데 정수에는
0 = TM_SQDIFF 1 = TM_SQDIFF_NORMED 2 = TM_CCORR 3 = TM_CCORR_NORMED 4 = TM_CCOEFF 5 = TM_CCOEFF_NORMED
이 숫자들이 들어간다. 보통 5를 추천함. 이건 알아서 테스트하거나 찾아보거나 할 것
w := templ.width h := templ.height
나중에 사각형을 씌워줘야 하니까 w 와 h 를 정해주고
cv.minMaxLoc(result) t := cv.extended maxVal := t[1] maxLoc := t[3]
결과값을 가져오도록 한다.
t 에 담아주는 값은
t[0] = minVal (최소 매칭 값)
t[1] = maxVal (최대 매칭 값)
t[2] = minLoc (최소값 위치 [x,y])
t[3] = maxLoc (최대값 위치 [x,y])
이 들어간다.
if (maxVal >= threshold) { x := maxLoc[0] y := maxLoc[1] dst := cv.rectangle(dst,ComArrayMake([x, y]),ComArrayMake([x + w, y + h]),ComArrayMake([0, 0, 255]),1) ; 첫 매칭 위치를 마스킹하고 다음 매칭 찾기 Loop { cv.rectangle(result,ComArrayMake([x-w//2, y-h//2]),ComArrayMake([x+w//2, y+h//2]),ComArrayMake([0]),-1) ; -1은 채우기 cv.minMaxLoc(result) t := cv.extended maxVal := t[1] maxLoc := t[3] if (maxVal < threshold) break x := maxLoc[0] y := maxLoc[1] dst := cv.rectangle(dst,ComArrayMake([x, y]),ComArrayMake([x + w, y + h]),ComArrayMake([0, 0, 255]),1) } }
그 다음 첫번째 일치값 외에 이후 일치율을 비교해서 다음 매칭을 찾는 조건반복문
cv.imshow("dst", dst) cv.waitKey(0) cv.destroyAllWindows()
확인해보자
<그림 3> 과 같이 일치하는 이미지에 빨간색 사각형이 그려진 것을 볼 수 있다.
DllCall("autoit_opencv_com460.dll\DllUnregisterServer", "cdecl") DllCall("FreeLibrary", "ptr", hOpencv) DllCall("FreeLibrary", "ptr", hOpencvCom)
마지막으로 메모리 풀어주면 끝
ComArrayMake(inputArray) { arr := ComObjArray(VT_VARIANT:=12, inputArray.Length()) Loop,% inputArray.Length() { arr[A_Index-1] := inputArray[A_Index] } return arr }
아 그리고 이거 함수도 가져가야함
결과
빨간색은 맘에 안들어서 파란색으로 바꿨다.
조건 반복문을 보면 x, y 값을 차례대로 가져와서 rectangle 을 그리는 모습을 볼 수 있다.
이걸 Array 에 담거나 혹은 뭐 그 상태에서 바로 어떤 행위를 하라고 하면 변수로 활용도 가능하다.
'오토핫키 > OpenCV' 카테고리의 다른 글
오토핫키와 OpenCV] #2. 이미지 출력 (0) 2023.03.23 오토핫키와 OpenCV ] #1. 설치 (1) 2023.03.23