본문 바로가기
AI/컴퓨터 비전

05. 마스크, 관심영역

by 사라리24 2024. 7. 18.

1. 마스크 연산

inRange() : 영상에서 지젇된 범위 안에 픽셀 선택
copyTo() : 마스크 연산을 지원하는 픽셀 값 복사 함수

 

 특정 범위의 픽셀 값을 추출

       
      cv2.inRange(영상, min값 (Hue, Saturation, Value) , max값 (Hue, Saturation, Value) )

 
예시) cv2.inRange(img, (50, 150, 0), (80, 255, 255))

Hue(색조)가 50에서 80 사이,
Saturation(채도)가 150에서 255 사이,
Value(명도)가 0에서 255 사이의 범위를 지정합니다.

 

 

 특정 HSV 색상 범위를 추출하여 이진 이미지를 생성


       
        import cv2

        img = cv2.imread('./candies.png')
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

        dst = cv2.inRange(hsv, (50, 150, 0), (80, 255, 255))

        cv2.imshow('img', img)
        cv2.imshow('dst', dst)
        cv2.waitKey()



 

 

 마스크를 사용하여지정된 부분을 출력 영상으로 복사


       
          cv2.copyTo(영상, 마스크, 출력영상)

 
 

 

 

 마스크 따기


       
            import cv2

            img = cv2.imread('./airplane.bmp')
            mask = cv2.imread('./mask_plane.bmp')
            dst = cv2.imread('./field.bmp')

            cv2.imshow('img', img)
            cv2.imshow('mask', mask)

            cv2.waitKey()


 

 

 이미지 합치기


       
            import cv2
           
            img = cv2.imread('./airplane.bmp')
            mask = cv2.imread('./mask_plane.bmp')
            dst = cv2.imread('./field.bmp')
           
            # dst가 없으면 새로 만들고
            # dst가 있으면 dst에 추가
            temp = cv2.copyTo(img, mask)
            cv2.copyTo(img, mask, dst)
           
            cv2.imshow('img', img)
            cv2.imshow('mask', mask)
            cv2.imshow('dst', dst)
            cv2.imshow('temp', temp)
           
            cv2.waitKey()

 

 

 

 영상에 크로마키로 다른 배경을 넣어보기


     
          import cv2

          cap1 = cv2.VideoCapture('./woman.mp4')
          cap2 = cv2.VideoCapture('./sea.mp4')

          w = round(cap1.get(cv2.CAP_PROP_FRAME_WIDTH))
          h = round(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT))

          frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT))
          frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT))
          fps = round(cap1.get(cv2.CAP_PROP_FPS))

          print(w)
          print(h)
          print(frame_cnt1)
          print(frame_cnt2)
          print(fps)

          while True:
              ret1, frame1 = cap1.read()
              if not ret1:
                  break
              ret2, frame2 = cap2.read()
              if not ret2:
                  break

              hsv = cv2.cvtColor(frame1, cv2.COLOR_BGR2HSV)
              mask = cv2.inRange(hsv, (50, 150, 0), (70, 255, 255))
              cv2.copyTo(frame2, mask, frame1)

              cv2.imshow('frame1', frame1)
              key = cv2.waitKey(10)
              if key == ord(' '):
                  cv2.waitKey()
              elif key == 27:
                  break

          cap1.release()
          cap2.release()

 

  • 주석
