😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[v0.8]μ˜μƒμ²˜λ¦¬_OpenCV_이미지 λ‚΄ κ΄€μ‹¬μ˜μ—­ (ROI) λ³Έλ¬Έ

πŸ‘©‍πŸ’» IoT (Embedded)/Image Processing

[v0.8]μ˜μƒμ²˜λ¦¬_OpenCV_이미지 λ‚΄ κ΄€μ‹¬μ˜μ—­ (ROI)

μ§•μ§•μ•ŒνŒŒμΉ΄ 2021. 12. 30. 01:29
728x90
λ°˜μ‘ν˜•

211230 μž‘μ„±

<λ³Έ λΈ”λ‘œκ·ΈλŠ” 귀퉁이 μ„œμž¬λ‹˜μ˜ λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν•΄μ„œ κ³΅λΆ€ν•˜λ©° μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€>

https://bkshin.tistory.com/entry/OpenCV-6-dd?category=1148027 

 

OpenCV - 6. 이미지 λ‚΄ κ΄€μ‹¬μ˜μ—­(Region of Interest, ROI) ν‘œμ‹œ

이번 ν¬μŠ€νŒ…μ—μ„œλŠ” 이미지 λ‚΄μ—μ„œ 관심 μ˜μ—­(Region of Interest, ROI)을 ν‘œμ‹œν•˜λŠ” 방법에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€. 이번 ν¬μŠ€νŒ… μ—­μ‹œ '파이썬으둜 λ§Œλ“œλŠ” OpenCV ν”„λ‘œμ νŠΈ(μ΄μ„Έμš° μ €)'λ₯Ό μ •λ¦¬ν•œ κ²ƒμž„μ„ 밝

bkshin.tistory.com

 

 

 

1. 관심 μ˜μ–΅ (ROI, Region Of Interest) ν‘œμ‹œν•˜κΈ°

: μ˜μƒ λ‚΄μ—μ„œ 관심이 μžˆλŠ” μ˜μ—­

 

cv2.rectangle(roi, (0,0), (h-1, w-1), (0,255,0))

: νƒœμ–‘ λΆ€λΆ„λ§Œ μŠ¬λΌμ΄μ‹± ν•œ roi μ΄λ―Έμ§€μ˜ (0, 0)λΆ€ν„° (h-1, w-1)κΉŒμ§€ (0, 255, 0) μƒ‰μœΌλ‘œ μ‚¬κ°ν˜•μ„ ν‘œμ‹œ

: (0, 0)은 쒌츑 상단

: (h-1, w-1)은 우츑 ν•˜λ‹¨

=> roi μ΄λ―Έμ§€μ˜ 쒌츑 상단뢀터 우츑 ν•˜λ‹¨κΉŒμ§€λ₯Ό κΌ­μ§“μ μœΌλ‘œ κ°–λŠ” μ‚¬κ°ν˜•μ„ κ·Έλ €μ€€λ‹€

: RGB 값인 (0, 255, 0)은 녹색

# κ΄€μ‹¬μ˜μ—­ ν‘œμ‹œ

import cv2
import numpy as np

img = cv2.imread('img/sun.jpg')

x=320; y=150; w=50; h=50        # roi μ’Œν‘œ
roi = img[y:y+h, x:x+w]         # roi 지정        ---β‘ 

print(roi.shape)                # roi shape, (50,50,3)
cv2.rectangle(roi, (0,0), (h-1, w-1), (0,255,0), 10) # roi 전체에 μ‚¬κ°ν˜• 그리기 ---β‘‘
cv2.imshow("img", img)

key = cv2.waitKey(0)
print(key)
cv2.destroyAllWindows()

ν•΄ ROI μ˜μ—­μ— λ„£κΈ°

 

 

+) νŠΉμ • μ˜μ—­ ν™•λŒ€ 및 볡제

# κ΄€μ‹¬μ˜μ—­ 볡제 및 μƒˆ 창에 λ„μš°κΈ°

import cv2
import numpy as np

img = cv2.imread('img/sun.jpg')

x=320; y=150; w=50; h=50
roi = img[y:y+h, x:x+w]     # roi 지정
img2 = roi.copy()           # roi λ°°μ—΄ 볡제 ---β‘ 

img[y:y+h, x+w:x+w+w] = roi # μƒˆλ‘œμš΄ μ’Œν‘œμ— roi μΆ”κ°€, νƒœμ–‘ 2개 λ§Œλ“€κΈ°
cv2.rectangle(img, (x,y), (x+w+w, y+h), (0,255,0), 10) # 2개의 νƒœμ–‘ μ˜μ—­μ— μ‚¬κ°ν˜• ν‘œμ‹œ

