[2023-06-27] 영상처리 기반 자이카 신호등 인식
영상처리 기반 신호등 인식
RGB의 문제점
- RGB 색상을 이용할 때 문제점 : 조명과 그림자 따른 지각 불균일성
- HSV 색상
- 색상(Hue) : 색 종류(노란색, 빨간색, 파란색, …)
- 채도(Saturation) : 선명도(원색에 가까울수록 채도가 높음)
- 명도(Value) : 밝기(명도가 높을 수 백색, 낮을수록 흑색)
신호등 이미지 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()
원 검출 및 노이즈 제거 예제
- 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()
- 예상과는 달리, 많은 원들이 검출되는 것을 확인할 수 있음
- 같은 코드를 다른 이미지로 실행해도 예상과 다르게 많은 원들이 검출 됨
너무 많은 원을 찾은 경우?
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) # 노이즈 제거 작업
- 노이즈 제거 전
- 노이즈 제거 후
영상처리 기반 신호등 인식(신호등 구의 위치 찾기)
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를 판정함
- 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()
자이카 traffic_sign 디렉터리 생성
$ mkdir traffic_sign
$ cd traffic_sign
$ mkdir src