파이썬(Python)/opencv

[Python] OpenCV PC 카메라 특정 색상만 출력하기 (Camera, BGR, HSV, inRange, bitwise_and)

끄적끄적아무거나 2022. 6. 4. 13:23
반응형

 

목차

    파이썬 카메라의 특정 색상만 보여주기 동작 방식

     

    이번 포스트는 노트북에 카메라를 사용해서 화면의 빨간색(Red), 녹색(Green), 파란색(Blue)만을 구분해서 해당 색상만을 보여주는 화면을 각 각 띄울 예정입니다. 

     

    총 4개의 윈도우가 화면에 나오고 하나는 원본 나머지는 Red, Green, Blue 윈도우 입니다. 

     

    이를 구현하기 위해서는 아래의 과정이 필요 합니다.

     

     

    1. 카메라 동작 구현

    2. RGB 색상의 범위 결정 (HSV 사용)

    3. RGB 색상의 임계값을 사용해서 마스크 생성

    4. 마스크를 원본 화면에 적용

    5. 화면 출력

     

    우선 코드 작성에 앞서 2번 단계 "RGB 색상의 범위 결정"은 선행되어야 합니다. 아래 목차에서 확인하도록 하겠습니다. 

     

     

     

    RGB 색상의 범위 결정

     

    빨간색(Red), 녹색(Green), 파란색(Blue) 각 색깔의 경계에 대해 생각해야 합니다. 어느정도의 색을 빨간색으로 생각할지는 주관적인 영역입니다. 

     

    저는 빨간색 이미지를 만들고 해당 이미지를 BGR2HSV를 사용해서 HSV (Hue, Saturation, Value) 값으로 변경해서 해당 값을 확인하고 HSV의 값에서 제가 생각하는 아래 기준과 윗 기준(Threshold)를 정했습니다.

     

    BGR을 통해서 HSV 값을 찾는 방법은 아래 코드를 사용하시면 됩니다. 

     

     

    예제 코드- 파란색 HSV 값 찾기>>

    import cv2
    import numpy as np
    
    blue_pixel = np.full((200,200,3),([255,0,0]), dtype=np.uint8)
    modified_blue = cv2.cvtColor(blue_pixel, cv2.COLOR_BGR2HSV )
    print(modified_blue)
    
    cv2.imshow("blue", blue_pixel)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    4번 라인: 파란색으로 이미지 만들기

    5번 라인: cvtColor 함수로 BGR 이미지 값을 HSV로 변환하기

    6번 라인: HSV 값 출력

    8번 라인: 파란색 이미지 출력

     

     

     

    결과>>

    [[[120 255 255] 
      [120 255 255] 
      [120 255 255] 
     ...
      [120 255 255]
      [120 255 255]
      [120 255 255]]]

    파란색의 HSV는 (120, 255, 255) 임을 알 수 있습니다. 

     

    동일 코드로 4번 라인의 [255,0,0] 값을 [0,255,0], [0,0,255]로 변경하면 녹색, 빨간색에 대한 HSV를 구할 수 있습니다. BGR의 HSV는 아래와 같습니다.

     

    • 파란색 HSV : (120, 255, 255)
    • 녹색 HSV : (60, 255, 255)
    • 빨간색 HSV : (0, 255, 255)

     

     

    위 값을 사용해서 Blue, Green, Red 의 경계를 아래와 같이 잡았습니다. 경계를 잡는 것은 코드를 작성하는 사람의 주관이므로 적절한 값을 사용하시면 됩니다.

     

    제가 정한 Low point와 High Point는 코드를 통해 확인할 수 있습니다. 해당 임계값은 직접 측정하면서 변경하시는 것도 좋습니다. 

     

     

     

     

    파이썬 카메라의 특정 색상만 보여주기 실습

     

    이제 앞서 찾아낸 임계값을 이용해서 실제 구현하는 코드를 작성하겠습니다. 코드를 통해 동작 방식을 쉽게 이해해보도록 하겠습니다. 

     

    예제 코드>>

    import cv2
    
    b_l_threhold = (100, 100, 100)
    b_h_threhold = (150, 255, 255)
    g_l_threhold = (30, 80, 80)
    g_h_threhold = (90, 255, 255)
    r_l_threhold = (-30, 100, 100)
    r_h_threhold = (30, 255, 255)
    
    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH,320)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT,240)    
    if not cap.isOpened():    
        print("cap open failed")    
        exit()
        
    while True:
        ret, img = cap.read()    
        if not ret:       
            print("Can't read cap")        
            break        
    
        hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
                
        g_mask = cv2.inRange(hsv_img, g_l_threhold, g_h_threhold)
        b_mask = cv2.inRange(hsv_img, b_l_threhold, b_h_threhold)  
        r_mask = cv2.inRange(hsv_img, r_l_threhold, r_h_threhold)       
    
        blue_img = cv2.bitwise_and(img, img, mask=b_mask)
        green_img = cv2.bitwise_and(img, img, mask=g_mask)  
        red_img = cv2.bitwise_and(img, img, mask=r_mask)          
    
        cv2.imshow('IMG',img)
        cv2.imshow('BLUE', blue_img)
        cv2.imshow('GREEN', green_img)
        cv2.imshow('RED', red_img)
        
        if cv2.waitKey(1) == ord('q'):
            break
        if cv2.waitKey(1) == ord('c'):        
            img_captured = cv2.imwrite('img_captured.png', img)
            img_captured = cv2.imwrite('blue_captured.png', blue_img)
            img_captured = cv2.imwrite('green_captured.png', green_img)
            img_captured = cv2.imwrite('red_captured.png', red_img)    
    
    cv2.destroyAllWindows()

    3~8라인: BGR 색상(Color)에 대한 경계 값을 설정합니다. 경계 값은 실습을 통해 변경해서 정한 값입니다.

    10~21번 라인: 컴퓨터에 카메라를 동작시킵니다.

    23번 라인: 카메라에서 모니터하는 화면을 HSV 값으로 변환 합니다. 

    25~27번 라인: inRange 함수로 마스크 범위 설정

    29~31번 라인: bitwise_and 로 마스크 범위 내에 값만 출력

    33~36번 라인: 출력

    38~44번 라인: q 입력 시 종료, c 입력시 화면 캡쳐

     

     

    결과>>

     

     

     

     

     

    반응형