더보기

       
         
          import cv2

          # 동영상 파일 열기
          cap1 = cv2.VideoCapture('./woman.mp4')
          cap2 = cv2.VideoCapture('./sea.mp4')

          # 첫 번째 동영상의 프레임 너비와 높이 구하기
          w = round(cap1.get(cv2.CAP_PROP_FRAME_WIDTH))
          h = round(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT))

          # 각 동영상의 총 프레임 수 구하기
          frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT))
          frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT))

          # 첫 번째 동영상의 프레임 속도(FPS) 구하기
          fps = round(cap1.get(cv2.CAP_PROP_FPS))

          # 출력: 프레임 너비, 높이, 프레임 수, FPS
          print(w)
          print(h)
          print(frame_cnt1)
          print(frame_cnt2)
          print(fps)

          # 프레임 처리 및 표시 루프
          while True:
              # 첫 번째 동영상에서 프레임 읽기
              ret1, frame1 = cap1.read()
              if not ret1:  # 프레임을 읽지 못하면 반복문 종료
                  break

              # 두 번째 동영상에서 프레임 읽기
              ret2, frame2 = cap2.read()
              if not ret2:  # 프레임을 읽지 못하면 반복문 종료
                  break

              # 첫 번째 프레임을 HSV 색상 공간으로 변환
              hsv = cv2.cvtColor(frame1, cv2.COLOR_BGR2HSV)

              # HSV 이미지에서 특정 색상 범위를 마스크로 설정
              mask = cv2.inRange(hsv, (50, 150, 0), (70, 255, 255))

              # 두 번째 프레임에 마스크를 적용하여 합성
              cv2.copyTo(frame2, mask, frame1)

              # 첫 번째 동영상의 프레임 출력
              cv2.imshow('frame1', frame1)

              # 키 입력 대기 (10ms)
              key = cv2.waitKey(10)

              # 스페이스바를 누르면 일시 정지
              if key == ord(' '):
                  cv2.waitKey()

              # ESC를 누르면 종료
              elif key == 27:
                  break

          # 동영상 파일 해제
          cap1.release()
          cap2.release()
 
  • 동영상 파일 열기 및 프로퍼티 확인
    • cap1 = cv2.VideoCapture('./woman.mp4'): 'woman.mp4' 파일을 열어 cap1 객체에 할당합니다.
    • cap2 = cv2.VideoCapture('./sea.mp4'): 'sea.mp4' 파일을 열어 cap2 객체에 할당합니다.
    • w = round(cap1.get(cv2.CAP_PROP_FRAME_WIDTH)): 첫 번째 동영상의 프레임 너비를 구하고 반올림하여 w 변수에 저장합니다.
    • h = round(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT)): 첫 번째 동영상의 프레임 높이를 구하고 반올림하여 h 변수에 저장합니다.
    • frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT)): 첫 번째 동영상의 총 프레임 수를 구하고 반올림하여 frame_cnt1 변수에 저장합니다.
    • frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT)): 두 번째 동영상의 총 프레임 수를 구하고 반올림하여 frame_cnt2 변수에 저장합니다.
    • fps = round(cap1.get(cv2.CAP_PROP_FPS)): 첫 번째 동영상의 프레임 속도(FPS)를 구하고 반올림하여 fps 변수에 저장합니다.
    • 각각의 값들을 출력하여 동영상 파일의 속성을 확인합니다.
  • 프레임 처리 및 표시 루프
    • while True:: 무한 루프를 시작합니다.
    • ret1, frame1 = cap1.read(): 첫 번째 동영상에서 프레임을 읽어옵니다. ret1은 프레임 읽기의 성공 여부를 나타내며, frame1은 읽어온 프레임입니다.
    • if not ret1: break: 프레임을 읽지 못하면 루프를 종료합니다.
    • 마찬가지로 두 번째 동영상에서도 프레임을 읽어옵니다.
    • hsv = cv2.cvtColor(frame1, cv2.COLOR_BGR2HSV): 첫 번째 프레임을 BGR에서 HSV로 색상 공간을 변환합니다.
    • mask = cv2.inRange(hsv, (50, 150, 0), (70, 255, 255)): HSV 이미지에서 특정 색상 범위를 마스크로 설정합니다.
    • cv2.copyTo(frame2, mask, frame1): 두 번째 프레임에 마스크를 적용하여 첫 번째 프레임에 합성합니다.
    • cv2.imshow('frame1', frame1): 첫 번째 동영상의 현재 프레임을 출력합니다.
    • key = cv2.waitKey(10): 10ms 동안 키 입력을 대기합니다.
    • if key == ord(' '): 스페이스바를 누르면 일시 정지하고, 다시 누르면 계속 진행합니다.
    • elif key == 27: break: ESC를 누르면 루프를 종료합니다.

 



2. 관심 영역 (ROI, Region of Interest)

- 영상 내에서 관심이 있는 영역

 

관심 영역을 선택하기


       
         cv2.selectROI(창이름, 영상, 중안좌표여부 = False)




  • 창이름: ROI를 선택할 때 나타날 창의 이름입니다. 선택할 영역을 표시할 창이 열립니다.
  • 영상: ROI를 선택할 이미지나 비디오 프레임입니다.
  • 중앙좌표여부 (optional): 기본적으로 False이며, True로 설정하면 ROI의 중심 좌표를 반환합니다.

 

 

관심 영역을 추출하기


       
            import cv2

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

            # x, y, w, h
            x = 182
            y = 21
            w = 122
            h = 110

            roi = img1[y: y+h, x: x+w]  # 이미지에서 ROI 영역을 슬라이싱
            img2 = roi.copy()  # ROI 영역을 새로운 이미지로 복사

            cv2.imshow('img1', img1) # 원본 이미지
            cv2.imshow('img2', img2) # ROI 이미지

            cv2.waitKey()


 


 

 

 

드래그한 곳을 추출하기


       

        import cv2

        isDrag = False
        oldx = oldy = w = h = 0
        color = (255, 0, 0)
        img_copy = None

        def on_mouse(event, x, y, flags, param):
            global oldx, oldy, isDrag, img_copy
            if event == cv2.EVENT_LBUTTONDOWN:
                isDrag = True
                oldx = x
                oldy = y
            elif event == cv2.EVENT_MOUSEMOVE:
                if isDrag:
                    img_copy = img.copy()
                    cv2.rectangle(img_copy, (oldx, oldy), (x, y), color, 3)
                    cv2.imshow('img', img_copy)
            elif event == cv2.EVENT_LBUTTONUP:
                if isDrag:
                    isDrag = False
                    if x > oldx and y > oldy:
                        w = x - oldx
                        h = y - oldy
                        if w > 0 and h > 0:
                            cv2.rectangle(img_copy, (oldx, oldy), (x, y), color, 3)
                            cv2.imshow('img', img_copy)
                            roi = img[oldy: oldy + h, oldx: oldx + w]
                            cv2.imshow('roi', roi)
                    else:
                        cv2.imshow('img', img)
                        print('영역이 잘 못 되었음')


        img = cv2.imread('./sun.jpg')
        cv2.namedWindow('img')
        cv2.setMouseCallback('img', on_mouse)
        cv2.imshow('img', img)
        cv2.waitKey()





 

 

cv2.selectROI 함수를 사용해보기

       
 

        import cv2

        img = cv2.imread('./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('roi', roi)

        cv2.waitKey()



 

 

'AI > 컴퓨터 비전' 카테고리의 다른 글

07. 이미지 유사도, 영상의 변환  (0) 2024.07.18
06. 이진화  (0) 2024.07.18
04. 평활화, 색공간, CLAHE, 정규화  (1) 2024.07.17
03. 영상 화소처리  (1) 2024.07.17
02. OpenCV 라이브러리  (3) 2024.07.16