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

[v0.35]์˜์ƒ์ฒ˜๋ฆฌ_ํŠน์ง• ๋งค์นญ(Feature Matching) ๋ณธ๋ฌธ

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

[v0.35]์˜์ƒ์ฒ˜๋ฆฌ_ํŠน์ง• ๋งค์นญ(Feature Matching)

์ง•์ง•์•ŒํŒŒ์นด 2022. 1. 18. 01:41
728x90
๋ฐ˜์‘ํ˜•

220118 ์ž‘์„ฑ

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

https://bkshin.tistory.com/entry/OpenCV-33-HOG-%EB%94%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%84%B0HOG-Descriptor?category=1148027 

 

OpenCV - 33. HOG(Histogram of Oriented Gradient) ๋””์Šคํฌ๋ฆฝํ„ฐ

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” HOG ๋””์Šคํฌ๋ฆฝํ„ฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋„ 'ํŒŒ์ด์ฌ์œผ๋กœ ๋งŒ๋“œ๋Š” OpenCV ํ”„๋กœ์ ํŠธ(์ด์„ธ์šฐ ์ €)'๋ฅผ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ(Gradient Vectors) ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ๋ž€ ์˜์ƒ ๋‚ด ํ•˜๋‚˜์˜

bkshin.tistory.com

 

 

 

 

 

1. ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ(Gradient Vectors)

: ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ๋ž€ ์˜์ƒ ๋‚ด ํ•˜๋‚˜์˜ ํ”ฝ์…€์„ ๊ธฐ์ค€์œผ๋กœ ์ฃผ๋ณ€ ํ”ฝ์…€์— ๋Œ€ํ•œ ๊ธฐ์šธ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฒกํ„ฐ

 

 https://chrisjmccormick.wordpress.com/2013/05/07/gradient-vectors/

 

: ๋นจ๊ฐ„ ์ ์œผ๋กœ ํ‘œ์‹œ๋œ ํ”ฝ์…€์„ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ์˜ Gray Scale ๊ฐ’์€ 56์ด๊ณ , ์˜ค๋ฅธ์ชฝ์˜ ๊ฐ’์€ 94

: Gray Scale์˜ ๊ฒฝ์šฐ 0์ด๋ฉด ๊ฒ€์€์ƒ‰์ด๊ณ  255์ด๋ฉด ํฐ์ƒ‰

: Gray Scale ๊ฐ’ 94๊ฐ€ 56๋ณด๋‹ค ๋ฐ์Œ

: ๋นจ๊ฐ„ ์ ์œผ๋กœ ํ‘œ์‹œ๋œ ํ”ฝ์…€ ์ž…์žฅ์—์„œ x์ถ• ๋ฐฉํ–ฅ์˜ ๋ณ€ํ™”๋Ÿ‰(gx)์€ (94 - 56) = 38

=> ์ด ๊ฐ’์ด x์ถ• ๋ฐฉํ–ฅ ๊ธฐ์šธ๊ธฐ ๋ณ€ํ™”๋Ÿ‰

 https://chrisjmccormick.wordpress.com/2013/05/07/gradient-vectors/

 

: y์ถ• ๋ฐฉํ–ฅ,, ๋นจ๊ฐ„ ์ ์„ ๊ธฐ์ค€์œผ๋กœ ์œ„์ชฝ Gray Scale ๊ฐ’์€ 93์ด๊ณ , ์•„๋ž˜์ชฝ ๊ฐ’์€ 55

=> y์ถ• ๋ฐฉํ–ฅ์˜ ๊ธฐ์šธ๊ธฐ ๋ณ€ํ™”๋Ÿ‰์€ (93 - 55) = 38

: x์ถ• ๋ฐฉํ–ฅ ๊ธฐ์šธ๊ธฐ ๋ณ€ํ™”๋Ÿ‰, y์ถ• ๋ฐฉํ–ฅ ๊ธฐ์šธ๊ธฐ ๋ณ€ํ™”๋Ÿ‰์ด ๋ชจ๋‘ 38

