๐Ÿ˜Ž ๊ณต๋ถ€ํ•˜๋Š” ์ง•์ง•์•ŒํŒŒ์นด๋Š” ์ฒ˜์Œ์ด์ง€?

[v0.27]์˜์ƒ์ฒ˜๋ฆฌ_์ด๋ฏธ์ง€ ๋งค์นญ (Image Matching) ๋ณธ๋ฌธ

๐Ÿ‘ฉ‍๐Ÿ’ป IoT (Embedded)/Image Processing

[v0.27]์˜์ƒ์ฒ˜๋ฆฌ_์ด๋ฏธ์ง€ ๋งค์นญ (Image Matching)

์ง•์ง•์•ŒํŒŒ์นด 2022. 1. 13. 00:32
728x90
๋ฐ˜์‘ํ˜•

220113 ์ž‘์„ฑ

<๋ณธ ๋ธ”๋กœ๊ทธ๋Š” ๊ท€ํ‰์ด ์„œ์žฌ๋‹˜์˜ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ๊ณต๋ถ€ํ•˜๋ฉฐ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค>

https://bkshin.tistory.com/entry/OpenCV-25-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A7%A4%EC%B9%AD-%ED%8F%89%EA%B7%A0-%ED%95%B4%EC%8B%9C-%EB%A7%A4%EC%B9%AD-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A7%A4%EC%B9%AD?category=1148027 

 

OpenCV - 25. ์ด๋ฏธ์ง€ ๋งค์นญ (ํ‰๊ท  ํ•ด์‹œ ๋งค์นญ, ํ…œํ”Œ๋ฆฟ ๋งค์นญ)

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ด๋ฏธ์ง€ ๋งค์นญ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ… ์—ญ์‹œ 'ํŒŒ์ด์ฌ์œผ๋กœ ๋งŒ๋“œ๋Š” OpenCV ํ”„๋กœ์ ํŠธ(์ด์„ธ์šฐ ์ €)'๋ฅผ ์ •๋ฆฌํ•œ ๊ฒƒ์ž„์„ ๋ฐํž™๋‹ˆ๋‹ค. ์ฝ”๋“œ: github.com/BaekKyunShin/OpenCV_Project_Python/tr

bkshin.tistory.com

 

 

 

 

1. ์ด๋ฏธ์ง€ ๋งค์นญ(Image Matching)

: ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์ด๋ฏธ์ง€๋ฅผ ๋น„๊ตํ•ด์„œ ์ง์ด ๋งž๋Š” ๊ฐ™์€ ํ˜•ํƒœ์˜ ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ์•„๋‚ด๋Š” ๊ธฐ์ˆ 

: ์ด๋ฏธ์ง€์—์„œ ๊ฐ์ฒด๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์€ ์ด๋ฏธ์ง€์—์„œ ์˜๋ฏธ ์žˆ๋Š” ํŠน์ง•๋“ค์„ ์ ์ ˆํ•œ ์ˆซ์ž๋กœ ๋ณ€ํ™˜ํ•˜๊ณ 

๊ทธ ์ˆซ์ž๋“ค์„ ์„œ๋กœ ๋น„๊ตํ•ด์„œ ์–ผ๋งˆ๋‚˜ ๋น„์Šทํ•œ์ง€ ํŒ๋‹จํ•˜๋Š” ๊ฒƒ

๋‘ ์ด๋ฏธ์ง€ ๊ฐ„ ์œ ์‚ฌ๋„๋ฅผ ์ธก์ •

: ํŠน์ง•์„ ๋Œ€ํ‘œํ•  ์ˆ˜ ์žˆ๋Š” ์ˆซ์ž๋ฅผ ํŠน์ง• ๋ฒกํ„ฐ ํ˜น์€ ํŠน์ง• ๋””์Šคํฌ๋ฆฝํ„ฐ

 

 

 

 

2. ํ‰๊ท  ํ•ด์‹œ ๋งค์นญ(Average Hash Matching)

: ์ด๋ฏธ์ง€ ๋งค์นญ์˜ ํ•œ ๊ธฐ๋ฒ•

: ํŠน์ง• ๋ฒกํ„ฐ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ํ‰๊ท ๊ฐ’์„ ์‚ฌ์šฉ

