「樹莓派」使用OpenCV & Numpy機器視覺來巡線

本期講解如何使用OpenCV以及Numpy來分析畫面中的黑線或白線的所在位置,從而實現機器視覺來巡線。

我們可以從黑色背景上尋白線也可以從白色背景上尋黑線

你可以將這個功能應用在你自己的機器人上面

所需代碼:

CVline:

<code>#!/usr/bin/env/python3 # File name : RPiCam.py # Date: 2019/12/23 import cv2 import zmq import base64 import picamera from picamera.array import PiRGBArray import numpy as np IP = '192.168.3.11' camera = picamera.PiCamera() camera.resolution = (640, 480) camera.framerate = 20 rawCapture = PiRGBArray(camera, size=(640, 480)) context = zmq.Context() footage_socket = context.socket(zmq.PAIR) footage_socket.connect('tcp://%s:5555'%IP) print(IP) linePos_1 = 380 linePos_2 = 430 lineColorSet = 255 for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): frame_image = frame.array frame_findline = cv2.cvtColor(frame_image, cv2.COLOR_BGR2GRAY) retval, frame_findline = cv2.threshold(frame_findline, 0, 255, cv2.THRESH_OTSU) frame_findline = cv2.erode(frame_findline, None, iterations=6) colorPos_1 = frame_findline[linePos_1] colorPos_2 = frame_findline[linePos_2] try: lineColorCount_Pos1 = np.sum(colorPos_1 == lineColorSet) lineColorCount_Pos2 = np.sum(colorPos_2 == lineColorSet) lineIndex_Pos1 = np.where(colorPos_1 == lineColorSet) lineIndex_Pos2 = np.where(colorPos_2 == lineColorSet) if lineColorCount_Pos1 == 0: lineColorCount_Pos1 = 1 if lineColorCount_Pos2 == 0: lineColorCount_Pos2 = 1 left_Pos1 = lineIndex_Pos1[0][lineColorCount_Pos1-1] right_Pos1 = lineIndex_Pos1[0][0] center_Pos1 = int((left_Pos1+right_Pos1)/2) left_Pos2 = lineIndex_Pos2[0][lineColorCount_Pos2-1] right_Pos2 = lineIndex_Pos2[0][0] center_Pos2 = int((left_Pos2+right_Pos2)/2) center = int((center_Pos1+center_Pos2)/2) except: center = None pass print(center) try: cv2.line(frame_image,(left_Pos1,(linePos_1+30)),(left_Pos1,(linePos_1-30)),(255,128,64),1) cv2.line(frame_image,(right_Pos1,(linePos_1+30)),(right_Pos1,(linePos_1-30)),(64,128,255),) cv2.line(frame_image,(0,linePos_1),(640,linePos_1),(255,255,64),1) cv2.line(frame_image,(left_Pos2,(linePos_2+30)),(left_Pos2,(linePos_2-30)),(255,128,64),1) cv2.line(frame_image,(right_Pos2,(linePos_2+30)),(right_Pos2,(linePos_2-30)),(64,128,255),1) cv2.line(frame_image,(0,linePos_2),(640,linePos_2),(255,255,64),1) cv2.line(frame_image,((center-20),int((linePos_1+linePos_2)/2)),((center+20),int((linePos_1+linePos_2)/2)),(0,0,0),1) cv2.line(frame_image,((center),int((linePos_1+linePos_2)/2+20)),((center),int((linePos_1+linePos_2)/2-20)),(0,0,0),1) except: pass encoded, buffer = cv2.imencode('.jpg', frame_image) jpg_as_text = base64.b64encode(buffer) footage_socket.send(jpg_as_text) rawCapture.truncate(0) /<code>

PC:

<code>#!/usr/bin/python3 # File name : PC.py # Author : William # Date: 2019/11/21 import cv2 import zmq import base64 import numpy as np context = zmq.Context() footage_socket = context.socket(zmq.PAIR) footage_socket.bind('tcp://*:5555') while True: frame = footage_socket.recv_string() img = base64.b64decode(frame) npimg = np.frombuffer(img, dtype=np.uint8) source = cv2.imdecode(npimg, 1) cv2.imshow("Stream", source) cv2.waitKey(1)/<code>