=> x์ถ• ๋ฐฉํ–ฅ ๊ธฐ์šธ๊ธฐ ๋ณ€ํ™”๋Ÿ‰, y์ถ• ๋ฐฉํ–ฅ ๊ธฐ์šธ๊ธฐ ๋ณ€ํ™”๋Ÿ‰์„ ํ•จ๊ป˜ ํ‘œํ˜„ํ•œ ๊ฐ’์ด ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ(gradient vector)

 

๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ์˜ ํฌ๊ธฐ์™€ ๋ฐฉํ–ฅ(๊ฐ๋„) ๊ณ„์‚ฐ
         ํฌ๊ธฐ๋Š” 53.74, ๋ฐฉํ–ฅ(๊ฐ๋„)์€ 45๋„          < ํฌ๊ธฐ์™€ ๋ฐฉํ–ฅ์„ ๋ฒกํ„ฐ๋กœ ํ‘œ์‹œ >

 

 

 

 

2. ํ”ฝ์…€(Pixels), ์…€(Cells), ๋ธ”๋ก(Blocks)

ํ”ฝ์…€ : ๋ง ๊ทธ๋Œ€๋กœ ์˜์ƒ ๋‚ด ํ•˜๋‚˜์˜ ํ”ฝ์…€ ๊ฐ’์„ ์˜๋ฏธ

์…€ : ์ด ํ”ฝ์…€๋“ค์„ ๋ช‡ ๊ฐœ ๋ฌถ์–ด์„œ ์†Œ๊ทธ๋ฃน์œผ๋กœ ๋งŒ๋“  ๊ฒƒ

๋ธ”๋ก : ๋‹ค์‹œ ์…€์„ ๋ช‡ ๊ฐœ ๋ฌถ์–ด์„œ ๊ทธ๋ฃน์œผ๋กœ ๋งŒ๋“  ๊ฒƒ

=> ํ•˜๋‚˜์˜ ๋ธ”๋ก ์•ˆ์— ์…€ ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์žˆ๊ณ , ํ•˜๋‚˜์˜ ์…€ ์•ˆ์— ํ”ฝ์…€ ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์žˆ์Œ

 

 

 

 

3. HOG(Histogram of Oriented Gradient)

: HOG๋Š” ๋ณดํ–‰์ž ๊ฒ€์ถœ์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ํŠน์ง• ๋””์Šคํฌ๋ฆฝํ„ฐ

: HOG๋Š” ์ด๋ฏธ์ง€ ๊ฒฝ๊ณ„์˜ ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ ํฌ๊ธฐ(magnitude)์™€ ๋ฐฉํ–ฅ(direction)์„ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋‚˜ํƒ€๋‚ด ๊ณ„์‚ฐ

: HOG ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ์˜์ƒ ์†์—์„œ ๊ฒ€์ถœํ•˜๊ณ ์ž ํ•˜๋Š” ์˜์—ญ์„ ์ž๋ฆ„

: ์ž˜๋ผ๋‚ธ ์˜์—ญ์„ ์œˆ๋„(window)

import cv2
import numpy as np

img = cv2.imread('img/jk.jpg')
img = np.float32(img) / 255.0

gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
magnitude, angle = cv2.cartToPolar(gx, gy)

 https://www.researchgate.net/figure/Histogram-of-Oriented-Gradient-12_fig3_313369595

: ๊ฐ ํ”ฝ์…€์„ ๊ธฐ์ค€์œผ๋กœ ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ๋ฅผ ๊ตฌํ•ด์•ผํ•จ

: ํ™”์‚ดํ‘œ๋กœ ํ‘œ์‹œ๋œ ๊ฒƒ์ด ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ์ž…

: ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ์˜ ํฌ๊ธฐ์™€ ๋ฐฉํ–ฅ์„ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ

: ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ์˜ ๋ฐฉํ–ฅ์„ ๊ณ„๊ธ‰(bin)์œผ๋กœ ํ•˜๊ณ  ํฌ๊ธฐ๋ฅผ ๊ฐ’์œผ๋กœ ๋ˆ„์ ํ•œ ํžˆ์Šคํ† ๊ทธ๋žจ

: ๊ณ„๊ธ‰(bin)์€ 180๋„๋ฅผ 20๋„์”ฉ ์ด 9๊ฐœ์˜ ๊ตฌ๊ฐ„์œผ๋กœ ๋‚˜๋ˆ„์–ด ์‚ฌ