: ๋‘ ์ด๋ฏธ์ง€ ์‚ฌ์ด์—์„œ ๋น„์Šทํ•œ ๊ทธ๋ฆผ์„ ์ฐพ๊ธฐ ์ „์— ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ทธ๋ฆผ์˜ ํŠน์ง• ๋ฒกํ„ฐ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•

    1) ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€๋กœ ์„ธ๋กœ ๋น„์œจ๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ํŠน์ •ํ•œ ํฌ๊ธฐ๋กœ ์ถ•์†Œ

    2) ํ”ฝ์…€ ์ „์ฒด์˜ ํ‰๊ท ๊ฐ’์„ ๊ตฌํ•ด์„œ ๊ฐ ํ”ฝ์…€์˜ ๊ฐ’์ด ํ‰๊ท ๋ณด๋‹ค ์ž‘์œผ๋ฉด 0, ํฌ๋ฉด 1๋กœ ๋ฐ”๊พธ๊ธฐ

    3) ๋˜๋Š” 1๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ๊ฐ ํ”ฝ์…€ ๊ฐ’์„ 1ํ–‰ 1์—ด๋กœ ๋ณ€ํ™˜ (์ด๋Š” ํ•œ ๊ฐœ์˜ 2์ง„์ˆ˜ ์ˆซ์ž๋กœ ๋ณด๊ธฐ)

 

: ๋น„๊ต๋ฅผ ํ•˜๊ณ ์ž ํ•˜๋Š” ๋‘ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ™์€ ํฌ๊ธฐ๋กœ ์ถ•์†Œ

: 0๊ณผ 1์˜ ๊ฐœ์ˆ˜๋„ ๋™์ผ (2์ง„์ˆ˜๋กœ ํ‘œํ˜„ํ–ˆ์„ ๋•Œ ๋น„ํŠธ ๊ฐœ์ˆ˜๊ฐ€ ๊ฐ™๋‹ค)

# ๊ถŒ์ด์„ ํ‰๊ท  ํ•ด์‹œ๋กœ ๋ณ€ํ™˜
import cv2

#์˜์ƒ ์ฝ์–ด์„œ ๊ทธ๋ ˆ์ด ์Šค์ผ€์ผ๋กœ ๋ณ€ํ™˜
img = cv2.imread('img/pistol.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 8x8 ํฌ๊ธฐ๋กœ ์ถ•์†Œ ---โ‘ 
gray = cv2.resize(gray, (16,16))
# ์˜์ƒ์˜ ํ‰๊ท ๊ฐ’ ๊ตฌํ•˜๊ธฐ ---โ‘ก
avg = gray.mean()
# ํ‰๊ท ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ 0๊ณผ 1๋กœ ๋ณ€ํ™˜ ---โ‘ข
bin = 1 * (gray > avg)
print(bin)

# 2์ง„์ˆ˜ ๋ฌธ์ž์—ด์„ 16์ง„์ˆ˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ ---โ‘ฃ
dhash = []
for row in bin.tolist():
    s = ''.join([str(i) for i in row])
    dhash.append('%02x'%(int(s,2)))
dhash = ''.join(dhash)
print(dhash)

cv2.namedWindow('pistol', cv2.WINDOW_GUI_NORMAL)
cv2.imshow('pistol', img)
cv2.waitKey(0)

๊ถŒ์ด ์ด๋ฏธ์ง€๋ฅผ 16 x 16 ํฌ๊ธฐ์˜ ํ‰๊ท  ํ•ด์‹œ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํŠน์ง• ๋ฒกํ„ฐ๋ฅผ ๊ตฌํ•˜๊ธฐ

1) ์ด๋ฏธ์ง€๋ฅผ 16 x 16 ์‚ฌ์ด์ฆˆ๋กœ ์กฐ์ •

2) ํ”ฝ์…€์˜ ์ „์ฒด ํ‰๊ท ๊ฐ’์„ ๊ตฌํ•˜๊ณ  ๊ทธ ํ‰๊ท ๊ฐ’๋ณด๋‹ค ํฐ ํ”ฝ์…€์€ 1, ์ž‘์€ ํ”ฝ์…€์€ 0์œผ๋กœ ๋ฐ”๊พธ๊ธฐ

3) ๊ฒฐ๊ณผ, 0๊ณผ 1๋กœ ๊ตฌ์„ฑ๋œ ๋ฐฐ์—ด

