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

[v0.11]์˜์ƒ์ฒ˜๋ฆฌ_์ด๋ฏธ์ง€ ์—ฐ์‚ฐ (ํ•ฉ์„ฑ, ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ, ๋งˆ์Šคํ‚น) ๋ณธ๋ฌธ

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

[v0.11]์˜์ƒ์ฒ˜๋ฆฌ_์ด๋ฏธ์ง€ ์—ฐ์‚ฐ (ํ•ฉ์„ฑ, ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ, ๋งˆ์Šคํ‚น)

์ง•์ง•์•ŒํŒŒ์นด 2022. 1. 2. 16:07
728x90
๋ฐ˜์‘ํ˜•

220102 ์ž‘์„ฑ

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

https://bkshin.tistory.com/entry/OpenCV-9-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%B0%EC%82%B0?category=1148027 

 

OpenCV - 9. ์ด๋ฏธ์ง€ ์—ฐ์‚ฐ (ํ•ฉ์„ฑ, ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ, ๋งˆ์Šคํ‚น)

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

bkshin.tistory.com

 

 

 

 

1. ์ด๋ฏธ์ง€ ์—ฐ์‚ฐ

: ํ•œ ํ”ฝ์…€์ด ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์˜ ๋ฒ”์œ„๋Š” 0~255

 

cv2.add(src1, src2, dest, mask, dtype)

: src1๊ณผ src2 ๋”ํ•˜๊ธฐ

- src1 : ์ฒซ ๋ฒˆ์งธ ์ž…๋ ฅ ์ด๋ฏธ์ง€

- src2 : ๋‘ ๋ฒˆ์งธ ์ž…๋ ฅ ์ด๋ฏธ์ง€

- dest(optional) : ์ถœ๋ ฅ ์˜์ƒ

- mask(optional) : mask ๊ฐ’์ด 0์ด ์•„๋‹Œ ํ”ฝ์…€๋งŒ ์—ฐ์‚ฐ

- dtype(optional) : ์ถœ๋ ฅ ๋ฐ์ดํ„ฐ ํƒ€์ž…(dtype)

 

cv2.subtract(src1, src2, dest, mask, dtype)

: src1์—์„œ src2 ๋นผ๊ธฐ

- cv2.add()์™€ ํŒŒ๋ผ๋ฏธํ„ฐ ๋™์ผ

 

cv2.multiply(src1, src2, dest, scale, dtype)

: src1๊ณผ src2 ๊ณฑํ•˜๊ธฐ

- scale(optional) : ์—ฐ์‚ฐ ๊ฒฐ๊ณผ์— ์ถ”๊ฐ€ ์—ฐ์‚ฐํ•  ๊ฐ’

 

cv2.divide(src1, src2, dest, scale, dtype)

: src1์„ src2๋กœ ๋‚˜๋ˆ„๊ธฐ

- cv2.multiply()์™€ ํŒŒ๋ผ๋ฏธํ„ฐ ๋™์ผ

# ์ด๋ฏธ์ง€์˜ ์‚ฌ์น™ ์—ฐ์‚ฐ
import cv2
import numpy as np

# ---โ‘  ์—ฐ์‚ฐ์— ์‚ฌ์šฉํ•  ๋ฐฐ์—ด ์ƒ์„ฑ
a = np.uint8([[200, 50]]) 
b = np.uint8([[100, 100]])

#---โ‘ก NumPy ๋ฐฐ์—ด ์ง์ ‘ ์—ฐ์‚ฐ
add1 = a + b
sub1 = a - b
mult1 = a * 2
div1 = a / 3

# ---โ‘ข OpenCV API๋ฅผ ์ด์šฉํ•œ ์—ฐ์‚ฐ
add2 = cv2.add(a, b)
sub2 = cv2.subtract(a, b)
mult2 = cv2.multiply(a , 2)
div2 = cv2.divide(a, 3)

#---โ‘ฃ ๊ฐ ์—ฐ์‚ฐ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
print("numpy-----OpenCV API")
print(add1, add2)
print(sub1, sub2)
print(mult1, mult2)
print(div1, div2)

numpy--------------OpenCV API
[[ 44 150]]             [[255 150]]
[[100 206]]             [[100   0]]
[[144 100]]             [[255 100]]
[[66.66666667 16.66666667]] [[67 17]]

 

1) numpy

add1 :

[ 200 + 100 = 300 -> 300 - 255 - 1 = 44 , 50 + 100 = 150]

unit8 ํƒ€์ž…์˜ ๊ฐ’์˜ ๋ฒ”์œ„๋Š” 0 ~ 255์ด๋ฏ€๋กœ 255๋ฅผ ๋„˜๋Š” ๊ฐ’์€ ๋‹ค์‹œ 0๋ถ€ํ„ฐ ์นด์šดํŒ…

sub1 : 

[ 200 - 100 = 100, 50 - 100 = -50 -> -50 + 255 + 1 = 206 ]