: 360๋„๊ฐ€ ์•„๋‹Œ 180๋„๋กœ ํ•˜๋Š” ์ด์œ ๋Š” ๊ธฐ์šธ๊ธฐ์˜ ์–‘์ˆ˜์™€ ์Œ์ˆ˜๊ฐ€ ๊ฐ™์€ ๋ฐฉํ–ฅ์„ ๋‚˜ํƒ€๋ƒ„

: ์œˆ๋„ ์ „์ฒด๋ฅผ ํ•˜๋‚˜์˜ ํžˆ์Šคํ† ๊ทธ๋žจ์œผ๋กœ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ•˜๋‚˜์˜ ์…€์„ ๊ธฐ์ค€์œผ๋กœ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ณ„์‚ฐ

 

 

 

: ํžˆ์Šคํ† ๊ทธ๋žจ ๊ณ„์‚ฐ์„ ๋งˆ์น˜๋ฉด ์ •๊ทœํ™”(normalization) ๊ณผ์ •์„ ๊ฑฐ์น˜๊ธฐ

: ๊ฒฝ๊ณ„ ๊ฐ’ ๊ธฐ์šธ๊ธฐ๋Š” ๋ฐ๊ธฐ์— ๋ฏผ๊ฐ => ๋ฏผ๊ฐ์„ฑ์„ ์—†์• ์ฃผ๋ ค๊ณ  ์ •๊ทœํ™”

: ์ •๊ทœํ™”๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด ์œˆ๋„๋ฅผ ํŠน์ • ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„๊ธฐ => ๋‚˜๋ˆ„๋Š” ์˜์—ญ์„ ๋ธ”๋ก(block)

: ๋ธ”๋ก ํฌ๊ธฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์…€ ํฌ๊ธฐ์˜ 2๋ฐฐ

: ๊ฐ ๋ธ”๋ก์€ ์ „์ฒด ์œˆ๋„๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ์ •๊ทœํ™” => ๊ฒน์น˜๋Š” ๋ถ€๋ถ„์ด ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์ด ๋ถ€๋ถ„์„ ๋ธ”๋ก ์ŠคํŠธ๋ผ์ด๋“œ(blcok stride)

 

=> ์›๋ณธ ์˜์ƒ์—์„œ ๋ณดํ–‰์ž์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„์„ ์ž๋ฅธ ์˜์—ญ์„ ์œˆ๋„(window)

=> ์‚ฌ๋žŒ์„ ๊ฒ€์ถœํ•  ๋•Œ๋Š” ๋ณดํ†ต 64 x 128 ํฌ๊ธฐ๋กœ ์œˆ๋„๋ฅผ ์ •ํ•จ

=> ์ž๋ฅธ ์œˆ๋„์—์„œ ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ๋ฅผ ๊ตฌํ•จ

=> ํŠน์ • ์˜์—ญ์„ ์ค‘์‹ฌ์œผ๋กœ ๊ธฐ์šธ๊ธฐ ๋ฒกํ„ฐ ํฌ๊ธฐ์™€ ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ตฌํ•จ

=> ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•œ ์˜์—ญ์„ ์…€(cell) ์…€์€ ๋ณดํ†ต 8 x 8 ํฌ๊ธฐ

=> ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๊ณ„์‚ฐํ•œ ๋’ค ์ •๊ทœํ™”

=> ์ •๊ทœํ™”ํ•˜๋ ค๋ฉด ์œˆ๋„๋ฅผ ๋‹ค์‹œ ์ž˜๊ฒŒ ๋‚˜๋ˆ„์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋ฅผ ๋ธ”๋ก(block)

=> ๋ธ”๋ก ํฌ๊ธฐ๋Š” ๋Œ€๊ฒŒ ์…€ ํฌ๊ธฐ์˜ 2๋ฐฐ, ๋ธ”๋ก์€ ์ „์ฒด ์œˆ๋„๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ์ •๊ทœํ™”ํ•˜๋Š”๋ฐ