4) 0์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋ถ€๋ถ„์ด ๊ถŒ์ด ๋ชจ์–‘์„ ๋‹ฎ์•˜์Œ

5) ๊ถŒ์ด์€ ๊ฒ€์€์ƒ‰์ด๋ฏ€๋กœ ํ”ฝ์…€ ๊ฐ’์ด 0์— ๊ฐ€๊น๊ณ , ๋ฐฐ๊ฒฝ์€ ํ”ฝ์…€ ๊ฐ’์ด 255์— ๊ฐ€๊น๋‹ค

6) ์ „์ฒด ํ”ฝ์…€์˜ ํ‰๊ท ๊ฐ’๋ณด๋‹ค ์ž‘์€ ๋ถ€๋ถ„์€ 0, ํฐ ๋ถ€๋ถ„์€ 1๋กœ ๋ฐ”๋€ ๊ฒƒ

 

- ๋‹ค๋ฅธ ์ด๋ฏธ์ง€์˜ ๊ฒƒ๊ณผ ๋น„๊ตํ•ด์„œ ์–ผ๋งˆ๋‚˜ ๋น„์Šทํ•œ์ง€๋ฅผ ์•Œ์•„๋‚ด์•ผ ํ•œ๋‹ค

- ๋น„์Šทํ•œ ์ •๋„๋ฅผ ์ธก์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•

 

  • ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ(Euclidian distance)
    • ๋‘ ๊ฐ’์˜ ์ฐจ์ด๋กœ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐ
    • ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๊ฐ€ ์ž‘์„์ˆ˜๋ก ๋‘ ์ˆ˜๋Š” ๋น„์Šทํ•œ ์ˆ˜
    • 5์™€ ๋น„๊ตํ•  ๊ฐ’์œผ๋กœ 1๊ณผ 7์ด ์žˆ๋‹ค๋ฉด 5์™€ 1์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋Š” 5-1 = 4, 5์™€ 7์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋Š” 7-5 = 2
  • ํ•ด๋ฐ ๊ฑฐ๋ฆฌ(Hamming distance)
    • ๋‘ ๊ฐ’์˜ ๊ธธ์ด๊ฐ€ ๊ฐ™์•„์•ผ ๊ณ„์‚ฐ
    • ๋‘ ์ˆ˜์˜ ๊ฐ™์€ ์ž๋ฆฌ ๊ฐ’ ์ค‘ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ์ด ๋ช‡ ๊ฐœ์ธ์ง€๋ฅผ ํŒ๋‹จํ•˜์—ฌ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐ
    • 12345์™€ ๋น„๊ตํ•  ๊ฐ’์œผ๋กœ 12354์™€ 92345๊ฐ€ ์žˆ์„ ๋•Œ 12345์™€ 12354์˜ ๋งˆ์ง€๋ง‰ ์ž๋ฆฌ๊ฐ€ 45์™€ 54๋กœ ๋‹ค๋ฅด๋ฏ€๋กœ ํ•ด๋ฐ ๊ฑฐ๋ฆฌ๋Š” 2์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด 12345์™€ 92345๋Š” 1๊ณผ 9 ํ•œ์ž๋ฆฌ๋งŒ ๋‹ค๋ฅด๋ฏ€๋กœ ํ•ด๋ฐ ๊ฑฐ๋ฆฌ๋Š” 1

: ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋Š” ์ž๋ฆฟ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ฐจ์ด๊ฐ€ ํฌ๊ฒŒ ๋ฒŒ์–ด์ง„๋‹ค

: ํ•ด๋ฐ ๊ฑฐ๋ฆฌ๋Š” ๋ช‡ ๊ฐœ์˜ ์ˆซ์ž๊ฐ€ ๋‹ค๋ฅธ๊ฐ€๋งŒ์„ ๊ณ ๋ ค

: ์ด๋ฏธ์ง€๋ฅผ ๋น„๊ตํ•˜๋Š”๋ฐ ํ‰๊ท  ํ•ด์‹œ ์ˆซ์ž์˜ ํฌ๊ธฐ๊ฐ€ ์ค‘์š”ํ•˜๊ธฐ๋ณด๋‹ค๋Š” ์–ผ๋งˆ๋‚˜ ์œ ์‚ฌํ•œ ์ž๋ฆฟ์ˆ˜๊ฐ€ ๋งŽ์€์ง€๊ฐ€ ๋” ์ค‘์š”