mult1 :

[ 200 * 2 = 400 -> 400 - 255 - 1 = 144, 50 * 2= 100 ]

div1 :

[ 200 / 3 = 66.666, 50 / 3 = 16.6666]

 

2) OpenCV API

add2 :

[ 200 + 100 = 300 -> 255 , 50 + 100 = 150 ]

cv2.add() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋ฉด 255๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๋ชจ๋“  ๊ฐ’์€ 255๋กœ ๋ฐ˜ํ™˜

sub2 : 

[ 200 - 100 = 100, 50 - 100 = -50 -> 0 ]

OpenCV์—์„œ๋Š” 0๋ณด๋‹ค ์ž‘์€ ๋ชจ๋“  ๊ฐ’์„ 0์œผ๋กœ ๋ฐ˜ํ™˜

mult2 :

[ 200 * 2 = 400 -> 255, 50 * 2= 100 ]

div2 :

[ 200 / 3 = 66.666 -> 67, 50 / 3 = 16.6666 -> 17]

๊ณฑํ•˜๊ธฐ์™€ ๋‚˜๋ˆ„๊ธฐ ์—ฐ์‚ฐ๋„ 255๋ฅผ ์ดˆ๊ณผํ•˜๊ฑฐ๋‚˜ 0๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๊ฐ–์ง€ ์•Š๊ณ , ์†Œ์ˆ˜์ ์€ ๊ฐ–์ง€ ์•Š์Œ

 

+) mask์˜ ๊ฐ’

# mask์™€ ๋ˆ„์  ํ• ๋‹น ์—ฐ์‚ฐ
import cv2
import numpy as np

#---โ‘  ์—ฐ์‚ฐ์— ์‚ฌ์šฉํ•  ๋ฐฐ์—ด ์ƒ์„ฑ
a = np.array([[1, 2]], dtype=np.uint8)
b = np.array([[10, 20]], dtype=np.uint8)
#---โ‘ก 2๋ฒˆ์งธ ์š”์†Œ๊ฐ€ 0์ธ ๋งˆ์Šคํฌ ๋ฐฐ์—ด ์ƒ์„ฑ 
mask = np.array([[1, 0]], dtype=np.uint8)

#---โ‘ข ๋ˆ„์  ํ• ๋‹น๊ณผ์˜ ๋น„๊ต ์—ฐ์‚ฐ
c1 = cv2.add(a, b, None, mask)
print(c1)
c2 = cv2.add(a, b, b.copy(), mask)
print(c2, b)
c3 = cv2.add(a, b, b, mask)
print(c3, b)

mask์˜ ๊ฐ’

[[11  0]]
[[11 20]] [[10 20]]
[[11 20]] [[11 20]]

 

1) cv2.add(a, b, None, mask)

[ 1 + 10 = 11, 0]

๋ฐฐ์—ด์ด [1, 0]์ธ mask๋ฅผ ์ง€์ • -> mask ๊ฐ’์ด 0์ด ์•„๋‹Œ ์œ„์น˜์— ์žˆ๋Š” ํ”ฝ์…€๋งŒ ์—ฐ์‚ฐ

 

2) cv2.add(a, b, b.copy(), mask)

[ 1 + 10 = 11, 0]    [ 10, 20 ]

 

3) cv2.add(a, b, b, mask)

[ 1 + 10 = 11, 0]    [ 11, 20 ]

a์™€ b์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋งŒ ๋”ํ•˜์—ฌ b์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ์— ์ ์šฉ

 

 

 

2. ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ

: numpy์˜ ํ•ฉ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ํ”ฝ์…€ ๊ฐ’์ด 255๊ฐ€ ๋„˜๋Š” ๊ฒฝ์šฐ ์ดˆ๊ณผ ๊ฐ’๋งŒ์„ ๊ฐ€์ง -> ์ด๋ฏธ์ง€๊ฐ€ ๊ฒ€์€์ƒ‰์— ๊ฐ€๊น๊ฒŒ

: cv2.add() ์—ฐ์‚ฐ์„ ํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„์˜ ํ”ฝ์…€ ๊ฐ’์ด 255 ๊ฐ€๊นŒ์ด ๋ชฐ๋ฆฌ๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒ -> ์˜์ƒ์ด ์ „์ฒด์ ์œผ๋กœ ํ•˜์–—๊ฒŒ 

# ์ด๋ฏธ์ง€ ๋‹จ์ˆœ ํ•ฉ์„ฑ

import cv2
import numpy as np
import matplotlib.pylab as plt

# ---โ‘  ์—ฐ์‚ฐ์— ์‚ฌ์šฉํ•  ์ด๋ฏธ์ง€ ์ฝ๊ธฐ
img1 = cv2.imread('img/wing_wall.jpg')
img2 = cv2.imread('img/yate.jpg')

