使用python編寫一個視覺巡線程序
要寫一個視覺巡線程序,首先需要安裝OpenCV庫來進(jìn)行圖像處理。然后,需要攝像頭或者相機來獲取視頻流或者圖片。
下面是一個使用OpenCV進(jìn)行視覺巡線的簡單示例程序:
import cv2 def follow_line(): # 打開攝像頭或者讀取視頻文件 cap = cv2.VideoCapture(0) # 參數(shù)0表示打開默認(rèn)攝像頭 # 設(shè)置視頻流的寬和高 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) while True: # 讀取一幀圖像 ret, frame = cap.read() # 進(jìn)行圖像處理,例如灰度化、邊緣檢測等 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 50, 150) # 在圖像上找到線條或者輪廓 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍歷每個輪廓 for contour in contours: # 計算輪廓的中心坐標(biāo) M = cv2.moments(contour) if M["m00"] != 0: cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) # 在圖像上標(biāo)記出線條的中心點 cv2.circle(frame, (cx, cy), 5, (0, 255, 0), -1) # 顯示圖像 cv2.imshow("Frame", frame) # 按下Esc鍵退出循環(huán) if cv2.waitKey(1) == 27: break # 釋放攝像頭或者關(guān)閉視頻文件 cap.release() cv2.destroyAllWindows() if __name__ == "__main__": follow_line()
這是一個簡單的巡線程序,它使用Canny邊緣檢測算法來檢測圖像中的線條,然后計算線條的中心坐標(biāo),并在圖像上標(biāo)記出來。你可以根據(jù)實際需求進(jìn)行進(jìn)一步的圖像處理和控制機器人運動的操作。
方法補充
除了上文的方法,小編還為大家整理了python實現(xiàn)視覺SLAM視覺巡線的方法,有需要的可以了解下
1.簡要概述:
通過攝像頭采集圖像,
將圖像灰度化、二值化、膨脹、腐蝕操作后,
提取第400行像素值v,接近于圖像底線位置,
提取中間值(這里為白色)的數(shù)量和位置,
根據(jù)數(shù)量和位置,利用簡單的數(shù)學(xué)公式,(首項+尾項)/2,計算出白色的中間位置,
然后對比實際的中間位置320(不需要改),計算出偏移量,
最后根據(jù)偏移量計算出電機應(yīng)有的轉(zhuǎn)角。
2.邊緣檢測實驗
#!/usr/bin/env python3 # 識別的是中線為白色 import cv2 import numpy as np # center定義 center = 320 # 打開攝像頭,圖像尺寸640*480(長*高),opencv存儲值為480*640(行*列) cap = cv2.VideoCapture(0) while (1): ret, frame = cap.read() cv2.imshow("recognize_face", frame) # 轉(zhuǎn)化為灰度圖 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow("gray", gray) # 大津法二值化 retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU) cv2.imshow("dst", dst) # 膨脹,白區(qū)域變大 dst = cv2.dilate(dst, None, iterations=2) cv2.imshow("dst2", dst) # # 腐蝕,白區(qū)域變小 # dst = cv2.erode(dst, None, iterations=6) cv2.imshow("dst3", dst) # 單看第400行的像素值v color = dst[400] try: # 找到白色的像素點個數(shù),如尋黑色,則改為0 white_count = np.sum(color == 255) # 找到白色的像素點索引,如尋黑色,則改為0 white_index = np.where(color == 255) # 防止white_count=0的報錯 if white_count == 0: white_count = 1 # 找到黑色像素的中心點位置 # 計算方法應(yīng)該是邊緣檢測,計算白色邊緣的位置和/2,即是白色的中央位置。 center = (white_index[0][white_count - 1] + white_index[0][0]) / 2 # 計算出center與標(biāo)準(zhǔn)中心點的偏移量,因為圖像大小是640,因此標(biāo)準(zhǔn)中心是320,因此320不能改。 direction = center - 320 print(direction) except: continue if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() #釋放cap cv2.destroyAllWindows()#銷毀所有窗口
2.樹莓派GPIO應(yīng)用
# coding:utf-8 # 實現(xiàn)樹莓派小車的變速控制 import RPi.GPIO as gpio # 定義引腳 in1 = 12 in2 = 16 in3 = 18 in4 = 22 # 設(shè)置GPIO口為BOARD編號規(guī)范,從左到右,從上到下。 gpio.setmode(gpio.BOARD) # 設(shè)置GPIO口為輸出 gpio.setup(in1, gpio.OUT) gpio.setup(in2, gpio.OUT) gpio.setup(in3, gpio.OUT) gpio.setup(in4, gpio.OUT) # 設(shè)置PWM波,頻率為500Hz pwm1 = gpio.PWM(in1, 500) pwm2 = gpio.PWM(in2, 500) pwm3 = gpio.PWM(in3, 500) pwm4 = gpio.PWM(in4, 500) # 初始化 pwm1.start(0) pwm2.start(0) pwm3.start(0) pwm4.start(0) # 定義向前 def go(): pwm1.ChangeDutyCycle(50) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(50) pwm4.ChangeDutyCycle(0) # 定義向右 def right(): pwm1.ChangeDutyCycle(50) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(30) pwm4.ChangeDutyCycle(0) # 定義向左 def left(): pwm1.ChangeDutyCycle(30) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(50) pwm4.ChangeDutyCycle(0) # 定義向后 def back(): pwm1.ChangeDutyCycle(0) pwm2.ChangeDutyCycle(50) pwm3.ChangeDutyCycle(0) pwm4.ChangeDutyCycle(50) # 定義停止 def stop(): pwm1.ChangeDutyCycle(0) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(0) pwm4.ChangeDutyCycle(0) pwm1.stop() pwm2.stop() pwm3.stop() pwm4.stop() gpio.cleanup()
3.視覺巡線
# coding:utf-8 # 加入攝像頭模塊,讓小車實現(xiàn)自動循跡行駛 # 思路為:攝像頭讀取圖像,進(jìn)行二值化,將白色的賽道凸顯出來 # 選擇下方的一行像素,黑色為0,白色為255 # 找到白色值的中點 # 目標(biāo)中點與標(biāo)準(zhǔn)中點(320)進(jìn)行比較得出偏移量 # 根據(jù)偏移量來控制小車左右輪的轉(zhuǎn)速 # 考慮了偏移過多失控->停止;偏移量在一定范圍內(nèi)->高速直行(這樣會速度不穩(wěn)定,已刪) import RPi.GPIO as gpio import time import cv2 import numpy as np import serial ser=serial.Serial('/dev/ttyAMA0',115200,timeout=1) # 定義引腳 pin1 = 12 pin2 = 16 pin3 = 18 pin4 = 22 # 設(shè)置GPIO口為BOARD編號規(guī)范 gpio.setmode(gpio.BOARD) # 設(shè)置GPIO口為輸出 gpio.setup(pin1, gpio.OUT) gpio.setup(pin2, gpio.OUT) gpio.setup(pin3, gpio.OUT) gpio.setup(pin4, gpio.OUT) # 設(shè)置PWM波,頻率為500Hz pwm1 = gpio.PWM(pin1, 500) pwm2 = gpio.PWM(pin2, 500) pwm3 = gpio.PWM(pin3, 500) pwm4 = gpio.PWM(pin4, 500) # pwm波控制初始化 pwm1.start(0) pwm2.start(0) pwm3.start(0) pwm4.start(0) # center定義 center = 320 # 打開攝像頭,圖像尺寸640*480(長*高),opencv存儲值為480*640(行*列) cap = cv2.VideoCapture(0) while (1): ret, frame = cap.read() cv2.imshow("recognize_face", frame) # 轉(zhuǎn)化為灰度圖 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 大津法二值化 retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU) # 膨脹,白區(qū)域變大 dst = cv2.dilate(dst, None, iterations=2) cv2.imshow("dst", dst) # # 腐蝕,白區(qū)域變小 # #dst = cv2.erode(dst, None, iterations=6) # 單看第400行的像素值s color = dst[400] try: # 找到白色的像素點個數(shù),如尋黑色,則改為0 white_count = np.sum(color == 255) # 找到白色的像素點索引,如尋黑色,則改為0 white_index = np.where(color == 255) # 防止white_count=0的報錯 if white_count == 0: white_count = 1 # 找到黑色像素的中心點位置 # 計算方法應(yīng)該是邊緣檢測,計算白色邊緣的位置和/2,即是白色的中央位置。 center = (white_index[0][white_count - 1] + white_index[0][0]) / 2 # 計算出center與標(biāo)準(zhǔn)中心點的偏移量,因為圖像大小是640,因此標(biāo)準(zhǔn)中心是320,因此320不能改。 direction = center - 320 print(direction) ser.write(direction) except: continue # 停止 if abs(direction) > 250: pwm1.ChangeDutyCycle(0) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(0) pwm4.ChangeDutyCycle(0) # 右轉(zhuǎn) elif direction >= 0: # 限制在70以內(nèi) if direction > 70: direction = 70 pwm1.ChangeDutyCycle(30 + direction) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(30) pwm4.ChangeDutyCycle(0) # 左轉(zhuǎn) elif direction < -0: if direction < -70: direction = -70 pwm1.ChangeDutyCycle(30) pwm2.ChangeDutyCycle(0) pwm3.ChangeDutyCycle(30 - direction) pwm4.ChangeDutyCycle(0) if cv2.waitKey(1) & 0xFF == ord('q'): break # 釋放清理 cap.release() cv2.destroyAllWindows() pwm1.stop() pwm2.stop() pwm3.stop() pwm4.stop() gpio.cleanup()
到此這篇關(guān)于使用python編寫一個視覺巡線程序的文章就介紹到這了,更多相關(guān)python視覺巡線內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Loguru日志封裝裝飾器實現(xiàn)過程
這篇文章主要介紹了Python Loguru日志封裝裝飾器實現(xiàn)過程,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-03-03Django實現(xiàn)jquery select2帶搜索的下拉框
最近在開發(fā)一個web應(yīng)用中需要用到帶搜索功能下拉框,本文實現(xiàn)Django實現(xiàn)jquery select2帶搜索的下拉框,感興趣的小伙伴們可以參考一下2021-06-06深入探討PythonLogging模塊的高級用法與性能優(yōu)化
在Python應(yīng)用程序中,日志處理是一項至關(guān)重要的任務(wù),本文將探索Logging模塊的高級用法,包括日志級別、格式化、處理程序等方面的功能,需要的可以參考下2024-04-04Python3基礎(chǔ)教程之遞歸函數(shù)簡單示例
這篇文章主要給大家介紹了關(guān)于Python3基礎(chǔ)教程之遞歸函數(shù)簡單示例的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Python3具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06