ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 오토핫키와 OpenCV] #3. 템플릿매칭
    오토핫키/OpenCV 2024. 12. 6. 05:16

    시작

    오우쉣 존나 오랜만이다.

    OpenCV 는 거의 2년 만에 다시 하는 것 같은데 예전에 템플릿매칭 관련해서 시도하다가 안되서 걍 포기했었는데

    AI 수준이 올라가고 Claude 가 코딩에서는 거의 신적인 능력을 보여주다보니 오류나던 부분을 해결했다.

    역시 Claude 가 최고야

    <그림 1>

    어쨋든 이번에는 <그림 1> 과 같은 편지 이미지를

     

    <그림 2>

    <그림 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>

    <그림 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

    댓글