# ---โ‘ก ์ด๋ฏธ์ง€ ๋ง์…ˆ
img3 = img1 + img2  # ๋”ํ•˜๊ธฐ ์—ฐ์‚ฐ
img4 = cv2.add(img1, img2) # OpenCV ํ•จ์ˆ˜

imgs = {'img1':img1, 'img2':img2, 'img1+img2': img3, 'cv.add(img1, img2)': img4}

# ---โ‘ข ์ด๋ฏธ์ง€ ์ถœ๋ ฅ
for i, (k, v) in enumerate(imgs.items()):
    plt.subplot(2,2, i + 1)
    plt.imshow(v[:,:,::-1])
    plt.title(k)
    plt.xticks([]); plt.yticks([])

plt.show()

numpy ์™€ opencv ์˜ ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ

 

-> numpy ๋Š” ๊ฑฐ๋ญ‡ํ•˜๊ฒŒ

-> openCV๋Š” ํ•˜์–—๊ฒŒ

 

+) ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ

: ๋‘ ์ด๋ฏธ์ง€๋ฅผ ์ œ๋Œ€๋กœ ํ•ฉ์„ฑํ•˜๋ ค๋ฉด ๊ฐ๊ฐ์˜ ์ด๋ฏธ์ง€์— ๊ฐ€์ค‘์น˜๋ฅผ ์ฃผ๊ณ  ํ•ฉํ•ด์•ผ ํ•œ๋‹ค

: ๊ฐ€์ค‘์น˜๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๊ฐ€์ค‘์น˜๋ฅผ ์•ŒํŒŒ(alpha) ๊ฐ’

: ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€ ์•ŒํŒŒ(alpha)๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•ฉ์„ฑ ๊ฒฐ๊ณผ ํ”ฝ์…€ ๊ฐ’ g(x)๋ฅผ ๊ตฌํ•˜๋Š” ๊ณต์‹

๊ฐ€์ค‘์น˜ alpha ๊ณต์‹

cv2.addWeight(img1, alpha, img2, beta, gamma)
- img1, img2 : ํ•ฉ์„ฑํ•  ๋‘ ์ด๋ฏธ์ง€
- alpha : img1์— ์ง€์ •ํ•  ๊ฐ€์ค‘์น˜(์•ŒํŒŒ ๊ฐ’)
- beta : img2์— ์ง€์ •ํ•  ๊ฐ€์ค‘์น˜, ํ”ํžˆ (1-alpha) ์ ์šฉ
- gamma : ์—ฐ์‚ฐ ๊ฒฐ๊ณผ์— ๊ฐ€๊ฐํ•  ์ƒ์ˆ˜, ํ”ํžˆ 0 ์ ์šฉ

# ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ
import cv2
import numpy as np

alpha = 0.5 # ํ•ฉ์„ฑ์— ์‚ฌ์šฉํ•  ์•ŒํŒŒ ๊ฐ’

#---โ‘  ํ•ฉ์„ฑ์— ์‚ฌ์šฉํ•  ์˜์ƒ ์ฝ๊ธฐ
img1 = cv2.imread('img/wing_wall.jpg')
img2 = cv2.imread('img/yate.jpg')

# ---โ‘ก NumPy ๋ฐฐ์—ด์— ์ˆ˜์‹์„ ์ง์ ‘ ์—ฐ์‚ฐํ•ด์„œ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ ์ ์šฉ
blended = img1 * alpha + img2 * (1-alpha)
blended = blended.astype(np.uint8) # ์†Œ์ˆ˜์  ๋ฐœ์ƒ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•จ
cv2.imshow('img1 * alpha + img2 * (1-alpha)', blended)

# ---โ‘ข addWeighted() ํ•จ์ˆ˜๋กœ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ ์ ์šฉ
dst = cv2.addWeighted(img1, alpha, img2, (1-alpha), 0) 
cv2.imshow('cv2.addWeighted', dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

numpy์™€ cv2.addWeight ํ•จ์ˆ˜ ํ™œ์šฉํ•œ ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ

 

+) ํŠธ๋ž™๋ฐ”์ด์šฉ

# ํŠธ๋ž™๋ฐ”๋กœ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ
import cv2
import numpy as np

win_name = 'Alpha blending'     # ์ฐฝ ์ด๋ฆ„
trackbar_name = 'fade'          # ํŠธ๋ ‰๋ฐ” ์ด๋ฆ„

# ---โ‘  ํŠธ๋ ‰๋ฐ” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜
def onChange(x):
    alpha = x/100
    dst = cv2.addWeighted(img1, 1-alpha, img2, alpha, 0) 
    cv2.imshow(win_name, dst)


# ---โ‘ก ํ•ฉ์„ฑ ์˜์ƒ ์ฝ๊ธฐ
img1 = cv2.imread('img/wing_wall.jpg')
img2 = cv2.imread('img/yate.jpg')

# ---โ‘ข ์ด๋ฏธ์ง€ ํ‘œ์‹œ ๋ฐ ํŠธ๋ ‰๋ฐ” ๋ถ™์ด๊ธฐ
cv2.imshow(win_name, img1)
cv2.createTrackbar(trackbar_name, win_name, 0, 100, onChange)

