๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

AI/Computer Vision

[Computer Vision] ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

728x90
๋ฐ˜์‘ํ˜•
๐Ÿ‘€ ๋ณธ ์˜ˆ์ œ๋Š” Window10์˜ VSCode, Python3.11.0๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

OpenCV๋Š” Computer Vision์— ์žˆ์–ด ๋Œ€์ค‘์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

Python์—์„œ OpenCV์—์„œ ์˜์ƒ์€ Numpy Array๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์–ด, Numpy์˜ ํ–‰๋ ฌ ์—ฐ์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜์ƒ ์ฝ๊ธฐ, ๋ณด๊ธฐ, ์ €์žฅ

OpenCV๋กœ ์˜์ƒ์„ ์ฝ๋Š” ๋ฐฉ๋ฒ•์€ "imread"๋ฅผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

import cv2
img = cv2.imread("<์ด๋ฏธ์ง€ ์ฃผ์†Œ>",flags)
# flags์˜ ์ข…๋ฅ˜
# cv2.IMREAD_COLOR == 1 : ์ด๋ฏธ์ง€๋ฅผ Default ๊ฐ’(BGR)์œผ๋กœ ์ฝ๋Š”๋‹ค.
# cv2.IMREAD_GRAYSCALE == 0 : ์ด๋ฏธ์ง€๋ฅผ GrayScale๋กœ ์ฝ๋Š”๋‹ค.
# cv2.IMREAD_UNCHANCED == -1 : ์ด๋ฏธ์ง€๋ฅผ alpha Channel๊นŒ์ง€ ํฌํ•จ(RGBA)ํ•˜์—ฌ ์ฝ๋Š”๋‹ค.

 

 

์ฝ์–ด์˜จ ์˜์ƒ์„ ๋ณด๋Š” ๋ฐฉ๋ฒ•์€ "imshow"๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ”๋กœ ์ฐฝ์ด ๊บผ์ง€๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

import cv2

img = cv2.imread("test.jpg")

cv2.imshow("color",img) # ์ด๋ฏธ์ง€๋ฅผ ๋„์šฐ๊ธฐ(GPU ํ™˜๊ฒฝ์—์„œ๋งŒ ๊ฐ€๋Šฅ)
cv2.waitKey(0) # ํ‚ค๋ณด๋“œ์˜ ์•„๋ฌด ํ‚ค๋‚˜ ๋ˆ„๋ฅผ ๋•Œ ์ข…๋ฃŒํ•œ๋‹ค.
cv2.destroyAllWindows() # ๋ชจ๋“  ์œˆ๋„์šฐ๋ฅผ ๋‹ซ๋Š”๋‹ค.

 

 

์˜์ƒ์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ "imwrite" ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

import cv2
 
img = cv2.imread("test.jpg",cv2.IMREAD_COLOR)

cv2.imwrite("test.jpg",img)

 

์˜์ƒ ์ œ์–ด

์˜์ƒ์˜ ํฌ๊ธฐ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์˜์ƒ ๊ฐ์ฒด์˜ shape๋ฅผ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.

import cv2
img = cv2.imread("color.jpg")

height,width,channel = img.shape
print(f"์„ธ๋กœ : {height}, ๊ฐ€๋กœ : {width}, ์ฑ„๋„(RGB,GRAY,RGBA) : {channel}")
# ์„ธ๋กœ : 428, ๊ฐ€๋กœ : 428, ์ฑ„๋„(RGB,GRAY,RGBA) : 3

 

 

์˜์ƒ์˜ ์ƒ‰์„ ๋ฐ˜์ „ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์˜์ƒ ๊ฐ์ฒด์— "~"(not) ์—ฐ์‚ฐ์„ ํ•˜๋ฉด๋œ๋‹ค.

import cv2
img1 = cv2.imread("color.jpg")

cv2.imshow("origin",img1)
cv2.imshow("reversed origin",~img1)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด "resize" ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

import cv2
img = cv2.imread("color.jpg")
height,width,channel = img.shape
print(f"์„ธ๋กœ : {height}, ๊ฐ€๋กœ : {width}, ์ฑ„๋„(RGB,GRAY,RGBA) : {channel}")
# ์„ธ๋กœ : 428, ๊ฐ€๋กœ : 428, ์ฑ„๋„(RGB,GRAY,RGBA) : 3

re_img = cv2.resize(img1,(512,512),interpolation=cv2.INTER_LANCZOS4)
# interpilation ์ธ์ž ์ข…๋ฅ˜
# cv2.INTER_NEAREST - ์ตœ๊ทผ๋ฐฉ ์ด์›ƒ ๋ณด๊ฐ„๋ฒ•
# cv2.INTER_LINEAR - ์–‘์„ ํ˜• ๋ณด๊ฐ„๋ฒ•(2x2 ์ด์›ƒ ํ”ฝ์…€ ์ฐธ์กฐ)
# cv2.INTER_CUBIC - 3์ฐจ ํšŒ์„  ๋ณด๊ฐ„๋ฒ•(4x4 ์ด์›ƒ ํ”ฝ์…€ ์ฐธ๋งˆ์ดˆ)
# cv2.INTER_LANCZOS4 - Lanczos ๋ณด๊ฐ„๋ฒ•(8x8 ์ด์›ƒ ํ”ฝ์…€ ์ฐธ์กฐ)
# cv2.INTER_AREA - ์˜์ƒ ์ถ•์†Œ ์‹œ ํšจ๊ณผ์ 

