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

[v0.14]์˜์ƒ์ฒ˜๋ฆฌ_์ด๋ฏธ์ง€ ์œ ์‚ฌ๋„ ๋น„๊ต ์™ธ ์‹ค์Šต ๋ณธ๋ฌธ

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

[v0.14]์˜์ƒ์ฒ˜๋ฆฌ_์ด๋ฏธ์ง€ ์œ ์‚ฌ๋„ ๋น„๊ต ์™ธ ์‹ค์Šต

์ง•์ง•์•ŒํŒŒ์นด 2022. 1. 5. 02:02
728x90
๋ฐ˜์‘ํ˜•

220105 ์ž‘์„ฑ

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

https://bkshin.tistory.com/entry/OpenCV-12-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%9C%A0%EC%82%AC%EB%8F%84-%EB%B9%84%EA%B5%90-%EC%82%AC%EB%9E%8C-%EC%96%BC%EA%B5%B4%EA%B3%BC-%ED%95%B4%EA%B3%A8-%ED%95%A9%EC%84%B1-%EB%AA%A8%EC%85%98-%EA%B0%90%EC%A7%80-CCTV?category=1148027 

 

OpenCV - 12. ์ด๋ฏธ์ง€ ์œ ์‚ฌ๋„ ๋น„๊ต, ์‚ฌ๋žŒ ์–ผ๊ตด๊ณผ ํ•ด๊ณจ ํ•ฉ์„ฑ, ๋ชจ์…˜ ๊ฐ์ง€ CCTV

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

bkshin.tistory.com

 

 

 

 

 

 

1. ์ด๋ฏธ์ง€ ์œ ์‚ฌ๋„ ๋น„๊ต ์‹ค์Šต

: ํ”ฝ์…€ ๊ฐ’์˜ ๋ถ„ํฌ๊ฐ€ ์„œ๋กœ ๋น„์Šทํ•˜๋‹ค๋ฉด ์œ ์‚ฌํ•œ ์ด๋ฏธ์ง€์ผ ํ™•๋ฅ ์ด ๋†’์Œ

: ๋ถ„ํฌ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ์ด๋ฏธ์ง€์ผ ํ™•๋ฅ ์ด ๋†’์Œ

 

cv2.compareHist(hist1, hist2, method)

: ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๋น„๊ตํ•˜์—ฌ ๋‘ ์ด๋ฏธ์ง€๊ฐ€ ์–ผ๋งˆ๋‚˜ ์œ ์‚ฌํ•œ์ง€ ํŒ๋‹จ
- hist1, hist2 : ๋น„๊ตํ•  ๋‘ ๊ฐœ์˜ ํžˆ์Šคํ† ๊ทธ๋žจ, ํฌ๊ธฐ์™€ ์ฐจ์›์ด ๊ฐ™์•„์•ผ ํ•จ
- method : ๋น„๊ต ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • cv2.HISTCMP_CORREL : ์ƒ๊ด€๊ด€๊ณ„ (1 : ์™„์ „ ์ผ์น˜, -1 : ์™„์ „ ๋ถˆ์ผ์น˜, 0 : ๋ฌด๊ด€๊ณ„)
  • cv2.HISTCMP_CHISQR : ์นด์ด์ œ๊ณฑ (0 : ์™„์ „ ์ผ์น˜, ๋ฌดํ•œ๋Œ€ : ์™„์ „ ๋ถˆ์ผ์น˜)
  • cv2.HISTCMP_INTERSECT : ๊ต์ฐจ (1 : ์™„์ „ ์ผ์น˜, 0 : ์™„์ „ ๋ถˆ์ผ์น˜ - 1๋กœ ์ •๊ทœํ™”ํ•œ ๊ฒฝ์šฐ)
# ํžˆ์Šคํ† ๊ทธ๋žจ ๋น„๊ต
import cv2, numpy as np
import matplotlib.pylab as plt

img1 = cv2.imread('img/hobbang.jpeg')
img2 = cv2.imread('img/hobbang1.jpg')
img3 = cv2.imread('img/hobbang2.jpeg')
img4 = cv2.imread('img/jadu.jpg')

# ----------img resize---------------------
img2 = cv2.resize(img2, dsize = (197, 256))
img3 = cv2.resize(img3, dsize = (197, 256))
img4 = cv2.resize(img4, dsize = (197, 256))