cv2.waitKey()
cv2.destroyAllWindows()

ํŠธ๋ž™๋ฐ”๋ฅผ ์ด์šฉํ•ด alpha ๊ฐ’ ์ž์œ ๋กญ๊ฒŒ ํ™œ์šฉํ•˜๊ธฐ

 

 

 

 

3. ๋น„ํŠธ์™€์ด์ฆˆ ์—ฐ์‚ฐ

: ๋‘ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์„ฑํ•  ๋•Œ ํŠน์ • ์˜์—ญ๋งŒ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์˜์—ญ๋งŒ ์ œ์™ธํ•˜๋Š” ๋“ฑ์˜ ์„ ๋ณ„์ ์ธ ์—ฐ์‚ฐ

 

cv2.bitwise_and(img1, img2, mask=None)

: ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด AND ์—ฐ์‚ฐ

 

cv2.bitwise_or(img1, img2, mask=None)

: ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด OR ์—ฐ์‚ฐ

 

cv2.bitwise_xor(img1, img2, mask=None)

: ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด XOR ์—ฐ์‚ฐ

 

cv2.bitwise_not(img1, img2, mask=None)

: ๊ฐ ํ”ฝ์…€์— ๋Œ€ํ•ด NOT ์—ฐ์‚ฐ

- img1, img2๋Š” ์—ฐ์‚ฐ์„ ํ•  ์ด๋ฏธ์ง€

- ๋‘ ์ด๋ฏธ์ง€๋Š” ๋™์ผํ•œ shape๋ฅผ ๊ฐ€์ง€๊ธฐ

- mask๋Š” 0์ด ์•„๋‹Œ ํ”ฝ์…€๋งŒ ์—ฐ์‚ฐ

์ถœ์ฒ˜ :&nbsp;https://antakkaum.tistory.com/593

# ๋น„ํŠธ์™€์ด์ฆˆ ์—ฐ์‚ฐ
import numpy as np, cv2
import matplotlib.pylab as plt

#--โ‘  ์—ฐ์‚ฐ์— ์‚ฌ์šฉํ•  ์ด๋ฏธ์ง€ ์ƒ์„ฑ
img1 = np.zeros( ( 200,400), dtype=np.uint8)
img2 = np.zeros( ( 200,400), dtype=np.uint8)
img1[:, :200] = 255         # ์™ผ์ชฝ์€ ํฐ์ƒ‰(255), ์˜ค๋ฅธ์ชฝ์€ ๊ฒ€์ •์ƒ‰(0)
img2[100:200, :] = 255      # ์œ„์ชฝ์€ ๊ฒ€์ •์ƒ‰(0), ์•„๋ž˜์ชฝ์€ ํฐ์ƒ‰(255)

#--โ‘ก ๋น„ํŠธ์™€์ด์ฆˆ ์—ฐ์‚ฐ
bitAnd = cv2.bitwise_and(img1, img2)
bitOr = cv2.bitwise_or(img1, img2)
bitXor = cv2.bitwise_xor(img1, img2)
bitNot = cv2.bitwise_not(img1)

#--โ‘ข Plot์œผ๋กœ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
imgs = {'img1':img1, 'img2':img2, 'and':bitAnd, 
          'or':bitOr, 'xor':bitXor, 'not(img1)':bitNot}
for i, (title, img) in enumerate(imgs.items()):
    plt.subplot(3,2,i+1)
    plt.title(title)
    plt.imshow(img, 'gray')
    plt.xticks([]); plt.yticks([])

plt.show()

๋น„ํŠธ ์—ฐ์‚ฐ์ž

 

1) and

: 1 + 0 = 0    : 1 + 0 = 0

: 1 + 1 = 1    : 1 + 0 = 0

 

2) or

: 1 + 0 = 1    : 0 + 0 = 0

: 1 + 1 = 1    : 0 + 1 = 1

 

3) xor

: 1 + 0 = 1    : 0 + 0 = 0

: 1 + 1 = 0    : 0 + 1 = 1

 

4) not (img1)

: img1๊ณผ ๋ฐ˜๋Œ€๋กœ

 

 

+) bitwize๋กœ ์›ํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ๋–ผ๊ธฐ

# bitwise_and ์—ฐ์‚ฐ์œผ๋กœ ๋งˆ์Šคํ‚นํ•˜๊ธฐ

import numpy as np, cv2
import matplotlib.pylab as plt

#--โ‘  ์ด๋ฏธ์ง€ ์ฝ๊ธฐ
img = cv2.imread('img/lena.png')

#--โ‘ก ๋งˆ์Šคํฌ ๋งŒ๋“ค๊ธฐ
mask = np.zeros_like(img)
cv2.circle(mask, (260,210), 100, (255,255,255), -1)
#cv2.circle(๋Œ€์ƒ์ด๋ฏธ์ง€, (์›์ x, ์›์ y), ๋ฐ˜์ง€๋ฆ„, (์ƒ‰์ƒ), ์ฑ„์šฐ๊ธฐ)