# ์‚ฌ๋ฌผ ์ด๋ฏธ์ง€ ์ค‘์—์„œ ๊ถŒ์ด ์ด๋ฏธ์ง€ ์ฐพ๊ธฐ
import cv2
import numpy as np
import glob

# ์˜์ƒ ์ฝ๊ธฐ ๋ฐ ํ‘œ์‹œ
img = cv2.imread('img/pistol.jpeg')
cv2.imshow('query', img)

# ๋น„๊ตํ•  ์˜์ƒ๋“ค์ด ์žˆ๋Š” ๊ฒฝ๋กœ ---โ‘ 
search_dir = 'img/101_ObjectCategories'

# ์ด๋ฏธ์ง€๋ฅผ 16x16 ํฌ๊ธฐ์˜ ํ‰๊ท  ํ•ด์‰ฌ๋กœ ๋ณ€ํ™˜ ---โ‘ก
def img2hash(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.resize(gray, (16, 16))
    avg = gray.mean()
    bi = 1 * (gray > avg)
    return bi

# ํ•ด๋ฐ๊ฑฐ๋ฆฌ ์ธก์ • ํ•จ์ˆ˜ ---โ‘ข
def hamming_distance(a, b):
    a = a.reshape(1,-1)
    b = b.reshape(1,-1)
    # ๊ฐ™์€ ์ž๋ฆฌ์˜ ๊ฐ’์ด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์˜ ํ•ฉ
    distance = (a !=b).sum()
    return distance

# ๊ถŒ์ด ์˜์ƒ์˜ ํ•ด์‰ฌ ๊ตฌํ•˜๊ธฐ ---โ‘ฃ
query_hash = img2hash(img)

# ์ด๋ฏธ์ง€ ๋ฐ์ดํƒ€ ์…‹ ๋””๋ ‰ํ† ๋ฆฌ์˜ ๋ชจ๋“  ์˜์ƒ ํŒŒ์ผ ๊ฒฝ๋กœ ---โ‘ค
img_path = glob.glob(search_dir+'/**/*.jpg')
for path in img_path:
    # ๋ฐ์ดํƒ€ ์…‹ ์˜์ƒ ํ•œ๊ฐœ ์ฝ์–ด์„œ ํ‘œ์‹œ ---โ‘ฅ
    img = cv2.imread(path)
    cv2.imshow('searching...', img)
    cv2.waitKey(5)
    # ๋ฐ์ดํƒ€ ์…‹ ์˜์ƒ ํ•œ๊ฐœ์˜ ํ•ด์‹œ  ---โ‘ฆ
    a_hash = img2hash(img)
    # ํ•ด๋ฐ ๊ฑฐ๋ฆฌ ์‚ฐ์ถœ ---โ‘ง
    dst = hamming_distance(query_hash, a_hash)
    if dst/256 < 0.25: # ํ•ด๋ฐ๊ฑฐ๋ฆฌ 25% ์ด๋‚ด๋งŒ ์ถœ๋ ฅ ---โ‘จ
        print(path, dst/256)
        cv2.imshow(path, img)
cv2.destroyWindow('searching...')
cv2.waitKey(0)
cv2.destroyAllWindows()

- ๊ถŒ์ด ์ด๋ฏธ์ง€๋ฅผ ๋น„๊ตํ•˜์—ฌ ๊ถŒ์ด๊ณผ ์œ ์‚ฌํ•œ ์ด๋ฏธ์ง€๋ฅผ ์ฐพ์•„๋‚ด๊ธฐ

- ๊ถŒ์ด์˜ ํ‰๊ท  ํ•ด์‹œ์™€ ๋น„๊ตํ•˜์—ฌ ํ•ด๋ฐ ๊ฑฐ๋ฆฌ๊ฐ€ 25% ์ด๋‚ด์ธ ์ด๋ฏธ์ง€๋ฅผ ์ถœ๋ ฅ

- ๋ง์›๊ฒฝ ๋‚˜์™”๋•ฝ,,!!

 

 

 

 

 

3. ํ…œํ”Œ๋ฆฟ ๋งค์นญ (Template Matching)

: ํŠน์ • ๋ฌผ์ฒด์— ๋Œ€ํ•œ ์ด๋ฏธ์ง€๋ฅผ ์ค€๋น„ํ•ด ๋‘๊ณ  ๊ทธ ๋ฌผ์ฒด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ 

์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฏธ์ง€์™€ ๋น„๊ตํ•˜์—ฌ ๋งค์นญ ๋˜๋Š” ์œ„์น˜๋ฅผ ์ฐพ๋Š” ๊ฒƒ

: ๋ฏธ๋ฆฌ ์ค€๋น„ํ•œ ์ด๋ฏธ์ง€๋ฅผ ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€

: ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€๋Š” ๋น„๊ตํ•  ์ด๋ฏธ์ง€๋ณด๋‹ค ํฌ๊ธฐ๊ฐ€ ํ•ญ์ƒ ์ž‘์•„์•ผํ•จ

 

result = cv2.matchTemplate(img, templ, method, result, mask)

: ์ž…๋ ฅ ์ด๋ฏธ์ง€(img)์—์„œ ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€(templ)๋ฅผ ์Šฌ๋ผ์ด๋”ฉํ•˜๋ฉด์„œ ์ฃผ์–ด์ง„ ๋ฉ”์„œ๋“œ์— ๋”ฐ๋ผ ๋งค์นญ์„ ์ˆ˜ํ–‰

: ๋ฐ˜ํ™˜ ๊ฐ’์€ (W - w + 1) x (H - h + 1) ํฌ๊ธฐ์˜ 2์ฐจ์› ๋ฐฐ์—ด

: ์ด ๋ฐฐ์—ด์˜ ์ตœ๋Œ€, ์ตœ์†Œ ๊ฐ’์„ ๊ตฌํ•˜๋ฉด ์›ํ•˜๋Š” ์ตœ์„ ์˜ ๋งค์นญ ๊ฐ’๊ณผ ๋งค์นญ์ ์„ ๊ตฌํ•œ๋‹ค

 

- img : ์ž…๋ ฅ ์ด๋ฏธ์ง€
- templ : ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€
- method : ๋งค์นญ ๋ฉ”์„œ๋“œ

  • cv2.TM_SQDIFF : ์ œ๊ณฑ ์ฐจ์ด ๋งค์นญ, ์™„๋ฒฝ ๋งค์นญ : 0, ๋‚˜์œ ๋งค์นญ : ํฐ ๊ฐ’
  • cv2.TM_SQDIFF_NORMED : ์ œ๊ณฑ ์ฐจ์ด ๋งค์นญ์˜ ์ •๊ทœํ™”
  • cv2.TM_CCORR : ์ƒ๊ด€๊ด€๊ณ„ ๋งค์นญ, ์™„๋ฒฝ ๋งค์นญ : ํฐ ๊ฐ’, ๋‚˜์œ ๋งค์นญ : 0
  • cv2.TM_CCORR_NORMED : ์ƒ๊ด€๊ด€๊ณ„ ๋งค์นญ์˜ ์ •๊ทœํ™”
  • cv2.TM_CCOEFF : ์ƒ๊ด€๊ณ„์ˆ˜ ๋งค์นญ, ์™„๋ฒฝ ๋งค์นญ : 1, ๋‚˜์œ ๋งค์นญ : -1
  • cv2.TM_CCOEFF_NORMED : ์ƒ๊ด€๊ณ„์ˆ˜ ๋งค์นญ์˜ ์ •๊ทœํ™”

- result(optional) : ๋งค์นญ ๊ฒฐ๊ณผ, (W - w + 1) x (H - h + 1) ํฌ๊ธฐ์˜ 2์ฐจ์› ๋ฐฐ์—ด

[์—ฌ๊ธฐ์„œ W, H๋Š” ์ž…๋ ฅ ์ด๋ฏธ์ง€์˜ ๋„ˆ๋น„์™€ ๋†’์ด, w, h๋Š” ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€์˜ ๋„ˆ๋น„์™€ ๋†’์ด]

- mask(optional) : TM_SQDIFF, TM_CCORR_NORMED์ธ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ๋งˆ์Šคํฌ

 

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src, mask)