cv2.imshow('query', img1)
imgs = [img1, img2, img3, img4]
hists = []
for i, img in enumerate(imgs) :
    plt.subplot(1,len(imgs),i+1)
    plt.title('img%d'% (i+1))
    plt.axis('off') 
    plt.imshow(img[:,:,::-1])
    #---โ‘  ๊ฐ ์ด๋ฏธ์ง€๋ฅผ HSV๋กœ ๋ณ€ํ™˜
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    #---โ‘ก H,S ์ฑ„๋„์— ๋Œ€ํ•œ ํžˆ์Šคํ† ๊ทธ๋žจ ๊ณ„์‚ฐ
    hist = cv2.calcHist([hsv], [0,1], None, [180,256], [0,180,0, 256])
    #---โ‘ข 0~1๋กœ ์ •๊ทœํ™”
    cv2.normalize(hist, hist, 0, 1, cv2.NORM_MINMAX)
    hists.append(hist)


query = hists[0]
methods = {'CORREL' :cv2.HISTCMP_CORREL, 'CHISQR':cv2.HISTCMP_CHISQR, 
           'INTERSECT':cv2.HISTCMP_INTERSECT,
           'BHATTACHARYYA':cv2.HISTCMP_BHATTACHARYYA}
for j, (name, flag) in enumerate(methods.items()):
    print('%-10s'%name, end='\t')
    for i, (hist, img) in enumerate(zip(hists, imgs)):
        #---โ‘ฃ ๊ฐ ๋ฉ”์„œ๋“œ์— ๋”ฐ๋ผ img1๊ณผ ๊ฐ ์ด๋ฏธ์ง€์˜ ํžˆ์Šคํ† ๊ทธ๋žจ ๋น„๊ต
        ret = cv2.compareHist(query, hist, flag)
        if flag == cv2.HISTCMP_INTERSECT: #๊ต์ฐจ ๋ถ„์„์ธ ๊ฒฝ์šฐ 
            ret = ret/np.sum(query)        #๋น„๊ต๋Œ€์ƒ์œผ๋กœ ๋‚˜๋ˆ„์–ด 1๋กœ ์ •๊ทœํ™”
        print("img%d:%7.2f"% (i+1 , ret), end='\t')
    print()
plt.show()

์ด๋ฏธ์ง€ ์œ ์‚ฌ๋„ ์‹ค์Šต
์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณ„ ์œ ์‚ฌ๋„ ๊ฒฐ๊ณผ

- ํžˆ์Šคํ† ๊ทธ๋žจ์„ ๋น„๊ตํ•  ๋•Œ ํฌ๊ธฐ์™€ ์ฐจ์›์ด ๊ฐ™์•„์•ผ ํ•ด์„œ img1 ์˜ ์ด๋ฏธ์ง€ ํฌ๊ธฐ์— ๋งž์ถฐ์„œ resize ํ•จ

- ์ƒ๊ด€ ๊ด€๊ณ„์—์„œ๋Š” ์™œ.. ์ž๋‘๊ฐ€ ๋†’์ง€?

- ์นด์ด ์ œ๊ณฑ์—์„œ๋Š” ์ž๋‘๊ฐ€ .. ๋” ์œ ์‚ฌํ•˜๋„ค? ๋ฌดํ•œ๋Œ€๋กœ ๊ฐ€๋ž€ ๋งˆ๋ฆฌ์–‘!

- ๊ต์ฐจ ์—์„œ๋Š” ๊ทธ๋‚˜๋งˆ ๋‚ฎ๋„ค ใ…œใ…œ

 

 

 

 

2. ํ•ด๊ณจ ์–ผ๊ตด๊ณผ ์‚ฌ์ž ํ•ฉ์„ฑ ์‹ค์Šต

# ํ•ด๊ณจ ์–ผ๊ตด๊ณผ ์‚ฌ์ž ํ•ฉ์„ฑํ•˜๊ธฐ
import cv2
import numpy as np

# ์˜์ƒ์˜ 15%๋ฅผ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ์˜ ๋ฒ”์œ„๋กœ ์ง€์ •
alpha_width_rate = 15

# ํ•ฉ์„ฑํ•  ๋‘ ์˜์ƒ ์ฝ๊ธฐ
img_bone = cv2.imread('img/bone.jpg')
img_rion = cv2.imread('img/rion.jpg')

# ----------img resize---------------------
img_rion = cv2.resize(img_rion, dsize = (728, 607))

# ์ž…๋ ฅ ์˜์ƒ๊ณผ ๊ฐ™์€ ํฌ๊ธฐ์˜ ๊ฒฐ๊ณผ ์˜์ƒ ์ค€๋น„
img_comp = np.zeros_like(img_bone)

# ์—ฐ์‚ฐ์— ํ•„์š”ํ•œ ์ขŒํ‘œ ๊ณ„์‚ฐ
height, width = img_bone.shape[:2]
middle = width//2                             # ์˜์ƒ์˜ ์ค‘์•™ ์ขŒํ‘œ
alpha_width = width * alpha_width_rate // 100 # ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ ๋ฒ”์œ„
start = middle - alpha_width//2               # ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ ์‹œ์ž‘ ์ง€์ 
step = 100/alpha_width                        # ์•ŒํŒŒ ๊ฐ’ ๊ฐ„๊ฒฉ