cv2.imshow("img", img)      # 원본 이미지 좜λ ₯
cv2.imshow("roi", img2)     # roi 만 λ”°λ‘œ 좜λ ₯

cv2.waitKey(0)
cv2.destroyAllWindows()

νŠΉμ • μ˜μ—­ κ°•μ‘° 및 μƒˆ μ°½ μ—΄κΈ°

 

 

2. 마우슀 λ“œλž˜κ·Έλ‘œ 관심 μ˜μ—­ ν‘œμ‹œ

onMouse()λΌλŠ” 콜백 ν•¨μˆ˜

: (1) 마우슀 μ™Όμͺ½ λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ, (2) λˆ„λ₯Έ μƒνƒœλ‘œ λ“œλž˜κ·Έν–ˆμ„ λ•Œ, (3) 마우슀 μ™Όμͺ½ λ²„νŠΌμ„ λ—„ λ•Œ

(x0, y0)

: 마우슀 λ“œλž˜κ·Έκ°€ μ‹œμž‘λœ μœ„μΉ˜

(x, y)

: 마우슀의 ν˜„μž¬ μœ„μΉ˜

# 마우슀둜 κ΄€μ‹¬μ˜μ—­ 지정 및 ν‘œμ‹œ, μ €μž₯ 

import cv2
import numpy as np

isDragging = False                      # 마우슀 λ“œλž˜κ·Έ μƒνƒœ μ €μž₯ 
x0, y0, w, h = -1,-1,-1,-1              # μ˜μ—­ 선택 μ’Œν‘œ μ €μž₯
blue, red = (255,0,0),(0,0,255)         # 색상 κ°’ 

def onMouse(event,x,y,flags,param):     # 마우슀 이벀트 ν•Έλ“€ ν•¨μˆ˜  ---β‘ 
    global isDragging, x0, y0, img      # μ „μ—­λ³€μˆ˜ μ°Έμ‘°
    if event == cv2.EVENT_LBUTTONDOWN:  # μ™Όμͺ½ 마우슀 λ²„νŠΌ λ‹€μš΄, λ“œλž˜κ·Έ μ‹œμž‘ ---β‘‘
        isDragging = True
        x0 = x
        y0 = y
    elif event == cv2.EVENT_MOUSEMOVE:  # 마우슀 μ›€μ§μž„ ---β‘’
        if isDragging:                  # λ“œλž˜κ·Έ 진행 쀑
            img_draw = img.copy()       # μ‚¬κ°ν˜• κ·Έλ¦Ό ν‘œν˜„μ„ μœ„ν•œ 이미지 볡제
            cv2.rectangle(img_draw, (x0, y0), (x, y), blue, 2) # λ“œλž˜κ·Έ 진행 μ˜μ—­ ν‘œμ‹œ
            cv2.imshow('img', img_draw) # μ‚¬κ°ν˜• ν‘œμ‹œλœ κ·Έλ¦Ό ν™”λ©΄ 좜λ ₯
    elif event == cv2.EVENT_LBUTTONUP:  # μ™Όμͺ½ 마우슀 λ²„νŠΌ μ—… ---β‘£
        if isDragging:                  # λ“œλž˜κ·Έ 쀑지
            isDragging = False          
            w = x - x0                  # λ“œλž˜κ·Έ μ˜μ—­ 폭 계산
            h = y - y0                  # λ“œλž˜κ·Έ μ˜μ—­ 높이 계산
            print("x:%d, y:%d, w:%d, h:%d" % (x0, y0, w, h))
            if w > 0 and h > 0:         # 폭과 높이가 μ–‘μˆ˜μ΄λ©΄ λ“œλž˜κ·Έ λ°©ν–₯이 옳음 ---β‘€
                img_draw = img.copy()   # 선택 μ˜μ—­μ— μ‚¬κ°ν˜• 그림을 ν‘œμ‹œν•  이미지 볡제
                # 선택 μ˜μ—­μ— λΉ¨κ°„ μ‚¬κ°ν˜• ν‘œμ‹œ
                cv2.rectangle(img_draw, (x0, y0), (x, y), red, 2) 
                cv2.imshow('img', img_draw) # λΉ¨κ°„ μ‚¬κ°ν˜• 그렀진 이미지 ν™”λ©΄ 좜λ ₯
                roi = img[y0:y0+h, x0:x0+w] # 원본 μ΄λ―Έμ§€μ—μ„œ 선택 영영만 ROI둜 지정 ---β‘₯
                cv2.imshow('cropped', roi)  # ROI 지정 μ˜μ—­μ„ μƒˆμ°½μœΌλ‘œ ν‘œμ‹œ
                cv2.moveWindow('cropped', 0, 0) # μƒˆμ°½μ„ ν™”λ©΄ 쒌츑 상단에 이동
                cv2.imwrite('img/cropped.jpg', roi)   # ROI μ˜μ—­λ§Œ 파일둜 μ €μž₯ ---⑦
                print("croped.")
            else:
                cv2.imshow('img', img)  # λ“œλž˜κ·Έ λ°©ν–₯이 잘λͺ»λœ 경우 μ‚¬κ°ν˜• κ·Έλ¦Όγ…‡γ…£ μ—†λŠ” 원본 이미지 좜λ ₯
                print("쒌츑 μƒλ‹¨μ—μ„œ 우츑 ν•˜λ‹¨μœΌλ‘œ μ˜μ—­μ„ λ“œλž˜κ·Έ ν•˜μ„Έμš”.")

