영상처리 기반 신호등 인식

RGB의 문제점

  • RGB 색상을 이용할 때 문제점 : 조명과 그림자 따른 지각 불균일성

image

  • HSV 색상
    • 색상(Hue) : 색 종류(노란색, 빨간색, 파란색, …)
    • 채도(Saturation) : 선명도(원색에 가까울수록 채도가 높음)
    • 명도(Value) : 밝기(명도가 높을 수 백색, 낮을수록 흑색)

image

신호등 이미지 HSV로 변환 예제

  • tf_hsv.py
import cv2

image = cv2.imread("green.jpg")

hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # BGR -> HSV
h, s, v = cv2.split(hsv)

cv2.imshow("h", h)
cv2.imshow("s", s)
cv2.imshow("v", v)

cv2.waitKey(0)

cv2.destroyAllWindows()

image

원 검출 및 노이즈 제거 예제

  • tf_circle.py
import cv2
import numpy as np

img = cv2.imread("green.jpg", cv2.IMREAD_GRAYSCALE) # 그레이스케일 변환
img = cv2.medianBlur(img,5) # 노이즈 제거 작업
cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) # 그레이스케일 -> BGR

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=25, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))

for i in circles[0,:]: # [중심의 X 좌표, 중심의 Y 좌표, 반지름]
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
    
cv2.imshow("img",cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 예상과는 달리, 많은 원들이 검출되는 것을 확인할 수 있음

image

  • 같은 코드를 다른 이미지로 실행해도 예상과 다르게 많은 원들이 검출 됨

image

너무 많은 원을 찾은 경우?

HoughCircles 함수 인자 재설정
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=25, minRadius=0, maxRadius=0)
# cv2.HoughCircles(이미지, 검출방법, 해상도비율, 최소거리, 캐니 엣지 검출 임계값, 중심 임계값, 최소반지름, 최대반지름)
  • 허프 원 변환은 그라디언트 방향과 크기 정보를 사용하여 원을 검출하는데, 그라디언트 정보는 엣지 검출을 통해 얻음
  • 캐니 엣지 검출의 임계값을 조정함으로써 어떤 강도의 픽셀을 엣지로 판단할지 결정할 수 있음
    • 캐니 엣지 검출 임계값이 낮으면 엣지 검출을 많이 하고, 높으면 엣지 검출을 적게 함 (적절한 값을 찾야아 함)
  • 중심 임계값은 낮을 수록 더 많은 원을 검출함(기준이 후해짐)
Blurring 노이즈 제거
img = cv2.medianBlur(img,5) # 노이즈 제거 작업
  • 노이즈 제거 전

image

  • 노이즈 제거 후

image

영상처리 기반 신호등 인식(신호등 구의 위치 찾기)

image

circles = np.uint16(np.around(circles))

for i in circles[0,:]: # [중심의 X 좌표, 중심의 Y 좌표, 반지름]
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
  • i[0], i[1] : 원의 중심 좌표(x,y)
  • i[2] : 원의 반지름

신호 판별하기

  • V 성분으로 점등 구를 판별
    • 원 내의 사각 영역 픽셀 값들의 범위를 기준으로 Light의 ON/OFF를 판정함

image

  • tf_circle_mean.py
import cv2
import numpy as np

image = cv2.imread("green.jpg")
image = cv2.medianBlur(image,5)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=25, minRadius=0, maxRadius=30)

circles = np.uint16(np.around(circles))

for i in circles[0,:]: # [중심의 X 좌표, 중심의 Y 좌표, 반지름]
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    cr_img = v[i[1]-10 : i[1]+10, i[0]-10 : i[0]+10]
    img_str = "x : {0}, y : {1}, mean : {2}".format(i[0], i[1], cr_img.mean())
    print(img_str)
    
cv2.imshow("img", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

image

자이카 traffic_sign 디렉터리 생성

  • $ mkdir traffic_sign
  • $ cd traffic_sign
  • $ mkdir src

image