# ์ž…๋ ฅ ์˜์ƒ์˜ ์ ˆ๋ฐ˜์”ฉ ๋ณต์‚ฌํ•ด์„œ ๊ฒฐ๊ณผ ์˜์ƒ์— ํ•ฉ์„ฑ
img_comp[:, :middle, : ] = img_bone[:, :middle, :].copy()
img_comp[:, middle:, :] = img_rion[:, middle:, :].copy()
cv2.imshow('half', img_comp)

# ์•ŒํŒŒ ๊ฐ’์„ ๋ฐ”๊พธ๋ฉด์„œ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ ์ ์šฉ
for i in range(alpha_width+1 ):
    alpha = (100 - step * i) / 100  # ์ฆ๊ฐ ๊ฐ„๊ฒฉ์— ๋”ฐ๋ฅธ ์•ŒํŒŒ ๊ฐ’ (1~0)
    beta = 1 - alpha                # ๋ฒ ํƒ€ ๊ฐ’ (0~1)
    # ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ ์ ์šฉ
    img_comp[:, start+i] = img_bone[:, start+i] * \
                                alpha + img_rion[:, start+i] * beta
    print(i, alpha, beta)
    
cv2.imshow('half bone', img_comp)
cv2.waitKey()
cv2.destroyAllWindows()

ํ•ด๊ณจ๊ณผ ์‚ฌ์ž์˜ ํ•ฉ์„ฑ

- ์•ŒํŒŒ๊ฐ’ ์กฐ์ •ํ•ด์„œ ๋ฐ˜์ชฝ์„ ํ•ฉ์„ฑํ–ˆ๋‹ค

- ๋งค์šฐ ๋งŒ์กฑ์Šค๋Ÿฝ๊ฒŒ ํ•ฉ์„ฑ์ด ๋˜์–ด์„œ ๋ฟŒ๋“ฏ ^^

- ์ด๊ฒƒ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฏธ์ง€ ํฌ๊ธฐ์™€ ์ฐจ์› ๋˜‘๊ฐ™์ด ํ•ด์ค˜์•ผ ํ•จ

 

 

 

 

3. ์›€์ง์ž„ ๊ฐ์ง€ CCTV ๋งŒ๋“ค๊ธฐ ์‹ค์Šต

: ๋ชจ์…˜ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ „ํ›„ ์˜์ƒ์˜ ์ฐจ์ด ๊ตฌํ•˜๋ฉด ๋œ๋‹ค

: ์„ธ ๊ฐœ์˜ ํ”„๋ ˆ์ž„ a, b, c๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์–ป์–ด์„œ a์™€ b์˜ ์ฐจ์ด ๊ทธ๋ฆฌ๊ณ  b์™€ c์˜ ์ฐจ์ด๊ฐ€ ๋ชจ๋‘ ๋ฐœ๊ฒฌ๋˜๋Š” ๊ฒฝ์šฐ!

์›€์ง์ž„์ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋‹จ

# ๋ชจ์…˜ ๊ฐ์ง€ CCTV 
import cv2
import numpy as np

# ๊ฐ๋„ ์„ค์ •(์นด๋ฉ”๋ผ ํ’ˆ์งˆ์— ๋”ฐ๋ผ ์กฐ์ • ํ•„์š”)
thresh = 35    # ๋‹ฌ๋ผ์ง„ ํ”ฝ์…€ ๊ฐ’ ๊ธฐ์ค€์น˜ ์„ค์ •
max_diff = 10   # ๋‹ฌ๋ผ์ง„ ํ”ฝ์…€ ๊ฐฏ์ˆ˜ ๊ธฐ์ค€์น˜ ์„ค์ •

# ์นด๋ฉ”๋ผ ์บก์…˜ ์žฅ์น˜ ์ค€๋น„
a, b, c = None, None, None
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)      # ํ”„๋ ˆ์ž„ ํญ์„ 480์œผ๋กœ ์„ค์ • 
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)     # ํ”„๋ ˆ์ž„ ๋†’์ด๋ฅผ 320์œผ๋กœ ์„ค์ •

