Professional Documents
Culture Documents
-----***-----
Đề tài:
Xây dựng chương trình nhận dạng biển báo giao thông
2
Mục lục
CHƯƠNG I.GIỚI THIỆU BÀI TOÁN.........................................................................4
1.1 Đặt vấn đề...........................................................................................................4
1.2 Mục tiêu và nhiệm vụ nghiên cứu.......................................................................4
1.3 Phương tiện công cụ sử dụng..............................................................................4
1.4 Phương pháp sử dụng..........................................................................................4
CHƯƠNG II.CÁC THUẬT TOÁN VÀ KHÁI NIỆM ĐƯỢC SỬ DỤNG.................5
2.1 Thuật toán Gauss.................................................................................................5
2.2 Toán tử Laplacian...............................................................................................5
2.3 Ảnh nhị phân (Binary image)..............................................................................5
2.4 Ảnh xám (Gray image)........................................................................................5
2.5 Biến đổi Hough (Hough Transform)...................................................................5
2.6 Giải thuật Canny.................................................................................................6
CHƯƠNG III : XÂY DỰNG CHƯƠNG TRÌNH........................................................7
3.1 Khái quát bài toán...............................................................................................7
3.2 Các bước thực hiện bài toán................................................................................7
3.3 Các hàm tiền xử lý ảnh........................................................................................8
3.3.1 Hàm constrastLimit:.....................................................................................8
3.3.2 Hàm LaplacianOfGaussian..........................................................................9
3.3.3 Hàm binarization..........................................................................................9
3.3.4 Hàm preprocess_image................................................................................9
3.3.5 Hàm removeSmallComponents.................................................................10
3.3.6 Hàm FindContour......................................................................................10
3.3.7 Hàm contourIsSign....................................................................................10
3.3.8 Các hàm crop sign......................................................................................11
3.3.9 Hàm tìm kiếm biển báo..............................................................................12
3.3.10 Hàm localization......................................................................................13
3.3.11 Hàm remove_line.....................................................................................14
3.3.12 Hàm remove_other_color.........................................................................15
3.3.13 Hàm main()..............................................................................................16
3
CHƯƠNG IV: KẾT QUẢ CHẠY CHƯƠNG TRÌNH...............................................22
CHƯƠNG V: ĐÁNH GIÁ VỀ CHƯƠNG TRÌNH VÀ KẾT LUẬN........................25
Ưu điểm:.................................................................................................................25
Nhược điểm:............................................................................................................25
Hướng phát triển trong tương lai............................................................................25
Lời kết.....................................................................................................................25
4
CHƯƠNG I.GIỚI THIỆU BÀI TOÁN
1.1 Đặt vấn đề
Với việc ứng dụng công nghệ thông tin để giải quyết các vấn đề trong giao thông là
một vấn đề thiết yếu và quan trọng. Việc xây dựng hệ thống giao thông thông minh
ở các xe tự động là vấn đề được quan tâm và phát triển trong và cả ngoài nước.
Sự phát triển thường xuyên của công nghệ trong sản xuất ô tô với những cải tiến
liên tục cho các dòng xe mới thì việc có một hệ thống nhận diện biển báo là một sự
cải tiện nên có và được quan tâm đảm bảo sự chính xác trong xử lý và an toàn
trong giao thông .
1.2 Mục tiêu và nhiệm vụ nghiên cứu
Mục tiêu: tạo ra một hệ thống có thể nhận dạng được cơ bản một số biển báo giao
thông
Nhiệm vụ nghiên cứu:
Nghiên cứu tổng quan về xử lý ảnh
Nghiên cứu, phân tích các phương pháp nhận dạng, xử lý hình ảnh biển báo giao
thông
Tìm hiểu các biển báo giao thông
Thu thập dữ liệu các biển báo cho cơ sở dữ liệu hình ảnh để nhận dang biển báo
giao thông
1.3 Phương tiện công cụ sử dụng
Thư viện sử dụng: OpenCV
Ngôn ngữ lập trình: Python
Phần mềm sử dụng : Anaconda-Spyder
1.4 Phương pháp sử dụng
5
CHƯƠNG II.CÁC THUẬT TOÁN VÀ KHÁI NIỆM ĐƯỢC
SỬ DỤNG
2.1 Thuật toán Gauss
Gaussian blur (làm mờ/mịn Gaussian) là kết quả của việc làm mờ hình ảnh bởi một
hàm Gaussian.
Kỹ thuật này được sử dụng để giảm nhiễu ảnh và các chi tiết. Hiệu ứng hình ảnh
của kỹ thuật Gaussian tương tự như việc nhìn một hình ảnh qua màn hình mờ.
Trong thị giác máy tính, Gaussian được sử dụng để tăng cường hình ảnh ở các quy
mô khác nhau hoặc như một kỹ thuật tăng cường dữ liệu trong học sâu.
6
2.5 Biến đổi Hough (Hough Transform)
Là một kỹ thuật phổ biến để phát hiện bất kỳ hình dạng nào nếu có thể biểu diễn
hình dạng đó dưới dạng toán học. Có thể phát hiện hình dạng ngay cả khi nó bị
hỏng hoặc bị bóp méo một chút
2.6 Giải thuật Canny
Gồm 4 bước:
Giảm nhiễu: Làm mờ ảnh, giảm nhiễu
Tính Gradient và hướng gradient
Non-maximum Suppression (viết tắt NMS): loại bỏ các pixel ở vị trí không phải
cực đại toàn cục
Ngưỡng kép (Double threshold)
Theo dõi cạnh bằng độ trễ (Edge Tracking by Hysteresis)
7
CHƯƠNG III : XÂY DỰNG CHƯƠNG TRÌNH
3.1 Khái quát bài toán
Bài toán nhận dang biển báo giao thông trải qua các bước sau:
Thông qua nguồn dữ liệu cụ thể là video được ghi lại , hệ thống sẽ xác định các
biển báo trong khung hình và dối chiếu với cơ sở dữ liệu được lưu sẵn của hệ
thống và xác định xem hình ảnh nhận được trong đó có phải biển báo giao thông
không. Sau khi nhận dang được đó là biển báo giao thông , hệ thống sẽ xử lý, nhận
dang và đưa thông tin là tên của biển báo giao thông
3.2 Các bước thực hiện bài toán
Thu nhập các ảnh biển báo giao thông
Tạo 1 folder “Dataset” và đưa vào CSDL hình ảnh gồm các biển báo gồm các biển
báo sau đây
8
Kết quả training
Hàm sẽ sử dụng GaussiaanBlur làm mịn ảnh được cho vào , sao đó chuyển ảnh
được làm mịn sang ảnh xám bằng cv2.cvtColor rồi tiếp tục dùng hàm
cv2.Laplacian để làm giảm thiệu độ nhiễu của ảnh. Sau cùng dùng
cv2.convertScaleAbs chia tỷ lệ,lấy giá trị tuyệt đối, chuyển đổi thành loại 8-bit
10
3.3.5 Hàm removeSmallComponents
def removeSmallComponents(image, threshold):
nb_components, output, stats, centroids =
cv2.connectedComponentsWithStats(image, connectivity=8)
sizes = stats[1:, -1]; nb_components = nb_components - 1
11
signature = [float(dist) / max_value for dist in result ]
# Check signature of contour.
temp = sum((1 - s) for s in signature)
temp = temp / len(signature)
if temp < threshold: # is the sign
return True, max_value + 2
else: # is not the sign
return False, max_value + 2
Hàm sẽ tính toán dựa vào tâm vầ chu vi và ngưỡng threshold , tạo một list result
nhập thêm kết quả của mỗi distance theo công thức , tính giá trị max_value bằng
giá trị lớn nhất của list result. Tạo list signature với mỗi giá trị bên trong list bằng
khoảng cách chia cho giá trị lớn nhất của list kết quả . Tạo biến temp bằng tổng
của 1 – s với mỗi s là biến trong list signature. Sau đó gán temp = temp chia cho số
lượng biến trong signature . Nếu như nhỏ hơn thì trả về kết quả đúng tức là biển
báo và max_value +2 ngược lại nếu lớn hơn trả về kết quả sai tức ko phải biển báo
và max_value +2
3.3.8 Các hàm crop sign
def cropContour(image, center, max_distance):
width = image.shape[1]
height = image.shape[0]
top = max([int(center[0] - max_distance), 0])
bottom = min([int(center[0] + max_distance + 1), height-1])
left = max([int(center[1] - max_distance), 0])
right = min([int(center[1] + max_distance+1), width-1])
print(left, right, top, bottom)
return image[left:right, top:bottom]
Các hàm này sẽ cắt phần ảnh biển báo và lưu lại
binary_image = removeSmallComponents(binary_image,
min_size_components)
binary_image = cv2.bitwise_and(binary_image,binary_image,
mask=remove_other_color(image))
#binary_image = remove_line(binary_image)
14
#signs, coordinates = findSigns(image, contours, similitary_contour_with_circle,
15)
sign, coordinate = findLargestSign(original_image, contours,
similitary_contour_with_circle, 15)
text = ""
sign_type = -1
i=0
Hàm này sẽ xử lý dữ liệu ảnh đầu vào và trình chiếu ra ảnh nhị phân sau đó xác
định biển báo nhận được là biển báo gì
15
mask = np.ones(img.shape[:2], dtype="uint8") * 255
if lines is not None:
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(mask,(x1,y1),(x2,y2),(0,0,0),2)
return cv2.bitwise_and(img, img, mask=mask)
Sử dụng biến đổi Hough thể hiện hình ảnh dưới dạng toán học sử dụng
cv2.bitwise_and qua đó loại bỏ viền
3.3.12 Hàm remove_other_color
def remove_other_color(img):
frame = cv2.GaussianBlur(img, (3,3), 0)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_blue = np.array([100,128,0])
upper_blue = np.array([215,255,255])
# Threshold the HSV image to get only blue colors
mask_blue = cv2.inRange(hsv, lower_blue, upper_blue)
Hàm dùng gaussianBlur để làm mịn ảnh sau đó chuyển định dạng ảnh sang không
gian màu HSV, định dạng vùng xanh của ảnh trong không gian màu , chỉnh
ngưỡng để lấy vùng xanh của ảnh, loại bỏ các màu sắc khác
vidcap = cv2.VideoCapture(args.file_name)
fps = vidcap.get(cv2.CAP_PROP_FPS)
width = vidcap.get(3) # float
height = vidcap.get(4) # float
17
success = True
similitary_contour_with_circle = 0.65 # parameter
count = 0
current_sign = None
current_text = ""
current_size = 0
sign_count = 0
coordinates = []
position = []
file = open("Output.txt", "w")
while True:
success,frame = vidcap.read()
if not success:
print("FINISHED")
break
width = frame.shape[1]
height = frame.shape[0]
#frame = cv2.resize(frame, (640,int(height/(width/640))))
frame = cv2.resize(frame, (640,480))
print("Frame:{}".format(count))
#image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
coordinate, image, sign_type, text = localization(frame,
args.min_size_components, args.similitary_contour_with_circle, model, count,
current_sign)
if coordinate is not None:
cv2.rectangle(image, coordinate[0],coordinate[1], (255, 255, 255), 1)
print("Sign:{}".format(sign_type))
if sign_type > 0 and (not current_sign or sign_type != current_sign):
current_sign = sign_type
current_text = text
top = int(coordinate[0][1]*1.05)
18
left = int(coordinate[0][0]*1.05)
bottom = int(coordinate[1][1]*0.95)
right = int(coordinate[1][0]*0.95)
tl = [left, top]
br = [right,bottom]
print(tl, br)
current_size = math.sqrt(math.pow((tl[0]-br[0]),2) + math.pow((tl[1]-
br[1]),2))
# grab the ROI for the bounding box and convert it
# to the HSV color space
roi = frame[tl[1]:br[1], tl[0]:br[0]]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
#roi = cv2.cvtColor(roi, cv2.COLOR_BGR2LAB)
elif current_sign:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
backProj = cv2.calcBackProject([hsv], [0], roiHist, [0, 180], 1)
19
# apply cam shift to the back projection, convert the
# points to a bounding box, and then draw them
(r, roiBox) = cv2.CamShift(backProj, roiBox, termination)
pts = np.int0(cv2.boxPoints(r))
s = pts.sum(axis = 1)
tl = pts[np.argmin(s)]
br = pts[np.argmax(s)]
size = math.sqrt(pow((tl[0]-br[0]),2) +pow((tl[1]-br[1]),2))
print(size)
if sign_type > 0:
top = int(coordinate[0][1])
left = int(coordinate[0][0])
bottom = int(coordinate[1][1])
right = int(coordinate[1][0])
20
position = [count, sign_type if sign_type <= 8 else 8, tl[0], tl[1], br[0],
br[1]]
cv2.rectangle(image, (tl[0], tl[1]),(br[0], br[1]), (0, 255, 0), 1)
font = cv2.FONT_HERSHEY_PLAIN
cv2.putText(image,current_text,(tl[0], tl[1] -15), font, 1,
(0,0,255),2,cv2.LINE_4)
if current_sign:
sign_count += 1
coordinates.append(position)
cv2.imshow('Result', image)
count = count + 1
#Write to video
out.write(image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
file.write("{}".format(sign_count))
for pos in coordinates:
file.write("\n{} {} {} {} {} {}".format(pos[0],pos[1],pos[2],pos[3],pos[4],
pos[5]))
print("Finish {} frames".format(count))
file.close()
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="NLP Assignment Command
Line")
parser.add_argument(
'--file_name',
21
default= "./MVI_1049.avi",
help= "Video to be analyzed"
)
parser.add_argument(
'--min_size_components',
type = int,
default= 300,
help= "Min size component to be reserved"
)
parser.add_argument(
'--similitary_contour_with_circle',
type = float,
default= 0.65,
help= "Similitary to a circle"
)
args = parser.parse_args()
main(args)
Hàm thực hiện chính sẽ training xử lý dữ ảnh dầu vào từ video so sánh đối chiếu
với ảnh trong cơ sở dữ liệu và trình chiếu kết quả ra gồm video output.avi là kết
quả nhận dạng các biển báo có trong video . Đồng thời in ra kết quả training ảnh
22
CHƯƠNG IV: KẾT QUẢ CHẠY CHƯƠNG TRÌNH
Sau khi chạy video đầu vào sẽ xuất ra video output với kết quả nhận dạng các ảnh
sau
23
24
25
CHƯƠNG V: ĐÁNH GIÁ VỀ CHƯƠNG TRÌNH VÀ KẾT
LUẬN
Ưu điểm:
Nhận dạng được một số biển báo cơ bản, đáp ứng cơ bản yêu cầu bài toán đề
ra
Độ chính xác với các biển báo trong cơ sở dữ liệu là tương đối ổn
Nhược điểm:
Hiện tại chương trình mới chỉ nhận dạng được số ít biển báo , thuật toán mới
chỉ có thể xác định các biển báo hình tròn
Sự chính xác của thuật toán vẫn chưa cao , vẫn còn khiếm khuyết và nhầm
lẫn
Khả năng nhận diện còn phụ thuộc vào ánh sáng và môi trường xung quanh
Dữ liệu biển báo còn khá ít chưa nhiều
Hướng phát triển trong tương lai
Phát triển thuật toán nhận diện các biển báo phức tạp hơn
Tạo cơ sở dữ liệu lớn hơn
Sử dụng thuật toán CNN để phân lớp và xử lý ảnh
Lời kết
Sau khi nghiên cứu và tham khảo , em đã có thể xây dựng một chương trình
nhận diện cơ bản các biển báo giao thông, tuy nhiên vẫn còn nhiều thiếu xót và hạn
chế về thuật toán và lập trình.
26