#--โ‘ข ๋งˆ์Šคํ‚น
masked = cv2.bitwise_and(img, mask)

#--โ‘ฃ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
cv2.imshow('original', img)
cv2.imshow('mask', mask)
cv2.imshow('masked', masked)
cv2.waitKey()
cv2.destroyAllWindows()

bitwise_and ํ•œ ์ด๋ฏธ์ง€

-> AND ์—ฐ์‚ฐ์€ True(0์ด ์•„๋‹Œ ๊ฐ’)์™€ True(0์ด ์•„๋‹Œ ๊ฐ’)๊ฐ€ ํ•ฉํ•ด์ง„ ๋ถ€๋ถ„๋งŒ True๊ฐ€ ์ถœ๋ ฅ

 

 

 

 

4. ๋‘ ์ด๋ฏธ์ง€์˜ ์ฐจ์ด

diff = cv2.absdiff(img1, img2)
- img1, img2 : ์ž…๋ ฅ ์ด๋ฏธ์ง€
- diff : ๋‘ ์ด๋ฏธ์ง€์˜ ์ฐจ์˜ ์ ˆ๋Œ€ ๊ฐ’

# ๋‘ ์ด๋ฏธ์ง€์˜ ์ฐจ๋ฅผ ํ†ตํ•ด ๋„๋ฉด์˜ ์ฐจ์ด ์ฐพ์•„๋‚ด๊ธฐ
import numpy as np, cv2

#--โ‘  ์—ฐ์‚ฐ์— ํ•„์š”ํ•œ ์˜์ƒ์„ ์ฝ๊ณ  ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ๋กœ ๋ณ€ํ™˜
img1 = cv2.imread('img/robot_arm1.jpg')
img2 = cv2.imread('img/robot_arm0.jpg')
img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

#--โ‘ก ๋‘ ์˜์ƒ์˜ ์ ˆ๋Œ€๊ฐ’ ์ฐจ ์—ฐ์‚ฐ
diff = cv2.absdiff(img1_gray, img2_gray)

#--โ‘ข ์ฐจ ์˜์ƒ์„ ๊ทน๋Œ€ํ™” ํ•˜๊ธฐ ์œ„ํ•ด ์“ฐ๋ ˆ์‹œํ™€๋“œ ์ฒ˜๋ฆฌ ๋ฐ ์ปฌ๋Ÿฌ๋กœ ๋ณ€ํ™˜
_, diff = cv2.threshold(diff, 1, 255, cv2.THRESH_BINARY)
diff_red = cv2.cvtColor(diff, cv2.COLOR_GRAY2BGR)
diff_red[:,:,2] = 0

#--โ‘ฃ ๋‘ ๋ฒˆ์งธ ์ด๋ฏธ์ง€์— ๋ณ€ํ™” ๋ถ€๋ถ„ ํ‘œ์‹œ
spot = cv2.bitwise_xor(img2, diff_red)

#--โ‘ค ๊ฒฐ๊ณผ ์˜์ƒ ์ถœ๋ ฅ
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('diff', diff)
cv2.imshow('spot', spot)
cv2.waitKey()
cv2.destroyAllWindows()

๋‘ ์ด๋ฏธ์ง€์˜ ์ฐจ์ด ์ฐพ์•„๋‚ด๊ธฐ

- ํšŒ์ƒ‰์กฐ๋กœ ๋ณ€ํ™˜๋œ ๋‘ ์ด๋ฏธ์ง€์˜ ์ฐจ์ด ๊ตฌํ•˜๊ธฐ

- ์ฐจ์ด๋ฅผ ๋šœ๋ ทํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด cv2.threshold() ์‚ฌ์šฉํ•˜์—ฌ 1๋ณด๋‹ค ํฐ ๊ฐ’์€ 255๋กœ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ 0์œผ๋กœ ๋ฐ”๊พธ๊ธฐ

- ์ƒ‰์ƒ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด cv2.cvtColor() ์‚ฌ์šฉํ•˜์—ฌ ์ƒ‰์ƒ ์Šค์ผ€์ผ์˜ ์ฐจ์› ๋ณ€๊ฒฝ ํ›„ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ

- cv2.bitwise_xor() ์œผ๋กœ ์ฐจ์ด ์žˆ๋Š” ๊ณณ์ด ๋นจ๊ฐ„ ์˜์—ญ์œผ๋กœ ํ‘œ์‹œ

 

 

 

5. ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ๊ณผ ๋งˆ์Šคํ‚น

: ๋‘ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์„ฑ -> ์ผ๋ฐ˜์ ์œผ๋กœ ํ•˜๋‚˜์˜ ์ด๋ฏธ์ง€๋Š” ๋ฐฐ๊ฒฝ๊ณผ ์ „๊ฒฝ(๋ฐฐ๊ฒฝ์ด ์•„๋‹Œ ์‹ค์ œ ์ด๋ฏธ์ง€)