height,width,channel = re_img.shape
print(f"์„ธ๋กœ : {height}, ๊ฐ€๋กœ : {width}, ์ฑ„๋„(RGB,GRAY,RGBA) : {channel}")
# ์„ธ๋กœ : 512, ๊ฐ€๋กœ : 512, ์ฑ„๋„(RGB,GRAY,RGBA) : 3

 

resize๋Š” ์˜์ƒ์˜ scale์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์œผ๋ฏ€๋กœ interpolation์„ ์ž˜ ์„ค์ •ํ•ด์•ผ, ์ด๋ฏธ์ง€ ์†์‹ค์ด ์ ์–ด์ง„๋‹ค.

  • cv2.INTER_NEAREST - ์ตœ๊ทผ๋ฐฉ ์ด์›ƒ ๋ณด๊ฐ„๋ฒ•, ๊ฐ€์žฅ ๋น ๋ฅด๋‚˜ ๊ฐ€์žฅ ํ€„๋ฆฌํ‹ฐ๊ฐ€ ๋–จ์–ด์ง.
  • cv2.INTER_LINEAR - ์–‘์„ ํ˜• ๋ณด๊ฐ„๋ฒ•(2x2 ์ด์›ƒ ํ”ฝ์…€ ์ฐธ์กฐ), ํšจ์œจ์„ฑ์ด ๊ฐ€์žฅ ์ข‹์Œ(์ ๋‹นํžˆ ๋น ๋ฅด๊ณ  ์ ๋‹นํžˆ ์ข‹์€ ๊ฒฐ๊ณผ)
  • cv2.INTER_CUBIC - 3์ฐจ ํšŒ์„  ๋ณด๊ฐ„๋ฒ•(4x4 ์ด์›ƒ ํ”ฝ์…€ ์ฐธ๋งˆ์ดˆ), LINEAR ๋ณด๋‹จ ๋Š๋ฆฌ๋‚˜ ๋” ์ข‹์€ ํ€„๋ฆฌํ‹ฐ
  • cv2.INTER_LANCZOS4 - Lanczos ๋ณด๊ฐ„๋ฒ•(8x8 ์ด์›ƒ ํ”ฝ์…€ ์ฐธ์กฐ), ๊ฐ€์žฅ ๋Š๋ฆฌ๋‚˜ ํ€„๋ฆฌํ‹ฐ๋Š” ์ œ์ผ ์ข‹์Œ
  • cv2.INTER_AREA - ์˜์ƒ ์ถ•์†Œ ์‹œ ํšจ๊ณผ์ , ์˜์—ญ์ ์ธ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•จ.

 

์˜์ƒ์˜ ์ƒ‰์ƒ ๊ณต๊ฐ„์„ ๋ฐ”๊พธ๋ ค๋ฉด "cvtColor"๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

