### ch05 程式碼下載 ### $ cd ~/Lab $ wget https://max543.com/debugger/class/python02/PiCamera/Lab/code/ch05.zip $ unzip ch05.zip ### ex5-1 (5-1.py) ### import cv2 rect = ((220, 20), (370, 190)) # 設定 ROI 的座標範圍 (left, top), (right, bottom) = rect # 自訂一個取出子畫面的函數 def roiarea(frame): return frame[top:bottom, left:right] # 自訂一個將 ROI 區域的資料貼回原本畫面的函數 def replaceroi(frame, roi): frame[top:bottom, left:right] = roi return frame cap = cv2.VideoCapture(0) ratio = cap.get(cv2.CAP_PROP_FRAME_WIDTH) / cap.get(cv2.CAP_PROP_FRAME_HEIGHT) WIDTH = 400 HEIGHT = int(WIDTH / ratio) while True: ret, frame = cap.read() frame = cv2.resize(frame, (WIDTH, HEIGHT)) frame = cv2.flip(frame, 1) # 取出子畫面 roi = roiarea(frame) roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # 將處理完的子畫面貼回到原本畫面中 frame = replaceroi(frame, roi) # 在 ROI 範圍處畫個框 cv2.rectangle(frame, rect[0], rect[1], (0,0,255), 2) cv2.imshow('frame', frame) if cv2.waitKey(1) == 27: cv2.destroyAllWindows() break ### ex5-2 (5-2.py) ### import cv2 cap = cv2.VideoCapture('vtest.avi') # OpenCV 範例影片 vtest.avi tracker = cv2.TrackerCSRT_create() roi = None # 宣告一個變數 roi 來儲存欲追蹤的座標位置 while True: ret, frame = cap.read() if roi is None: roi = cv2.selectROI('frame', frame) if roi != (0, 0, 0, 0): # 若有框出一個區域,則將矩形區域傳給追蹤演算法的 init() 函數 tracker.init(frame, roi) success, rect = tracker.update(frame) # # 物體移動到新的區域,update() 計算新區域的座標,將新座標交給 rectangle() 畫出一個矩形區域。 if success: (x, y, w, h) = [int(i) for i in rect] cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 0), 2) cv2.imshow('frame', frame) if cv2.waitKey(66) == 27: cv2.destroyAllWindows() break ### ex5-3 ### # YOLO 官方網址 https://pjreddie.com/darknet/yolo/ # YOLO 預訓練模型的權重檔 https://pjreddie.com/media/files/yolov3.weights # OpenCV + YOLO 物體辨識的官方教學文件 https://opencv-tutorial.readthedocs.io/en/latest/yolo/yolo.html ### ex5-4 (5-3.py) ### import cv2 import numpy as np classes = open("yolo/coco.names").read().strip().split('\n') # 載入分類名稱檔 coco.names np.random.seed(42) # 指定亂數種子 colors = np.random.randint(0, 255, size = (len(classes), 3), dtype = "uint8") # 使用亂數產生不同分類色彩值的 Numpy 陣列 net = cv2.dnn.readNetFromDarknet("yolo/yolov3.cfg", "yolo/yolov3.weights") # 載入 YOLO3 模型的設定檔 (Cfg File) 和權重檔 (Weight File) net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) # 指定優先選擇 OpenCV 後台 # 決定輸出層 ln = net.getLayerNames() ln = [ln[i - 1] for i in net.getUnconnectedOutLayers()] # post_process() 函數處理物體辨識結果 def post_process(img, outputs, conf): H, W = img.shape[:2] # 取出圖片的高 (H) 與寬 (W) boxes = [] # 物體的方框座標 (空串列) confidences = [] # 信心指數值 (空串列) classIDs = [] # 分類編號 (空串列) # 一一取出辨識出的物體 for output in outputs: scores = output[5:] # 取出分數 classID = np.argmax(scores) # 取出分類編號 confidence = scores[classID] # 取得信心指數值 # 取得的信心指數值 confidence ,若大於所傳入的參數值 conf (傳入的 0.5),則表示偵測到物體 if confidence > conf: x, y, w, h = output[:4] * np.array([W, H, W, H]) # 取出物體範圍 p0 = int(x - w//2), int(y - h//2) p1 = int(x + w//2), int(y + h//2) boxes.append([*p0, int(w), int(h)]) confidences.append(float(confidence)) classIDs.append(classID) indices = cv2.dnn.NMSBoxes(boxes, confidences, conf, conf - 0.1) if len(indices) > 0: for i in indices.flatten(): (x, y) = (boxes[i][0], boxes[i][1]) (w, h) = (boxes[i][2], boxes[i][3]) color = [int(c) for c in colors[classIDs[i]]] cv2.rectangle(img, (x, y), (x + w, y + h), color, 2) text = "{}: {:.4f}".format(classes[classIDs[i]], confidences[i]) cv2.putText(img, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) img0 = cv2.imread("horse.jpg") img = img0.copy() blob = cv2.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB = True, crop = False) net.setInput(blob) outputs = net.forward(ln) outputs = np.vstack(outputs) post_process(img, outputs, 0.5) cv2.imshow("window", img) cv2.waitKey(0) cv2.destroyAllWindows()