=> ๋ธ”๋ก์ด ํ•œ๋ฒˆ์— ์ด๋™ํ•˜๋Š” ๊ฑฐ๋ฆฌ๋ฅผ ๋ธ”๋ก ์ŠคํŠธ๋ผ์ด๋“œ(block stride)

 

 

 

 

 

 

4. HOG ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ๋ณดํ–‰์ž ์ธ์‹

descriptor = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins)

: HOG ๋””์Šคํฌ๋ฆฝํ„ฐ ์ถ”์ถœ๊ธฐ ์ƒ์„ฑ

: ๋ฏธ๋ฆฌ ํ›ˆ๋ จ๋œ SVM ๋ชจ๋ธ(pretrained SVM model)์„ ์ „๋‹ฌ๋ฐ›์•„ ๋ณดํ–‰์ž๋ฅผ ์ถ”์ถœ ๊ฐ€๋Šฅ

 

- winSize : ์œˆ๋„ ํฌ๊ธฐ, HOG ์ถ”์ถœ ์˜์—ญ
- blockSize : ๋ธ”๋ก ํฌ๊ธฐ, ์ •๊ทœํ™” ์˜์—ญ
- blockStride : ์ •๊ทœํ™” ๋ธ”๋ก ๊ฒน์นจ ํฌ๊ธฐ
- cellSize : ์…€ ํฌ๊ธฐ, ํžˆ์Šคํ† ๊ทธ๋žจ ๊ณ„์‚ฐ ์˜์—ญ
- nbins : ํžˆ์Šคํ† ๊ทธ๋žจ ๊ณ„๊ธ‰ ์ˆ˜
- descriptor : HOG ํŠน์ง• ๋””์Šคํฌ๋ฆฝํ„ฐ ์ถ”์ถœ๊ธฐ

 

hog = descriptor.compute(img)

: HOG ๊ณ„์‚ฐ

 

- img : ๊ณ„์‚ฐ ๋Œ€์ƒ ์ด๋ฏธ์ง€
- hog : HOG ํŠน์ง• ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ฒฐ๊ณผ

 

+ ๋ณดํ–‰์ž ์ธ์‹์„ ์œ„ํ•œ ์‚ฌ์ „ ํ›ˆ๋ จ API๋ฅผ ์ œ๊ณต

scvmdetector = cv2.HOGDescriptor_getDefaultPeopleDetector() : 64 x 128 ์œˆ๋„ ํฌ๊ธฐ๋กœ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ

scvmdetector = cv2.HOGDescriptor_getDaimlerPeopleDetector() : 48 x 96 ์œˆ๋„ ํฌ๊ธฐ๋กœ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ

descriptor = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins) : HOG ์ƒ์„ฑ

descriptor.setSVMDetector(svmdetector) : ํ›ˆ๋ จ๋œ SVM ๋ชจ๋ธ ์„ค์ •

rects, weights = descriptor.detectMultiScale(img) : ๊ฐ์ฒด ๊ฒ€์ถœ
- img : ๊ฒ€์ถœํ•˜๊ณ ์ž ํ•˜๋Š” ์ด๋ฏธ์ง€
- rects : ๊ฒ€์ถœ๋œ ๊ฒฐ๊ณผ ์˜์—ญ ์ขŒํ‘œ N x 4 (x, y, w, h)
- weights : ๊ฒ€์ถœ๋œ ๊ฒฐ๊ณผ ๊ณ„์ˆ˜ N x 1

# HOG-SVM ๋ณดํ–‰์ž ๊ฒ€์ถœ
import cv2

# default ๋””๋ฑํ„ฐ๋ฅผ ์œ„ํ•œ HOG ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์„ค์ •--- โ‘ 
hogdef = cv2.HOGDescriptor()
hogdef.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

# dailer ๋””๋ฑํ„ฐ๋ฅผ ์œ„ํ•œ HOG ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์„ค์ •--- โ‘ก
hogdaim  = cv2.HOGDescriptor((48,96), (16,16), (8,8), (8,8), 9)
hogdaim.setSVMDetector(cv2.HOGDescriptor_getDaimlerPeopleDetector())

