Opencv

9-1 Opencv에 의한 RGB HUE 색상 필터링 AI 처리 기법

coding art 2020. 4. 19. 13:16
728x90

이미지에서 RGB HUE 즉 색상 필터를 사용하여 이미지에서 원하는 색상 부분을 마스킹 작업을 해보자. 다음의 분홍색 꽃 바탕위에 사각형 붉은색 도형으로 이루어진 원 이미지에서 붉은 색 부분만 필터링 해 보기로 하자.


스마트폰에서 찍은 원 이미지의 4128X2322이다. 이 이미지는 라즈베리파이의 PiCamera를 사용하는 Opencv 비젼 코드로 처리하기에는 벅차므로 가로의 픽셀 수를 640으로 낮추도록 하면 높이 방향은 368이 된다. 이 숫자는 Opencv 코드에서 주는 경고 메세지를 참조하여 수정하였다.



수정된 이미지에 적당한 크기의 빨간색 사각형을 추가한 아미지가 원 이미지가 된다. 원 이미지를 대상으로 RGB HUE 값 범위에 의해 빨간색만을 필터링 하려면 우선 전체적으로 색상의 불규칙한 불연속성이 강하므로 Gaussian Blurring 커늘을 사용하여 다소 연속적인 색상 분포로 처리해야 할 필요가 있다.







이 기법은 CNN에서 사용하는 컨볼루션 필터 커늘에 가우시안 분포를 적용하는 것인데 처리 후 색상 분포가 특히 명암 변화율이 심한 모서리(Edge)에서 다소 누그러지는 느낌이 들게 된다. 커늘 사이즈 설정은 사용자가 설정하게끔 되어 있다.


위의 비교 그림에서 GaussianBlur 미적용으로 분홍색 꽃이 정확하게 관찰되는 이미지와 GaussianBlur 가 적용되어 뭔가 흐릿한 느낌의 원이미지를 비교해 보면 가우시안 필터 처리 효과를 쉽게 확인 할 수 있다. 가우시안 필터 미적용 시에는 이미지 픽셀 색상 값의 불연속적인 효과로 인해 마스킹 시에 노이즈에 해당하는 흰 점들이 많이 나타난다.

 

한편 필터링 하고자 하는 RGB HUE 색상의 적절한 범위를 정확하게 지정해야 한다. 현재 사용한 빨간색상의 RGB HUE 값 범위는 Adrian의 노란색 테니스 공 tracking 코드에서 사용하는 값을 따다 사용하였다. 이 색상 필터링에서 G 1505~10 범위로 값을 조금만 수정해도 필터링이 안 될 정도로 민감하다.


RGB HUE 값 범위 지정에 의한 색상 필터링 작업을 위한 코드는 컬러볼 tracking 코드를 수정해서 사용하도록 하자. 이 코드는 원래 초당 frame 값이 최소 32로 설정되어 사용되지만 정적인 이미지이기 때문에 frame 값을 분당 1 로 조정하여 사용하도록 하자. 물론 이 값을 0.2 정도로 낮춰도 코드는 이상 없이 실행 가능하다.

 

이와같은 RGB HUE 색상 값 범위를 주어 특별한 색상의 오브젝트를 필터링 하는 기법은 특히 농업이나 원예 분야에서 저굥될 수 있는 기법으로서 특징이 이미지의 시간적인 변화율이 대단히 느린 편이다. 따라서 frame rate 값이 높을 필요가 없으므로 소형인 라브베리파이의 컴퓨팅 부담을 감안하여 최대한 낮은 값을 사용하도록 하자.

 

첨부된 코드를 다운받아 실행해 보자.



#red_detect.py

 from picamera.array import PiRGBArray

from picamera import PiCamera

import time

import cv2

import sys

import numpy as np


# initialize the camera and grab a reference to the raw camera capture

camera = PiCamera()

#camera.resolution 

camera.resolution = (640, 432)

camera.framerate = 1

rawCapture = PiRGBArray(camera, size=(640, 432))

# allow the camera to warmup

time.sleep(0.1)

#lastTime = time.time()*1000.0

# capture frames from the camera

for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):


    #image = frame.array

    #image = cv2.imread('redtulip.jpg')

    image = cv2.imread('re.jpg')

    #image = cv2.GaussianBlur(image,(11,11), cv2.BORDER_DEFAULT)

    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)


    cv2.imshow("image", image)

    #lower_red =   np.array([70,100,50])

    lower_red =   np.array([165,100,50])

    upper_red =   np.array([255,255,255])

    maskred = cv2.inRange(hsv, lower_red, upper_red)

    resred = cv2.bitwise_and(image,image, mask= maskred)

    cv2.imshow('maskred', maskred)

    cv2.imshow('resred',resred)


    # show the frame

    key = cv2.waitKey(1) & 0xFF

    # clear the stream in preparation for the next frame

    rawCapture.truncate(0)    

# if the `q` key was pressed, break from the loop

    if key == ord("q"):

        break