앞의 게시물의 마지막 이미지를 보면 차선 이외에 주변의 많은 다른 픽셀들이 감지되는 것을 볼 수 있습니다. 이를 제거하기 위해 ROI(Region Of Interest), 즉 관심 영역을 지정해야 합니다.

 

카메라가 차량 전면에 고정돼있다고 하면 차선은 항상 이미지의 동일한 영역에 나타납니다. 보고 싶은 부분만 잘라내어 차선이라고 생각되는 부분만 본다는 것입니다. 여러 모양으로 ROI를 지정할 수 있는데 우선 삼각형으로 만들어보겠습니다. 그럼 삼각형 내부에 있는 흰 픽셀이 차선임을 의미하겠죠?

 

코드에 적힌 test.jpg 이미지는 차선 인식(1) 게시물에 있습니다. 

2021.04.26 - [Udacity/computer vision & deep learning] - 차선인식(1) - 색으로 차선인식

 

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

# Read in the image and print some stats
image = mpimg.imread('test.jpg')
print('This image is: ', type(image), 
         'with dimensions:', image.shape)

# Pull out the x and y sizes and make a copy of the image
ysize = image.shape[0]
xsize = image.shape[1]
region_select = np.copy(image)

# 삼각형 모양으로 roi 지정하기
# 아래의 세가지 변수를 바꿔가며 삼각형 모양안에 차선이 다들어오도록 만들어 줍니다.
left_bottom = [70, 315]
right_bottom = [497, 315]
apex = [280, 190]

# np.polyfit()함수는 괄호안에 x좌표, y좌표, 차수를 넣으면 두 점을 연결한 직선의 기울기와 y절편을 알려줍니다.
fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)

# 위에서 그린 선 안에 있는 모든 픽셀을 선택합니다.
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & \
                    (YY > (XX*fit_right[0] + fit_right[1])) & \
                    (YY < (XX*fit_bottom[0] + fit_bottom[1]))

# 위에서 선택한 픽셀의 색을 빨간색으로 만든다. 즉, roi부분을 빨간색으로 만든다.
region_select[region_thresholds] = [255, 0, 0]

# Display the image
plt.imshow(region_select)

# 그래프가 나타나지않으면 아래의 주석을 풀면됩니다.
# plt.show()

 

위의 코드를 실행했을 때 결과 이미지는 아래와 같습니다.

 

 

그럼 roi내부를 모두 빨간색으로 하는 것이 아니라 차선만 빨간색으로 만들어 보겠습니다.

 

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

# Read in the image
image = mpimg.imread('test.jpg')

# Grab the x and y sizes and make two copies of the image
# With one copy we'll extract only the pixels that meet our selection,
# then we'll paint those pixels red in the original image to see our selection 
# overlaid on the original.
ysize = image.shape[0]
xsize = image.shape[1]
color_select= np.copy(image)
line_image = np.copy(image)

# Define our color criteria
red_threshold = 200
green_threshold = 200
blue_threshold = 200
rgb_threshold = [red_threshold, green_threshold, blue_threshold]

# Define a triangle region of interest (Note: if you run this code, 
# Keep in mind the origin (x=0, y=0) is in the upper left in image processing
# you'll find these are not sensible values!!
# But you'll get a chance to play with them soon in a quiz ;)
left_bottom = [70, 315]
right_bottom = [497, 315]
apex = [280, 190]

fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)

# Mask pixels below the threshold
color_thresholds = (image[:,:,0] < rgb_threshold[0]) | \
                    (image[:,:,1] < rgb_threshold[1]) | \
                    (image[:,:,2] < rgb_threshold[2])

# Find the region inside the lines
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & \
                    (YY > (XX*fit_right[0] + fit_right[1])) & \
                    (YY < (XX*fit_bottom[0] + fit_bottom[1]))
# Mask color selection
color_select[color_thresholds] = [0,0,0]
# Find where image is both colored right and in the region
line_image[~color_thresholds & region_thresholds] = [255,0,0]

# Display our two output images
plt.imshow(color_select)
plt.imshow(line_image)

# uncomment if plot does not display
# plt.show()

 

위의 코드의 결과이미지는 다음과 같습니다.

 

 

'Udacity > computer vision & deep learning' 카테고리의 다른 글

차선인식(1) - 색으로 차선인식  (0) 2021.04.26

이미지에서 차선을 찾아보려고 합니다. 도로의 차선을 식별하기 위해서 필요한 것들이 무엇이 있을까요?

1. : 주로 차선은 흰색, 주황색으로 칠해져있습니다.

2. 모양 : 실선, 점선

3. 이미지에서의 위치 : 자동차에 장착된 카메라가 고정되어있기 때문에 차선은 항상 카메라 이미지에서 동일한 영역에                                  나타납니다. 