cap = cv2.VideoCapture('img/walking.mp4')
mode = True  # ๋ชจ๋“œ ๋ณ€ํ™˜์„ ์œ„ํ•œ ํ”Œ๋ž˜๊ทธ ๋ณ€์ˆ˜ 
print('Toggle Space-bar to change mode.')
while cap.isOpened():
    ret, img = cap.read()
    if ret :
        if mode:
            # default ๋””ํ…ํ„ฐ๋กœ ๋ณดํ–‰์ž ๊ฒ€์ถœ --- โ‘ข
            found, _ = hogdef.detectMultiScale(img)
            for (x,y,w,h) in found:
                cv2.rectangle(img, (x,y), (x+w, y+h), (0,255,255))
        else:
            # daimler ๋””ํ…ํ„ฐ๋กœ ๋ณดํ–‰์ž ๊ฒ€์ถœ --- โ‘ฃ
            found, _ = hogdaim.detectMultiScale(img)
            for (x,y,w,h) in found:
                cv2.rectangle(img, (x,y), (x+w, y+h), (0,255,0))
        cv2.putText(img, 'Detector:%s'%('Default' if mode else 'Daimler'), \
                        (10,50 ), cv2.FONT_HERSHEY_DUPLEX,1, (0,255,0),1)
        cv2.imshow('frame', img)
        key = cv2.waitKey(1) 
        if key == 27:
            break
        elif key == ord(' '):
            mode = not mode
    else:
        break
cap.release()
cv2.destroyAllWindows()

HOG ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ด์šฉํ•ด Default ๋ณดํ–‰์ž ์ธ์‹
HOG ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ด์šฉํ•ด Daimler ๋ณดํ–‰์ž ์ธ์‹

- Default ๋ณดํ–‰์ž ๊ฒ€์ถœ๊ธฐ์™€ Daimler ๋ณดํ–‰์ž ๊ฒ€์ถœ๊ธฐ๋ฅผ ์ด์šฉํ•ด ๋ณดํ–‰์ž๋ฅผ ๊ฒ€์ถœ

- ์ŠคํŽ˜์ด์Šค ๋ฐ”๋ฅผ ๋ˆ„๋ฅด๋ฉด ๊ฒ€์ถœ๊ธฐ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

- ๋…ธ๋ž€์ƒ‰ ๋ฐ•์Šค๋กœ ๋ณดํ–‰์ž๋ฅผ ์ธ์‹ํ•œ ๊ฒŒ Default ๋ณดํ–‰์ž ๊ฒ€์ถœ๊ธฐ

- ์ดˆ๋ก์ƒ‰ ๋ฐ•์Šค๋กœ ๋ณดํ–‰์ž๋ฅผ ์ธ์‹ํ•œ ๊ฒŒ Daimler ๋ณดํ–‰์ž ๊ฒ€์ถœ๊ธฐ

- Default ๋ณดํ–‰์ž ๊ฒ€์ถœ๊ธฐ๋Š” ๋ถˆํ•„์š”ํ•œ ๊ฒ€์ถœ์ด ์ ์€ ๋Œ€์‹  ๋ฉ€๋ฆฌ ์žˆ๋Š” ์ž‘์€ ๋ณดํ–‰์ž๋Š” ๊ฒ€์ถœํ•˜์ง€ ๋ชปํ•จ

- Daimler ๋ณดํ–‰์ž ๊ฒ€์ถœ๊ธฐ๋Š” ๋ฉ€๋ฆฌ ์žˆ๋Š” ์ž‘์€ ๋ณดํ–‰์ž๋„ ๊ฒ€์ถœํ•˜์ง€๋งŒ ์‚ผ๊ฐ๋Œ€๋‚˜ ๊ฑด๋ฌผ ๊ทธ๋ฆผ์ž๋„ ๋ณดํ–‰์ž๋กœ ์ธ์‹

 

 

 

 

 

 

 

์™€์šฐ~ ๋™์˜์ƒ๋„˜๋‚˜ ๋Š๋ฆฌ๋‹น

ํฌ๊ธฐ๊ฐ€ ์ปค์„œ ๋งŽ์ด ์ž˜๋ฆฐ๋‹ค ใ…œใ…กใ…œ

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