img = cv2.imread('img/sun.jpg')
cv2.imshow('img', img)
cv2.setMouseCallback('img', onMouse) # 마우슀 이벀트 등둝 ---⑧
cv2.waitKey()
cv2.destroyAllWindows()

직접 마우슀둜 λ“œλž˜κ·Έ!
잘린 이미지 μ €μž₯

 

 

 

+) opencv의 ν•¨μˆ˜ μ‚¬μš©!

ret = cv2.selectROI(win_name, img, showCrossHair=True, fromCenter=False)

: 마우슀둜 관심 μ˜μ—­μ„ λ“œλž˜κ·Έ ν•œ λ’€ μŠ€νŽ˜μ΄μŠ€λ‚˜ μ—”ν„°λ₯Ό λˆ„λ₯΄λ©΄ μƒˆ 창에 관심 μ˜μ—­μ΄ λœ¬λ‹€
win_name : κ΄€μ‹¬μ˜μ—­μ„ ν‘œμ‹œν•  창의 이름
img : κ΄€μ‹¬μ˜μ—­μ„ ν‘œμ‹œν•  이미지
showCrossHair : 선택 μ˜μ—­ 쀑심에 μ‹­μž λͺ¨μ–‘ ν‘œμ‹œ μ—¬λΆ€
fromCenter : 마우슀 μ‹œμž‘ 지점을 μ˜μ—­μ˜ μ€‘μ‹¬μœΌλ‘œ 지정
ret : μ„ νƒν•œ μ˜μ—­μ˜ μ’Œν‘œμ™€ 크기 (x, y, w, h); 선택을 μ·¨μ†Œν•˜λ©΄ λͺ¨λ‘ 0으둜 지정됨

# selectROI둜 κ΄€μ‹¬μ˜μ—­ 지정 및 ν‘œμ‹œ, μ €μž₯ (roi_select_img.py)

import cv2, numpy as np

img = cv2.imread('img/sun.jpg')

x,y,w,h	= cv2.selectROI('img', img, False)      # 원본 이미지 λ„μ–΄μ€Œ
if w and h:
    roi = img[y:y+h, x:x+w]
    cv2.imshow('cropped', roi)  # ROI 지정 μ˜μ—­μ„ μƒˆμ°½μœΌλ‘œ ν‘œμ‹œ
    cv2.moveWindow('cropped', 0, 0) # μƒˆμ°½μ„ ν™”λ©΄ 쒌츑 상단에 이동
    cv2.imwrite('img/cropped2.jpg', roi)   # ROI μ˜μ—­λ§Œ 파일둜 μ €μž₯

cv2.waitKey(0)
cv2.destroyAllWindows()

Select a ROI and then press SPACE or ENTER button!
Cancel the selection process by pressing c button!

 

opencv ν•¨μˆ˜ μ΄μš©ν•΄μ„œ 마우슀 λ“œλž˜κ·Έ!

 

잘린 이미지 μ €μž₯

 

 

ν›„.. ROI

직접 마우슀둜 λ“œλž˜κ·Έ ν•  수 μžˆμ—ˆλ‹€λ‹ˆ

ꡉμž₯히 μœ μš©ν•˜κ΅°

728x90
λ°˜μ‘ν˜•
Comments