: ์ž…๋ ฅ ๋ฐฐ์—ด์—์„œ์˜ ์ตœ์†Œ, ์ตœ๋Œ€ ๊ฐ’๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ตœ์†Œ ๊ฐ’, ์ตœ๋Œ€ ๊ฐ’์˜ ์ขŒํ‘œ๋„ ๋ฐ˜ํ™˜

 

- src : ์ž…๋ ฅ 1 ์ฑ„๋„ ๋ฐฐ์—ด
- minVal, maxVal : ๋ฐฐ์—ด ์ „์ฒด์—์„œ์˜ ์ตœ์†Œ ๊ฐ’, ์ตœ๋Œ€ ๊ฐ’
- minLoc, maxLoc : ์ตœ์†Œ ๊ฐ’๊ณผ ์ตœ๋Œ€ ๊ฐ’์˜ ์ขŒํ‘œ (x, y)

# ํ…œํ”Œ๋ฆฟ ๋งค์นญ์œผ๋กœ ๊ฐ์ฒด ์œ„์น˜ ๊ฒ€์ถœ
import cv2
import numpy as np

# ์ž…๋ ฅ์ด๋ฏธ์ง€์™€ ํ…œํ”Œ๋ฆฟ ์ด๋ฏธ์ง€ ์ฝ๊ธฐ
img = cv2.imread('img/figures.jpg')
template = cv2.imread('img/taekwonv1.jpg')
th, tw = template.shape[:2]
cv2.imshow('template', template)