: BGRA ์ƒ‰์ƒ ํ˜•์‹์œผ๋กœ ํ‘œํ˜„ํ•  ๋•Œ,

๋ฐฐ๊ฒฝ์€ A(์•ŒํŒŒ, alpha)๊ฐ€ 0์ด๊ณ , ์ „๊ฒฝ์€ A๊ฐ€ 255 ( A๊ฐ€ 0์ด๋ฉด ํˆฌ๋ช…ํ•˜๊ณ , 255๋ฉด ๋ถˆํˆฌ๋ช… )

# ํˆฌ๋ช… ๋ฐฐ๊ฒฝ PNG ํŒŒ์ผ์„ ์ด์šฉํ•œ ํ•ฉ์„ฑ

import cv2
import numpy as np

#--โ‘  ํ•ฉ์„ฑ์— ์‚ฌ์šฉํ•  ์˜์ƒ ์ฝ๊ธฐ, ์ „๊ฒฝ ์˜์ƒ์€ 4์ฑ„๋„ png ํŒŒ์ผ
img_fg = cv2.imread('img/opencv_logo.png', cv2.IMREAD_UNCHANGED)
img_bg = cv2.imread('img/clover.jpg')

#--โ‘ก ์•ŒํŒŒ์ฑ„๋„์„ ์ด์šฉํ•ด์„œ ๋งˆ์Šคํฌ์™€ ์—ญ๋งˆ์Šคํฌ ์ƒ์„ฑ
_, mask = cv2.threshold(img_fg[:,:,3], 1, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

#--โ‘ข ์ „๊ฒฝ ์˜์ƒ ํฌ๊ธฐ๋กœ ๋ฐฐ๊ฒฝ ์˜์ƒ์—์„œ ROI ์ž˜๋ผ๋‚ด๊ธฐ
img_fg = cv2.cvtColor(img_fg, cv2.COLOR_BGRA2BGR)
h, w = img_fg.shape[:2]
roi = img_bg[10:10+h, 10:10+w ]

#--โ‘ฃ ๋งˆ์Šคํฌ ์ด์šฉํ•ด์„œ ์˜ค๋ ค๋‚ด๊ธฐ
masked_fg = cv2.bitwise_and(img_fg, img_fg, mask=mask)
masked_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)

#--โ‘ฅ ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ
added = masked_fg + masked_bg
img_bg[10:10+h, 10:10+w] = added

cv2.imshow('mask', mask)
cv2.imshow('mask_inv', mask_inv)
cv2.imshow('masked_fg', masked_fg)
cv2.imshow('masked_bg', masked_bg)
cv2.imshow('added', added)
cv2.imshow('result', img_bg)
cv2.waitKey()
cv2.destroyAllWindows()

์ด๋ฏธ์ง€ ํ•ฉ์„ฑ!

- _, mask = cv2.threshod(img_fg[:, :, 3], 1, 255, cv2.THRESH_BINARY)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐฐ๊ฒฝ๊ณผ ์ „๊ฒฝ์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋งˆ์Šคํฌ

- mask_inv = cv2.bitwise_not(mask)์ด๋ฏ€๋กœ mask_inv๋Š” mask์˜ ๋ฐ˜๋Œ€ (์ฆ‰, ๋ฐฐ๊ฒฝ์€ ํฐ์ƒ‰, ์ „๊ฒฝ์€ ๊ฒ€์€์ƒ‰)

 

 

 

+) ์ƒ‰์ƒ ๋ณ„๋กœ ์ถ”์ถœ

cv2.inRange(hsv, lower, upper)

: hsv์˜ ๋ชจ๋“  ๊ฐ’ ์ค‘ lower์™€ upper ๋ฒ”์œ„ ์‚ฌ์ด์— ์žˆ๋Š” ๊ฐ’์€ 255, ๋‚˜๋จธ์ง€ ๊ฐ’์€ 0์œผ๋กœ ๋ณ€ํ™˜

# HSV ์ƒ‰์ƒ์œผ๋กœ ๋งˆ์Šคํ‚น

import cv2
import numpy as np
import matplotlib.pylab as plt

#--โ‘  ํ๋ธŒ ์˜์ƒ ์ฝ์–ด์„œ HSV๋กœ ๋ณ€ํ™˜
img = cv2.imread("img/cube.JPG")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

#--โ‘ก ์ƒ‰์ƒ๋ณ„ ์˜์—ญ ์ง€์ •
blue1 = np.array([90, 50, 50])
blue2 = np.array([120, 255,255])
green1 = np.array([45, 50,50])
green2 = np.array([75, 255,255])
red1 = np.array([0, 50,50])
red2 = np.array([15, 255,255])
red3 = np.array([165, 50,50])
red4 = np.array([180, 255,255])
yellow1 = np.array([20, 50,50])
yellow2 = np.array([35, 255,255])

