이번에는 threshold방식을 이용하여 인식하고자 하는 물체의 윤곽선을 얻었다.
- 목표 : 콘 인식 및 주행
- 개발환경 : IDLE
- 언어 : python
- 방식 : 단순 알고리즘(Canny threshold)
위와 같이 계획을 세웠다.
Canny threshold를 이용하면 물체의 윤곽선을 얻을 수 있다.
윤곽선을 보다 정확하게 얻기 위해 Gaussian Filter을 사용하여 이미지의 노이즈를 줄여주었다.
그리고 라바콘이 주황색이라는 점을 고려하여 HSL필터로 나머지 차선과 배경과 같은 노이즈를 없애 주었다.
그 후 Canny threshold 알고리즘을 사용하여 윤곽선을 추출했다. Canny threshold에 대해 더 알고싶으면 아래 사이트를 참조하기 바란다.
OpenCV: Canny Edge Detector
Prev Tutorial: Laplace Operator Next Tutorial: Hough Line Transform Goal In this tutorial you will learn how to: Use the OpenCV function cv::Canny to implement the Canny Edge Detector. Theory The Canny Edge detector [40] was developed by John F. Canny in 1
docs.opencv.org
import matplotlib.pyplot as plt
import numpy as np
import cv2
path = "./source/2022-07-04_16-10-12.mp4"
obj = cv2.imread('./source/lavacorn.png', cv2.IMREAD_GRAYSCALE)#wad
cap=cv2.VideoCapture(path)
obj_contours,_=cv2.findContours(obj, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)#wad
obj_pts=obj_contours[0]#wad
fps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
codec = cv2.VideoWriter_fourcc(*'DIVX')
out=cv2.VideoWriter('output.mp4', codec, 30.0, (int(width),int(height)), isColor=False)
kernel_size=5
low_threshold=200
high_threshold=255
rho=2
theta=np.pi/180
threshold=90
min_line_len=10
max_line_gap=50
a=0.8
b=1.
theta_w=0.
def grayscale(img):
hsl=cv2.cvtColor(img, cv2.COLOR_BGR2HLS)
imgH,imgS,imgL=cv2.split(hsl)
return imgL
def gaussian_blur(img, kernel_size):
return cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)
def canny(img, low_threshold, high_threshold):
"""Applies the Canny transform"""
return cv2.Canny(img, low_threshold, high_threshold)
def auto_canny(img, sigma):
"""Applies the Canny transform"""
v=np.median(img)
lower=int(max(0,(1.0-sigma)*v))
upper=int(min(255, (1.0+sigma)*v))
return cv2.Canny(img, lower, upper)
def region_of_interest(img, vertices):
mask=np.zeros_like(img)
if len(img.shape)>2:
channel_count = img.shape[2]
ignore_mask_color=(255,)*channel_count
else:
ignore_mask_color=255
cv2.fillPoly(mask, vertices, ignore_mask_color)
masked_image=cv2.bitwise_and(img,mask)
return masked_image
def draw_lines(img, lines, color=[255,0,0], thickness=5):
for line in lines:
for x1, y1, x2, y2 in line:
cv2.line(img, (x1,y1), (x2,y2), color, thickness)
def hough_lines(img, rho, theta, threshold, min_line_len, max_line_gap):
lines=cv2.HoughLinesP(img, rho, theta, threshold, np.array([]), min_line_len, max_line_gap)
line_img=np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
draw_lines(line_img, lines)
return line_img
def weighted_img(img, initial_img, a, b, theta_w):
return cv2.addWeighted(initial_img, a, img, b, theta_w)
while cap.isOpened(): # cap 정상동작 확인
ret, img = cap.read()
# 프레임이 올바르게 읽히면 ret은 True
if not ret:
print("프레임을 수신할 수 없습니다. 종료 중 ...")
break
img = cv2.resize(img, dsize=(640, 360))
gray=grayscale(img)
blur_gray=gaussian_blur(gray, kernel_size)
edges=canny(blur_gray, low_threshold, high_threshold)
mask=np.zeros_like(img)
if len(img.shape)>2:
channel_count=img.shape[2]
ignore_mask_color=(255,) * channel_count
else:
ignore_mask_color=255
imshape=img.shape
vertices=np.array([[(0,275),
(250, 170),
(310, 170),
(imshape[1], 275)]], dtype=np.int32) #(0,275)(250, 185)(310, 185)(imshape[1], 275)
cv2.fillPoly(mask, vertices, ignore_mask_color)
masked_image=region_of_interest(edges, vertices)
bigimg=cv2.resize(masked_image, dsize=(1280, 720))
## 작업공간 ##
contours,_=cv2.findContours(bigimg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for pts in contours:
if cv2.contourArea(pts) <100:
continue
rc=cv2.boundingRect(pts)
#cv2.rectangle(bigimg, rc, (255, 0,0),1)
dist=cv2.matchShapes(obj_pts, pts, cv2.CONTOURS_MATCH_I3, 0)
if dist <0.4:
cv2.rectangle(bigimg, rc, (255, 0,0),1)
cv2.imshow('frame1', bigimg)
out.write(bigimg)
if cv2.waitKey(1) == ord('q'):
break
# 작업 완료 후 해제
cap.release()
out.release()
cv2.destroyAllWindows()
Python에서 OpenCV로 Canny Detection을 이용하는 차선 인식
세상에는 고수가 많고, 그 많은 고수들중 또 많은 분들이 친절(^^)합니다. 요즘은 그 많은 친절한 고수분들의 설명을 따라하는 것 만으로도 참~ 즐거운 공부가 됩니다. 오늘은.. (제가 맨날하는)
pinkwink.kr
위 사이트를 기반으로 코드를 작성하였다. 이전 포스트와 다른 점이 있다면 HSL필터를 사용하여 차선을 인식하던 문제점을 해결하고 콘을 인식하도록 하였다.
위 동영상에서 보이듯 차선은 전부 제외하고 콘만 인식하도록 만든 것을 볼 수 있다. 하지만 인식률이 떨어지는 문제점이 있었다. 차선이 인식되는 근본적인 문제를 해결하였다는 점에서 본 포스팅은 의의가 크다. 다음 포스팅에서는 콘에 대한 인식률을 높이고 차선을 연결하는 것을 목표로 삼고 진행할 것이다.
이전 포스팅이 궁금하다면 아래 사이트를 참조하길 바란다.
[Python] Hough transform을 이용하여
이번 시도에서는 원근법을 사용하여 이미지를 변형하는 방식 대신 차선 그 자체를 인식하는 방법을 사용하였다. 목표 : 콘 인식 및 주행 개발환경 : IDLE 언어 : python 방식 : 단순 알고리즘(허프
codezaram.tistory.com