# 3๊ฐ€์ง€ ๋งค์นญ ๋ฉ”์„œ๋“œ ์ˆœํšŒ
methods = ['cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR_NORMED', \
                                     'cv2.TM_SQDIFF_NORMED']
for i, method_name in enumerate(methods):
    img_draw = img.copy()
    method = eval(method_name)
    # ํ…œํ”Œ๋ฆฟ ๋งค์นญ   ---โ‘ 
    res = cv2.matchTemplate(img, template, method)
    # ์ตœ๋Œ€, ์ตœ์†Œ๊ฐ’๊ณผ ๊ทธ ์ขŒํ‘œ ๊ตฌํ•˜๊ธฐ ---โ‘ก
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    print(method_name, min_val, max_val, min_loc, max_loc)

    # TM_SQDIFF์˜ ๊ฒฝ์šฐ ์ตœ์†Œ๊ฐ’์ด ์ข‹์€ ๋งค์นญ, ๋‚˜๋จธ์ง€๋Š” ๊ทธ ๋ฐ˜๋Œ€ ---โ‘ข
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
        match_val = min_val
    else:
        top_left = max_loc
        match_val = max_val
    # ๋งค์นญ ์ขŒํ‘œ ๊ตฌํ•ด์„œ ์‚ฌ๊ฐํ˜• ํ‘œ์‹œ   ---โ‘ฃ      
    bottom_right = (top_left[0] + tw, top_left[1] + th)
    cv2.rectangle(img_draw, top_left, bottom_right, (0,0,255),2)
    # ๋งค์นญ ํฌ์ธํŠธ ํ‘œ์‹œ ---โ‘ค
    cv2.putText(img_draw, str(match_val), top_left, \
                cv2.FONT_HERSHEY_PLAIN, 2,(0,255,0), 1, cv2.LINE_AA)
    cv2.imshow(method_name, img_draw)
cv2.waitKey(0)
cv2.destroyAllWindows()

 ๋กœ๋ด‡ ํƒœ๊ถŒ V๋ฅผ ๋‹ค๋ฅธ ์ด๋ฏธ์ง€ ๋‚ด์—์„œ ํ…œํ”Œ๋ฆฟ ๋งค์นญ ๋ฐฉ์‹์œผ๋กœ ์ฐพ๊ธฐ

- cv2.TM_SQDIFF_NORMED : ์ œ๊ณฑ ์ฐจ์ด ๋งค์นญ์˜ ์ •๊ทœํ™”

=> ์ตœ์†Œ๊ฐ’์ด ์ข‹์€ ๋งค์นญ

- cv2.TM_CCORR_NORMED : ์ƒ๊ด€๊ด€๊ณ„ ๋งค์นญ์˜ ์ •๊ทœํ™”

- cv2.TM_CCOEFF_NORMED : ์ƒ๊ด€๊ณ„์ˆ˜ ๋งค์นญ์˜ ์ •๊ทœํ™”

 

 

 

 

 

ํ›„ํ›„...

728x90
๋ฐ˜์‘ํ˜•
Comments