# --โ‘ข ์ƒ‰์ƒ์— ๋”ฐ๋ฅธ ๋งˆ์Šคํฌ ์ƒ์„ฑ
mask_blue = cv2.inRange(hsv, blue1, blue2)
mask_green = cv2.inRange(hsv, green1, green2)
mask_red = cv2.inRange(hsv, red1, red2)
mask_red2 = cv2.inRange(hsv, red3, red4)
mask_yellow = cv2.inRange(hsv, yellow1, yellow2)

#--โ‘ฃ ์ƒ‰์ƒ๋ณ„ ๋งˆ์Šคํฌ๋กœ ์ƒ‰์ƒ๋งŒ ์ถ”์ถœ
res_blue = cv2.bitwise_and(img, img, mask=mask_blue)
res_green = cv2.bitwise_and(img, img, mask=mask_green)
res_red1 = cv2.bitwise_and(img, img, mask=mask_red)
res_red2 = cv2.bitwise_and(img, img, mask=mask_red2)
res_red = cv2.bitwise_or(res_red1, res_red2)
res_yellow = cv2.bitwise_and(img, img, mask=mask_yellow)

#--โ‘ค ๊ฒฐ๊ณผ ์ถœ๋ ฅ
imgs = {'original': img, 'blue':res_blue, 'green':res_green, 
                            'red':res_red, 'yellow':res_yellow}
for i, (k, v) in enumerate(imgs.items()):
    plt.subplot(2,3, i+1)
    plt.title(k)
    plt.imshow(v[:,:,::-1])
    plt.xticks([]); plt.yticks([])
plt.show()

์ƒ‰์ƒ๋ณ„ ์ด๋ฏธ์ง€

ํ  ์™œ ์ดˆ๋ก์ด ์•ˆ๋˜๋Š”๊ฑฐ์ง•

 

 

 

 

+) ์ƒ‰์ƒ์„ ์ด์šฉํ•œ ๋งˆ์Šคํ‚น ๋ฐฉ์‹์„ ํฌ๋กœ๋งˆํ‚ค(chroma key)

# ํฌ๋กœ๋งˆํ‚ค ๋งˆ์Šคํ‚น๊ณผ ํ•ฉ์„ฑ

import cv2
import numpy as np
import matplotlib.pylab as plt

#--โ‘  ํฌ๋กœ๋งˆํ‚ค ๋ฐฐ๊ฒฝ ์˜์ƒ๊ณผ ํ•ฉ์„ฑํ•  ๋ฐฐ๊ฒฝ ์˜์ƒ ์ฝ๊ธฐ
img1 = cv2.imread('img/sample.jpeg')
img2 = cv2.imread('img/wing_wall.jpg')

#--โ‘ก ROI ์„ ํƒ์„ ์œ„ํ•œ ์ขŒํ‘œ ๊ณ„์‚ฐ
height1, width1 = img1.shape[:2]
height2, width2 = img2.shape[:2]
x = (width2 - width1)//2
y = height2 - height1
w = x + width1
h = y + height1

#--โ‘ข ํฌ๋กœ๋งˆํ‚ค ๋ฐฐ๊ฒฝ ์˜์ƒ์—์„œ ํฌ๋กœ๋งˆํ‚ค ์˜์—ญ์„ 10ํ”ฝ์…€ ์ •๋„๋กœ ์ง€์ •
chromakey = img1[:10, :10, :]
offset = 20

#--โ‘ฃ ํฌ๋กœ๋งˆํ‚ค ์˜์—ญ๊ณผ ์˜์ƒ ์ „์ฒด๋ฅผ HSV๋กœ ๋ณ€๊ฒฝ
hsv_chroma = cv2.cvtColor(chromakey, cv2.COLOR_BGR2HSV)
hsv_img = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)

#--โ‘ค ํฌ๋กœ๋งˆํ‚ค ์˜์—ญ์˜ H๊ฐ’์—์„œ offset ๋งŒํผ ์—ฌ์œ ๋ฅผ ๋‘์–ด์„œ ๋ฒ”์œ„ ์ง€์ •
# offset ๊ฐ’์€ ์—ฌ๋Ÿฌ์ฐจ๋ก€ ์‹œ๋„ ํ›„ ๊ฒฐ์ •
#chroma_h = hsv_chroma[0]
chroma_h = hsv_chroma[:,:,0]
lower = np.array([chroma_h.min()-offset, 100, 100])
upper = np.array([chroma_h.max()+offset, 255, 255])

#--โ‘ฅ ๋งˆ์Šคํฌ ์ƒ์„ฑ ๋ฐ ๋งˆ์Šคํ‚น ํ›„ ํ•ฉ์„ฑ
mask = cv2.inRange(hsv_img, lower, upper)
mask_inv = cv2.bitwise_not(mask)
roi = img2[y:h, x:w]
fg = cv2.bitwise_and(img1, img1, mask=mask_inv)
bg = cv2.bitwise_and(roi, roi, mask=mask)
img2[y:h, x:w] = fg + bg

