Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 183 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
183
Dung lượng
15,01 MB
Nội dung
BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC SƯ PHẠM KỸ THUẬT THÀNH PHỐ HỒ CHÍ MINH ĐỒ ÁN TỐT NGHIỆP NGÀNH CNKT Ô TÔ NGHIÊN CỨU, THIẾT KẾ VÀ LẮP ĐẶT HỆ THỐNG ĐIỀU KHIỂN ỨNG DỤNG XỬ LÝ ẢNH VÀO XE MINI ĐỂ VẬN CHUYỂN HÀNG HÓA TRONG KHUÔN VIÊN VIỆN GVHD: ThS NGUYỄN THÀNH TUYÊN SVTH: TRẦN VÕ TÂM DUYÊN NGUYỄN PHƯƠNG TÍNH SKL009394 Tp Hồ Chí Minh, tháng 8/2022 TRƯỜNG ĐẠI HỌC SƯ PHẠM KỸ THUẬT THÀNH PHỐ HỒ CHÍ MINH KHOA CƠ KHÍ ĐỘNG LỰC ĐỒ ÁN TỐT NGHIỆP NGHIÊN CỨU, THIẾT KẾ VÀ LẮP ĐẶT HỆ THỐNG ĐIỀU KHIỂN ỨNG DỤNG XỬ LÝ ẢNH VÀO XE MINI ĐỂ VẬN CHUYỂN HÀNG HÓA TRONG KHUÔN VIÊN VIỆN SVTH : TRẦN VÕ TÂM DUYÊN MSSV: 18145323 SVTH : NGUYỄN PHƯƠNG TÍNH MSSV: 18145469 GVHD: ThS NGUYỄN THÀNH TUYÊN Tp Hồ Chí Minh, tháng 08 năm 2022 LỜI CẢM ƠN Trong suốt trình học tập, chúng em nhận quan tâm, hướng dẫn giúp đỡ tận tình thầy Trường Đại học Sư phạm Kỹ thuật TP Hồ Chí Minh nói chung thầy Khoa Cơ khí động lực nói riêng, giúp đỡ gia đình bạn bè với nổ lực học tập thân Lời em xin bày tỏ lòng biết ơn đên Ban giám hiệu quý thầy cô Trường Đại học Sư phạm Kỹ thuật TP Hồ Chí Minh, tạo điều kiện từ vật chất đến tinh thần cổ vũ tinh thần sinh viên Đặc biệt, nhóm chúng em xin gửi lời cảm ơn chân thành đến thầy ThS Nguyễn Thành Tuyên trực tiếp hướng dẫn, giúp đỡ nhóm em hồn thành đồ án Và nhóm em xin gửi lời cảm ơn đến q thầy Khoa Cơ khí động lực, thầy Bộ môn Điện – Điện tử ô tô dạy cho chúng em kiến thức cần có để hồn thành đồ án Tuy nhiên, khơng thể tránh vài thiếu sót trình bày, nhìn nhận đánh giá vấn đề, nhóm chúng em mong nhận góp ý đánh giá thầy mơn để đề tài em hồn thiện Em xin chân thành cảm ơn! Tp Hồ Chí Minh, ngày 08 tháng 08 năm 2022 TRẦN VÕ TÂM DUN NGUYỄN PHƯƠNG TÍNH i TĨM TẮT Đề tài: “Nghiên cứu, thiết kế lắp đặt hệ thống điều khiển ứng dụng xử lý ảnh vào xe mini để vận chuyển hàng hóa khn viên viện” Mơ hình đề tài nghiên cứu chế tạo từ tháng 03 năm 2022 đến tháng 08 năm 2022, Trường Đại học Sư phạm kỹ thuật Thành phố Hồ Chí Minh Trong đề tài, phương pháp xử lý ảnh thuật toán CNN xây dựng dựa lý thuyết Machine Learning Deep Learning Ngơn ngữ lập trình sử dụng Python, giúp cho việc lập trình xử lý ảnh trở nên đơn giản Bên cạnh đó, mơ hình trang bị thêm định vị GPS, giúp người dùng biết vị trí xe đâu Và lưu thông đường không tránh khỏi xuất vật cản, mơ hình cịn trang bị thêm cảnh báo va chạm với người đường/vật cản Nguyên lý hoạt động mơ hình: dựa phương pháp nhận diện lane đường, nhóm chúng em xây dựng thuật tốn cho mơ hình nhận diện lane đường theo khác màu vạch kẻ, sau máy tính tính tốn, thiết lập phương, hướng đường chạy mơ hình xuất hình cho người sử dụng dễ theo dõi Và phương pháp nhận diện biển báo, mơ hình nhận diện chấp hành sau qua biển báo giao thông đường thẳng đường cong; nhiên, dạng đường cong có biển báo “STOP”, máy tính tính tốn góc cong hẹp khơng cho phép xe dừng lại, nhằm đảm bảo an tồn giao thơng Với mục đích vận chuyển hàng hóa, nhóm chúng em có trang bị thêm cho mơ hình thiết bị định vị GPS gửi thơng tin người dùng, dễ dàng biết xe hoạt động vị trí gặp vấn đề đâu để kịp thời xử lý Và xe trang bị cảnh báo vật cản người đường Mục đích đề tài hướng đến xây dựng lý thuyết điều khiển xe tự hành vận chuyển hàng hóa cấp độ 1, làm tảng phục vụ nghiên cứu phịng thí nghiệm Bộ môn Điện – Điện tử ô tô Khoa Cơ khí động lực Trường Đại học Sư phạm kỹ thuật Thành phố Hồ Chí Minh Tuy nhiên, vài vấn đề tồn động nghiên cứu, nhóm lấy làm động lực để cố gắng hồn thiện tương lai không xa ii Max_Cntr_idx= -1 for index, cnt in enumerate(cnts): area = cv2.contourArea(cnt) if area > Max_Cntr_area: Max_Cntr_area = area Max_Cntr_idx = index LargestContour_Found = True if (Max_Cntr_idx!=-1): thresh = cv2.drawContours(thresh, cnts, Max_Cntr_idx, (255,255,255), -1) return thresh, LargestContour_Found def RetLargestContour_OuterLane(gray,minArea): LargestContour_Found = False thresh=np.zeros(gray.shape,dtype=gray.dtype) _,bin_img = cv2.threshold(gray,0,255,cv2.THRESH_BINARY) cnts = cv2.findContours(bin_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1] Max_Cntr_area = Max_Cntr_idx= -1 for index, cnt in enumerate(cnts): area = cv2.contourArea(cnt) if area > Max_Cntr_area: Max_Cntr_area = area Max_Cntr_idx = index LargestContour_Found = True if Max_Cntr_area < minArea: LargestContour_Found = False if ((Max_Cntr_idx!=-1) and (LargestContour_Found)): thresh = cv2.drawContours(thresh, cnts, Max_Cntr_idx, (255,255,255), -1) return thresh, LargestContour_Found def ROI_extracter(image,strtPnt,endPnt): 145 ROI_mask = np.zeros(image.shape, dtype=np.uint8) cv2.rectangle(ROI_mask,strtPnt,endPnt,255,thickness=-1) image_ROI = cv2.bitwise_and(image,ROI_mask) return image_ROI def ExtractPoint(img,specified_row): Point= (0,specified_row) specified_row_data = img[ specified_row-1,:] positions = np.nonzero(specified_row_data) # position[0] = rows = cols if (len(positions)!=0): min_col = positions[0].min() Point=(min_col,specified_row) return Point def RetClosestContour2(gray): Outer_Points_list=[] ClosestContour_Found = False thresh=np.zeros(gray.shape,dtype=gray.dtype) Lane_OneSide=np.zeros(gray.shape,dtype=gray.dtype) Lane_TwoSide=np.zeros(gray.shape,dtype=gray.dtype) _,bin_img = cv2.threshold(gray,0,255,cv2.THRESH_BINARY) cnts = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1] thresh = cv2.drawContours(thresh, cnts, 0, (255,255,255), 1) Row,Bot_Row = FindExtremas(thresh) DetectedContourROI = ROI_extracter(thresh,(0, Row + 25),(thresh.shape[1],Bot_Row15)) cnts2 = cv2.findContours(DetectedContourROI, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1] val=0 LowRow_a=-1 LowRow_b=-1 Euc_row=0 146 Closest_Index=0 First_line= np.copy(Lane_OneSide) cnts_tmp=[] if(len(cnts2)>2): for index_tmp, cnt_tmp in enumerate(cnts2): if((cnt_tmp.shape[0])>50): cnts_tmp.append(cnt_tmp) cnts2 = cnts_tmp for index, cnt in enumerate(cnts2): Lane_OneSide = np.zeros(gray.shape,dtype=gray.dtype) Lane_OneSide = cv2.drawContours(Lane_OneSide, cnts2, index, (255,255,255), 2) Lane_TwoSide = cv2.drawContours(Lane_TwoSide, cnts2, index, (255,255,255), 2) if(len(cnts2)==2): if (index==0): First_line = np.copy(Lane_OneSide) LowRow_a = FindLowestRow(Lane_OneSide) elif(index==1): LowRow_b = FindLowestRow(Lane_OneSide) if(LowRow_a1): for index_tmp, cnt_tmp in enumerate(cnts2): if((cnt_tmp.shape[0])>50): cnts_tmp.append(cnt_tmp) cnts2 = cnts_tmp for index, cnt in enumerate(cnts2): Lane_OneSide = np.zeros(gray.shape,dtype=gray.dtype) Lane_OneSide = cv2.drawContours(Lane_OneSide, cnts2, index, (255,255,255), 1) Lane_TwoSide = cv2.drawContours(Lane_TwoSide, cnts2, index, (255,255,255), 1) if(len(cnts2)==2): if (index==0): First_line = np.copy(Lane_OneSide) LowRow_a = FindLowestRow(Lane_OneSide) elif(index==1): 148 LowRow_b = FindLowestRow(Lane_OneSide) if(LowRow_a MinArea: cnts_Legit.append(cnts[index]) 149 cnts=cnts_Legit CntIdx_BstMatch = [] Closests_Pixels_list = [] for index, cnt in enumerate(cnts): prevmin_dist = 100000 Bstindex_cmp = BstCentroid_a=0 BstCentroid_b=0 for index_cmp in range(len(cnts)-index): index_cmp = index_cmp + index cnt_cmp = cnts[index_cmp] if (index!=index_cmp): min_dist,Centroid_a,Centroid_b = ApproxDistBWCntrs(cnt,cnt_cmp) if(min_dist < prevmin_dist): if (len(CntIdx_BstMatch)==0): prevmin_dist = min_dist Bstindex_cmp = index_cmp BstCentroid_a=Centroid_a BstCentroid_b=Centroid_b else: Present= False for i in range(len(CntIdx_BstMatch)): if ( (index_cmp == i) and (index == CntIdx_BstMatch[i]) ): Present= True if not Present: prevmin_dist = min_dist Bstindex_cmp = index_cmp BstCentroid_a=Centroid_a BstCentroid_b=Centroid_b if ((prevmin_dist!=100000 ) and (prevmin_dist>MaxDistance)): break 150 if (type(BstCentroid_a)!=int): CntIdx_BstMatch.append(Bstindex_cmp) cv2.line(BW_zero,BstCentroid_a,BstCentroid_b,(0,0,255),thickness=2) BW_zero = cv2.cvtColor(BW_zero,cv2.COLOR_BGR2GRAY) BW_Largest,Largest_found = RetLargestContour(BW_zero)#3msec if(Largest_found): return BW_Largest else: return BW Detection\Lanes\utilities.py import numpy as np import cv2 import matplotlib.pyplot as plt import math def Distance(a,b): a_y = a[0,0] a_x = a[0,1] b_y = b[0,0] b_x = b[0,1] distance = math.sqrt( ((a_x-b_x)**2)+((a_y-b_y)**2) ) return distance def Distance_(a,b): return math.sqrt( ( (a[1]-b[1])**2 ) + ( (a[0]-b[0])**2 ) ) def findlaneCurvature(x1,y1,x2,y2): offset_Vert=90# angle found by tan-1 (slop) is wrt horizontal > This will shift to wrt Vetical if((x2-x1)!=0): slope = (y2-y1)/(x2-x1) y_intercept = y2 - (slope*x2) #y= mx+c anlgeOfinclination = math.atan(slope) * (180 / np.pi)#Conversion to degrees else: 151 slope=1000#infinity y_intercept=0#None [Line never crosses the y axis] anlgeOfinclination = 90#vertical line if(anlgeOfinclination!=90): if(anlgeOfinclination 0) if(Edge_Binary_nz_pix[0].shape[0]): Zpoly = np.polyfit(Edge_Binary_nz_pix[1], Edge_Binary_nz_pix[0], 2) Zpoly_Func = np.poly1d(Zpoly) x_new = np.linspace(0, col, col) y_new = Zpoly_Func(x_new) draw_points = (np.asarray([x_new, y_new]).T).astype(np.int32) cv2.polylines(Lane_detected, [draw_points], False, (255,255,255),2) return Lane_detected 152 def average_2b_(Edge_ROI): TrajectoryOnEdge = np.copy(Edge_ROI) row = Edge_ROI.shape[0] # Shape = [row, col, channels] col = Edge_ROI.shape[1] Lane_detected = np.zeros(Edge_ROI.shape,dtype = Edge_ROI.dtype) Edge_Binary = Edge_ROI > Edge_Binary_nz_pix = np.where(Edge_Binary) x_len = Edge_Binary_nz_pix[0].shape[0] if(Edge_Binary_nz_pix[0].shape[0]): y = Edge_Binary_nz_pix[0] x = Edge_Binary_nz_pix[1] Zpoly = np.polyfit(x, y, 2) Zpoly_Func = np.poly1d(Zpoly) x_new = np.linspace(0, col, col) y_new = Zpoly_Func(x_new) x_new = x_new.astype(np.int32) y_new = y_new.astype(np.int32) draw_points = (np.asarray([x_new, y_new]).T).astype(np.int32) cv2.polylines(TrajectoryOnEdge, [draw_points], False, (255,255,255),2) cv2.polylines(Lane_detected, [draw_points], False, (255,255,255),2) return Lane_detected Detection\Signs\SignDetectionApi.py import tensorflow as tf from tensorflow.keras.models import load_model import timeit import os import cv2 import time import numpy as np import config import math 153 detected_img = if config.Detect_lane_N_Draw: write_data = False else: write_data = True draw_detected = True display_images = False model_loaded = False model = sign_classes = ["speed_sign_70","speed_sign_80","stop","No_Sign"] # Trained CNN Classes class SignTracking: def init (self): print("Initialized Object of signTracking class") mode = "Detection" max_allowed_dist = 100 feature_params = dict(maxCorners=100,qualityLevel=0.3,minDistance=7,blockSize=7) lk_params = dict(winSize=(15, 15),maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT,10, 0.03)) color = np.random.randint(0, 255, (100, 3)) known_centers = [] known_centers_confidence = [] old_gray = p0 = [] Tracked_class = mask = def Distance(self,a,b): return math.sqrt( ( (float(a[1])-float(b[1]))**2 ) + ( (float(a[0])-float(b[0]))**2 ) ) def MatchCurrCenter_ToKnown(self,center): match_found = False match_idx = 154 for i in range(len(self.known_centers)): if ( self.Distance(center,self.known_centers[i]) < self.max_allowed_dist ): match_found = True match_idx = i return match_found, match_idx return match_found, match_idx def Reset(self): self.known_centers = [] self.known_centers_confidence = [] self.old_gray = self.p0 = [] signTrack = SignTracking() def image_forKeras(image): image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB) image = cv2.resize(image,(30,30)) #Resize to model size requirement image = np.expand_dims(image, axis=0) return image def SignDetection_Nd_Tracking(gray,cimg,frame_draw,model): if (signTrack.mode == "Detection"): cv2.putText(frame_draw,str(signTrack.Tracked_class),(10,80),cv2.FONT_HERSHEY_P LAIN,0.7,(255,255,255),1) NumOfVotesForCircle = 40 CannyHighthresh = 200 mindDistanBtwnCircles = 100 # kept as sign will likely not be overlapping max_rad = 150 circles = cv2.HoughCircles(gray,cv2.HOUGH_GRADIENT,1,mindDistanBtwnCircles,param1=C annyHighthresh,param2=NumOfVotesForCircle,minRadius=10,maxRadius=max_rad) if circles is not None: circles = np.uint16(np.around(circles)) 155 for i in circles[0,:]: center =(i[0],i[1]) match_found,match_idx = signTrack.MatchCurrCenter_ToKnown(center) radius = i[2] + if (radius !=5): global detected_img detected_img = detected_img + startP = (center[0]-radius,center[1]-radius) endP = (center[0]+radius,center[1]+radius) detected_sign = cimg[startP[1]:endP[1],startP[0]:endP[0]] if(detected_sign.shape[1] and detected_sign.shape[0]): sign = sign_classes[np.argmax(model(image_forKeras(detected_sign)))] if(sign != "No_Sign"): if match_found: signTrack.known_centers_confidence[match_idx] += if(signTrack.known_centers_confidence[match_idx] > 3): circle_mask = np.zeros_like(gray) circle_mask[startP[1]:endP[1],startP[0]:endP[0]] = 255 signTrack.mode = "Tracking" # Set mode to tracking signTrack.Tracked_class = sign # keep tracking frame sign name signTrack.old_gray = gray.copy() signTrack.p0 = cv2.goodFeaturesToTrack(signTrack.old_gray, mask=circle_mask, **signTrack.feature_params) signTrack.mask = np.zeros_like(frame_draw) else: signTrack.known_centers.append(center) signTrack.known_centers_confidence.append(1) cv2.putText(frame_draw,sign,(endP[0]20,startP[1]+10),cv2.FONT_HERSHEY_PLAIN,0.5,(0,0,255),1) if draw_detected: 156 cv2.circle(frame_draw,(i[0],i[1]),i[2],(0,255,0),1) cv2.circle(frame_draw,(i[0],i[1]),2,(0,0,255),3) if write_data: if (sign =="speed_sign_70"): class_id ="0/" elif(sign =="speed_sign_80"): class_id ="1/" elif(sign =="stop"): class_id ="2/" else: class_id ="3/" img_dir = os.path.abspath("Detection/Signs/datasets/") + class_id img_name = img_dir + str(detected_img)+".png" if not os.path.exists(img_dir): os.makedirs(img_dir) cv2.imwrite(img_name , detected_sign) if display_images: cimg_str = 'detected circles' cv2.imshow(cimg_str,frame_draw) cv2.waitKey(1) else: p1, st, err = cv2.calcOpticalFlowPyrLK(signTrack.old_gray, gray, signTrack.p0, None,**signTrack.lk_params) if p1 is None: signTrack.mode = "Detection" signTrack.mask = np.zeros_like(frame_draw) signTrack.Reset() else: good_new = p1[st == 1] good_old = signTrack.p0[st == 1] for i, (new, old) in enumerate(zip(good_new, good_old)): 157 a, b = (int(x) for x in new.ravel()) c, d = (int(x) for x in old.ravel()) signTrack.mask = cv2.line(signTrack.mask, (a, b), (c, d), signTrack.color[i].tolist(), 2) frame_draw = cv2.circle(frame_draw, (a, b), 5, signTrack.color[i].tolist(), -1) frame_draw_ = frame_draw + signTrack.mask np.copyto(frame_draw,frame_draw_) signTrack.old_gray = gray.copy() signTrack.p0 = good_new.reshape(-1, 1, 2) def detect_Signs(frame,frame_draw): global model_loaded if not model_loaded: print(tf. version )#2.4.1 print("************ LOADING MODEL **************") global model model = load_model(os.path.abspath('Detection/Signs/models/4_signClassification_model_nano.h 5'),compile=False) model.summary() model_loaded = True gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) start_signDetection = time.time() cv2.putText(frame_draw,signTrack.mode,(10,10),cv2.FONT_HERSHEY_PLAIN,0.5,(2 55,255,255),1) SignDetection_Nd_Tracking(gray.copy(),frame.copy(),frame_draw,model) end_signDetection = time.time() return signTrack.mode , signTrack.Tracked_class 158 S K L 0