if cap.isOpened():
    ret, a = cap.read()         # a ํ”„๋ ˆ์ž„ ์ฝ๊ธฐ
    ret, b = cap.read()         # b ํ”„๋ ˆ์ž„ ์ฝ๊ธฐ

    while ret:
        ret, c = cap.read()     # c ํ”„๋ ˆ์ž„ ์ฝ๊ธฐ
        draw = c.copy()         # ์ถœ๋ ฅ ์˜์ƒ์— ์‚ฌ์šฉํ•  ๋ณต์ œ๋ณธ
        if not ret:
            break
        
        # 3๊ฐœ์˜ ์˜์ƒ์„ ๊ทธ๋ ˆ์ด ์Šค์ผ€์ผ๋กœ ๋ณ€๊ฒฝ
        a_gray = cv2.cvtColor(a, cv2.COLOR_BGR2GRAY)
        b_gray = cv2.cvtColor(b, cv2.COLOR_BGR2GRAY)
        c_gray = cv2.cvtColor(c, cv2.COLOR_BGR2GRAY)

        # a-b, b-c ์ ˆ๋Œ€ ๊ฐ’ ์ฐจ ๊ตฌํ•˜๊ธฐ 
        diff1 = cv2.absdiff(a_gray, b_gray)
        diff2 = cv2.absdiff(b_gray, c_gray)

        # ์Šค๋ ˆ์‹œํ™€๋“œ๋กœ ๊ธฐ์ค€์น˜ ์ด๋‚ด์˜ ์ฐจ์ด๋Š” ๋ฌด์‹œ
        ret, diff1_t = cv2.threshold(diff1, thresh, 255, cv2.THRESH_BINARY)
        ret, diff2_t = cv2.threshold(diff2, thresh, 255, cv2.THRESH_BINARY)

        # ๋‘ ์ฐจ์ด์— ๋Œ€ํ•ด์„œ AND ์—ฐ์‚ฐ, ๋‘ ์˜์ƒ์˜ ์ฐจ์ด๊ฐ€ ๋ชจ๋‘ ๋ฐœ๊ฒฌ๋œ ๊ฒฝ์šฐ
        diff = cv2.bitwise_and(diff1_t, diff2_t)

        # ์—ด๋ฆผ ์—ฐ์‚ฐ์œผ๋กœ ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ ---โ‘ 
        k = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))
        diff = cv2.morphologyEx(diff, cv2.MORPH_OPEN, k)

        # ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒํ•œ ํ”ฝ์…€์ด ๊ฐฏ์ˆ˜ ํŒ๋‹จ ํ›„ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
        diff_cnt = cv2.countNonZero(diff)
        if diff_cnt > max_diff:
            nzero = np.nonzero(diff)  # 0์ด ์•„๋‹Œ ํ”ฝ์…€์˜ ์ขŒํ‘œ ์–ป๊ธฐ(y[...], x[...])
            cv2.rectangle(draw, (min(nzero[1]), min(nzero[0])), \
                                (max(nzero[1]), max(nzero[0])), (0,255,0), 2)
            cv2.putText(draw, "Motion Detected", (10,30), \
                                cv2.FONT_HERSHEY_DUPLEX, 0.5, (0,0,255))
        
        # ์ปฌ๋Ÿฌ ์Šค์ผ€์ผ ์˜์ƒ๊ณผ ์Šค๋ ˆ์‹œํ™€๋“œ ์˜์ƒ์„ ํ†ตํ•ฉํ•ด์„œ ์ถœ๋ ฅ
        stacked = np.hstack((draw, cv2.cvtColor(diff, cv2.COLOR_GRAY2BGR)))
        cv2.imshow('motion sensor',stacked )

        # ๋‹ค์Œ ๋น„๊ต๋ฅผ ์œ„ํ•ด ์˜์ƒ ์ˆœ์„œ ์ •๋ฆฌ
        a = b
        b = c
        
        if cv2.waitKey(1) & 0xFF == 27:
            break

์›€์ง์ด๋Š” ๋‚ด์† ํฌ์ฐฉ!

- ์ฒ˜์Œ์— ์›€์ง์ž„์„ ๊ฐ์ง€ ๋ชปํ•ด์„œ ๊ธฐ์ค€์น˜๋ฅผ ์ข€๋” ๋†’์˜€์Œ

- ๋†’์—ฌ์„œ ๊ทธ๋Ÿฐ์ง€, ์•„๋‹˜ ๋‚ด๊ฐ€ ์ฒ˜์Œ์— ์ œ๋Œ€๋กœ ์•ˆํ”๋“ค์—ˆ๋Š”์ง€ ํŠผ ์ˆ˜์ •ํ•˜๋‹ˆ๊นŒ ์›€์ง์ž„์ด ์žกํžŒ๋‹ค

- ์™• ์‹ ๊ธฐํ•˜๋‹ค

 

 

 

 

 

 

 

์˜ค๋Š˜์€ ์‹ ๊ธฐํ•œ๊ฑฐ

์™• ๋งˆ๋‹ˆํ•จ ><

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