#--โ‘ฆ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
cv2.imshow('chromakey', img1)
cv2.imshow('added', img2)
cv2.waitKey()
cv2.destroyAllWindows()

๋‚˜์ค‘์— ์ ์ ˆํ•œ ์ƒ‰์ƒ ์„ ํƒ์œผ๋กœ ๋‹ค์‹œ ๋„์ „..!

 

 

 

 

+)  cv2.seamlessClone() ํ•จ์ˆ˜ ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ!

dst = cv2.seamlessClone(src, dst, mask, coords, flags, output)

: ์•ŒํŒŒ ๊ฐ’์ด๋‚˜ ๋งˆ์Šคํฌ๋ฅผ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•„๋„๋จ

: mask๋Š” img1์˜ ์ „์ฒด ์˜์—ญ์„ 255๋กœ ์ฑ„์›Œ์„œ ํ•ด๋‹น ์˜์—ญ ์ „๋ถ€๊ฐ€ ํ•ฉ์„ฑ์˜ ๋Œ€์ƒ์ž„์„ ํ‘œํ˜„


- src : ์ž…๋ ฅ ์ด๋ฏธ์ง€, ์ผ๋ฐ˜์ ์œผ๋กœ ์ „๊ฒฝ
- dst : ๋Œ€์ƒ ์ด๋ฏธ์ง€, ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐฐ๊ฒฝ
- mask : ๋งˆ์Šคํฌ, src์—์„œ ํ•ฉ์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ์˜์—ญ์€ 255, ๋‚˜๋จธ์ง€๋Š” 0
- coords : src๊ฐ€ ๋†“์ด๊ธฐ ์›ํ•˜๋Š” dst์˜ ์ขŒํ‘œ (์ค‘์•™)
- flags : ํ•ฉ์„ฑ ๋ฐฉ์‹

  • ์ž…๋ ฅ ์›๋ณธ์„ ์œ ์ง€ํ•˜๋Š” cv2.NORMAL_CLONE
  • ์ž…๋ ฅ๊ณผ ๋Œ€์ƒ์„ ํ˜ผํ•ฉํ•˜๋Š” cv2.MIXED_CLONE

- output(optional) : ํ•ฉ์„ฑ ๊ฒฐ๊ณผ

# SeamlessClone์„ ํ™œ์šฉํ•œ ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ
import cv2
import numpy as np
import matplotlib.pylab as plt
 
#--โ‘  ํ•ฉ์„ฑ ๋Œ€์ƒ ์˜์ƒ ์ฝ๊ธฐ
img1 = cv2.imread("img/flower1.jpg")
img2= cv2.imread("img/hand.jpg")

#--โ‘ก ๋งˆ์Šคํฌ ์ƒ์„ฑ, ํ•ฉ์„ฑํ•  ์ด๋ฏธ์ง€ ์ „์ฒด ์˜์—ญ์„ 255๋กœ ์…‹ํŒ…
mask = np.full_like(img1, 255)
 
#--โ‘ข ํ•ฉ์„ฑ ๋Œ€์ƒ ์ขŒํ‘œ ๊ณ„์‚ฐ(img2์˜ ์ค‘์•™)
height, width = img2.shape[:2]
center = (width//2, height//2)
 
#--โ‘ฃ seamlessClone ์œผ๋กœ ํ•ฉ์„ฑ 
normal = cv2.seamlessClone(img1, img2, mask, center, cv2.NORMAL_CLONE)
mixed = cv2.seamlessClone(img1, img2, mask, center, cv2.MIXED_CLONE)

#--โ‘ค ๊ฒฐ๊ณผ ์ถœ๋ ฅ
cv2.imshow('normal', normal)
cv2.imshow('mixed', mixed)
cv2.waitKey()
cv2.destroyAllWindows()

cv2.seamlessClone() ํ™œ์šฉ ์ด๋ฏธ์ง€

-> ์™ผ์ชฝ cv2.NORMAL_CLONE ์ผ ๋•Œ๋Š” ๊ฝƒ์€ ์„ ๋ช…ํ•˜์ง€๋งŒ ์ฃผ๋ณ€์˜ ํ”ผ๋ถ€๊ฐ€ ๋‹ค์†Œ ๋ญ‰๊ฐœ์ง

-> ์˜ค๋ฅธ์ชฝ cv2.MIXED_CLONE ์ผ ๋•Œ๋Š” ๊ฝƒ์€ ๋‹ค์†Œ ํ๋ฆฌ์ง€๋งŒ ์ฃผ๋ณ€ ํ”ผ๋ถ€์™€ ์ž˜ ๋งค์นญ์ด ๋˜๊ฒŒ ํ•ฉ์„ฑ

 

 

 

 

 

 

ํ›„. .๊ธธ์—ˆ๋”ฐ

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