4. 방향(orientation) : 차량이 도로를 똑바로 향하고 있을 때 차선은 삼각형 모양으로 보입니다.


먼저 색으로 차선을 한번 찾아보려고 합니다.

차선이 흰색이라고 가정을 하면 이미지에서 흰색 픽셀을 어떻게 골라낼 것인가요?

이미지가 rgb채널(red-green-blue)로 이루어져 있다고 생각을 해봅시다. 각각의 채널은 0에서 255까지의 범위를 가지는데 0은 가장 어두운 부분, 255는 가장 밝은 부분을 의미합니다.

 

모든 이미지 파일은 픽셀(Pixel)이라는 것으로 이루어져 있습니다. 눈에 보이지는 않지만 아주 작은 크기의 사각형 단위인 픽셀에 색상이 넣어짐으로써 한 칸의 색이 완성이 되고, 그런 작은 사각형들이 모여 이미지를 완성시킵니다.

 

Quiz!

rgb채널에서 순수 흰색을 뽑아내고 싶으면 범위를 어떻게 지정해야 할까요?

더보기

답은 [255,255,255]입니다.


파이썬으로 흰색을 추출하는 코딩을 해보겠습니다.

 

test.jpg

이미지를 그려내기 위해서pyplotMatplotlib에 있는 image라이브러리를 불러옵니다. 또한 이미지를 수정/관리하기 위한 용도로 Numpy 사용합니다.

 

# matplotlib는 파이썬의 시각화 도구입니다.
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

 

그런 다음 x  y 크기를 잡고 작업할 이미지의 복사본을 만듭니다.

이미지를 수정/관리할 때는/ 항상 Copy를 만드는 것이 좋습니다. 이미지에 직접 수정을 가하게 된다면 돌이킬 수 없을 수도 있기 때문입니다.

 

# 이미지를 읽고 몇가지 속성을 출력합니다.
image = mpimg.imread('test.jpg')
print('This image is: ',type(image), 
         'with dimensions:', image.shape)

# x와 y의 사이즈를 측정하고, 복사본을 만듭니다.
ysize = image.shape[0] #이미지의 높이
xsize = image.shape[1] #이미지의 너비
# Note: 단순히 "="를 사용하는 대신 항상 복사본을 만드십시오.
color_select = np.copy(image)

※ image.shape [이미지 높이, 이미지 너비, 채널 수] 

이미지에서 좌표축을 만들어보면 아래 사진과 같습니다.

위의 코드에서 ysize와 xsize가 왜 이미지의 높이와 너비를 의미하는지 알겠죠?


다음으로는 차선으로 뽑아낼 색의 임계값을 지정해 볼까요

아래의 임계값을 추출할 수 있도록 조정해야 합니다.

 

# 색상 선택의 기준을 정합니다.
red_threshold = 200
green_threshold = 200
blue_threshold = 200
rgb_threshold = [red_threshold, green_threshold, blue_threshold] # 3가지채널을 조합합니다.

 

다음으로는 임계값 아래의 픽셀들은 다 0, 즉 검은색으로 만들어 줍니다. 그럼 지정한 임계값보다 밝은 색상만 추출되고 임계값보다 어두운 색상은 검정색으로 출력됩니다. 임계값을 조정하다 보면 흰색만 이미지에 나타나게 됩니다.

 

※각각의 임계값을 모두 0으로 설정한 후 이미지를 출력하면 검은색으로 만들 부분이 없기 때문에 아무런 변화가 없는 것을 알 수 있습니다. 

 

# 임계 값 미만의 픽셀을 식별한다.
thresholds = (image[:,:,0] < rgb_threshold[0]) \
            | (image[:,:,1] < rgb_threshold[1]) \
            | (image[:,:,2] < rgb_threshold[2])
color_select[thresholds] = [0,0,0]

# 이미지를 보여준다.              
plt.imshow(color_select)
plt.show()
# 결과이미지를 저장하려면 아래코드를 입력하면됩니다.
# mpimg.imsave("test-after.png", color_select)

 

image [:,:,0]은 rgb에서 0번째 채널을 의미합니다. 코드를 해석해보면 0번째 채널인 빨간색 채널의 임계값이 지정해 놓은 rgb_threshold의 0번째행인 red_threshold값보다 작을 경우 임계값을 0으로 만들어준다는 것입니다.

다음은 임계값을 조정하여 가능한 많은 차선을 추출한 이미지입니다.

 

test-after.png

 

다음 게시물에 계속됩니다!

'Udacity > computer vision & deep learning' 카테고리의 다른 글

차선인식(2) - ROI지정하기  (0) 2021.04.26

+ Recent posts