import cv2
img = cv2.imread("test.jpg")
bgr_img = cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
# ์ƒ‰์ƒ ๊ณต๊ฐ„ ๋ณ€๊ฒฝ Flags
# cv2.COLOR_<๊ธฐ์กด๊ณต๊ฐ„>2<๋ณ€๊ฒฝ ๊ณต๊ฐ„>
cv2.imshow("bgr",bgr_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

์ƒ‰์ƒ ๊ณต๊ฐ„ ์ข…๋ฅ˜

  • BGR(Blue-Green-Red) : OpenCV ๊ธฐ๋ณธ ์ปฌ๋Ÿฌ ์ŠคํŽ˜์ด์Šค, ์ปดํ“จํ„ฐ ๋น„์ „ ์ž‘์—…์— ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ.
  • RGB(Red-Green-Blue) : ๋น›์˜ ์‚ผ์›์ƒ‰์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์ปฌ๋Ÿฌ ์ŠคํŽ˜์ด์Šค, ์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์ด๋‚˜ ๋””์Šคํ”Œ๋ ˆ์ด์— ๋งŽ์ด ์‚ฌ์šฉ.
  • Grayscale : ํ‘๋ฐฑ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ˜ธ๋‚˜ ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ปฌ๋Ÿฌ ์ŠคํŽ˜์ด์Šค, ์ฃผ๋กœ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ๋‚˜ ๋ชจ์„œ๋ฆฌ ๊ฒ€์ถœ๋“ฑ์— ์‚ฌ์šฉ.
  • HSV(Hue-Saturation-Value) : ์ƒ‰์ƒ, ์ฑ„๋„, ๋ช…๋„๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ์ปฌ๋Ÿฌ์Šค ํŽ˜์ด์Šค, ์ปฌ๋Ÿฌ ๊ธฐ๋ฐ˜ ๊ฐ์ฒด ๊ฒ€์ถœ์ด๋‚˜ ์ƒ‰์ƒ ํ•„ํ„ฐ๋ง์— ์œ ์šฉํ•จ.

 

 

์˜์ƒ์˜ ์ƒ‰์ƒ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์€ RGB(๋˜๋Š” BGR, RGBA, BGRA)์—์„œ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ์ƒ‰์ƒ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

# ์ƒ‰์ƒ ๋ณ€๊ฒฝ
cv2.imshow("original",img1)
img1[30:40] = [255,0,255] # ์„ธ๋กœ์˜ 30 ~ 39 ์œ„์น˜์˜ ์ƒ‰์„ (255,0,255)๋กœ ๋ณ€๊ฒฝ
img1[:,10:20] = [0,255,0] # ๊ฐ€๋กœ์˜ 10 ~ 19 ์œ„์น˜์˜ ์ƒ‰์„ (0,255,0)๋กœ ๋ณ€๊ฒฝ
cv2.imshow("color change",img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

๋น„๋””์˜ค ์ŠคํŠธ๋ฆผ

Opencv์—์„œ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆผ์„ ์—ฌ๋Š” ๋ฐฉ๋ฒ•์€ "VideoCapture"๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ˆซ์ž๋ฅผ ์ค„ ๊ฒฝ์šฐ ์นด๋ฉ”๋ผ ์˜์ƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋™์˜์ƒ์„ ๋ณด๋ ค๋ฉด ๋™์˜์ƒ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค. 

import cv2

retval = cv2.VideoCapture("v1.mp4",apiPreference=None)
# 0 : ๊ธฐ๋ณธ ์นด๋ฉ”๋ผ
# 1~ : ์žฅ์น˜ ๊ด€๋ฆฌ์ž์— ์—ฐ๊ฒฐ๋œ ์ˆœ์„œ๋Œ€๋กœ
# retval
# ์„ฑ๊ณต ์‹œ True
# ์‹คํŒจ ์‹œ False

# ์นด๋ฉ”๋ผ๊ฐ€ ์—ด๋ ธ๋Š”์ง€ ํ™•์ธ
if not retval.isOpened():
    print("์‹คํŒจ!")
    import sys
    sys.exit()
print("์—ด๊ธฐ ์„ฑ๊ณต")

 

๊ทธ ๋‹ค์Œ์œผ๋กœ VideoCapture ๊ฐ์ฒด์˜ ํ”„๋ ˆ์ž„์„ ๋ฐ›์•„์™€์•ผ ํ•œ๋‹ค. 

ํ”„๋ ˆ์ž„์„ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ์ฒด์˜ read ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

ret,frame = retval.read()
print(ret) # ์˜์ƒ ๋ฐ˜ํ™˜ ์„ฑ๊ณต ์œ ๋ฌด
print(type(frame)) # ์˜์ƒ์˜ ํ”„๋ ˆ์ž„

# ์˜์ƒ ์ถœ๋ ฅ
while True:
    ret,frame = retval.read()
    
    if not ret: # ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์„ ๋ชป๋ฐ›์•„ ์™”์„ ๋•Œ break
        break

    # ์˜์ƒ ์ถœ๋ ฅ
    cv2.imshow("video",frame)

    # ESC ๋ˆ„๋ฅด๋ฉด ๊ฐ•์ œ ์ข…๋ฃŒ
    if cv2.waitKey(10) == 27:
        break

retval.release() # ์‚ฌ์šฉํ•œ ์ž์› ํ•ด์ œ
cv2.destroyAllWindows()

 

 

get ๋ฉ”์„œ๋“œ๋กœ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆผ์˜ ์†์„ฑ์„ ์ฐธ์กฐํ•˜์—ฌ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

import cv2
retval = cv2.VideoCapture("v1.mp4",apiPreference=None)
# ์†์„ฑ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ
# retval.get(<์›ํ•˜๋Š” ์†์„ฑ>)
print(f"Width : {retval.get(cv2.CAP_PROP_FRAME_WIDTH)}")
print(f"Height : {retval.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
print(f"FPS : {retval.get(cv2.CAP_PROP_FPS)}")

 

 

set ๋ฉ”์„œ๋“œ๋กœ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆผ์˜ ์†์„ฑ์„ ์ฐธ์กฐํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

retval = cv2.VideoCapture("v1.mp4",apiPreference=None)
retval.set(cv2.CAP_PROP_FRAME_WIDTH,1024)
retval.set(cv2.CAP_PROP_FRAME_HEIGHT,1024)

728x90
๋ฐ˜์‘ํ˜•