当前位置: 代码网 > it编程>前端脚本>Python > 使用python编写一个视觉巡线程序

使用python编写一个视觉巡线程序

2025年01月03日 Python 我要评论
要写一个视觉巡线程序,首先需要安装opencv库来进行图像处理。然后,需要摄像头或者相机来获取视频流或者图片。下面是一个使用opencv进行视觉巡线的简单示例程序:import cv2def foll

要写一个视觉巡线程序,首先需要安装opencv库来进行图像处理。然后,需要摄像头或者相机来获取视频流或者图片。

下面是一个使用opencv进行视觉巡线的简单示例程序:

import cv2

def follow_line():
    # 打开摄像头或者读取视频文件
    cap = cv2.videocapture(0)  # 参数0表示打开默认摄像头
    # 设置视频流的宽和高
    cap.set(cv2.cap_prop_frame_width, 640)
    cap.set(cv2.cap_prop_frame_height, 480)

    while true:
        # 读取一帧图像
        ret, frame = cap.read()
        
        # 进行图像处理,例如灰度化、边缘检测等
        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:
            # 计算轮廓的中心坐标
            m = cv2.moments(contour)
            if m["m00"] != 0:
                cx = int(m["m10"] / m["m00"])
                cy = int(m["m01"] / m["m00"])
                
                # 在图像上标记出线条的中心点
                cv2.circle(frame, (cx, cy), 5, (0, 255, 0), -1)
        
        # 显示图像
        cv2.imshow("frame", frame)
        
        # 按下esc键退出循环
        if cv2.waitkey(1) == 27:
            break
    
    # 释放摄像头或者关闭视频文件
    cap.release()
    cv2.destroyallwindows()

if __name__ == "__main__":
    follow_line()

这是一个简单的巡线程序,它使用canny边缘检测算法来检测图像中的线条,然后计算线条的中心坐标,并在图像上标记出来。你可以根据实际需求进行进一步的图像处理和控制机器人运动的操作。

方法补充

除了上文的方法,小编还为大家整理了python实现视觉slam视觉巡线的方法,有需要的可以了解下

1.简要概述:

通过摄像头采集图像,

将图像灰度化、二值化、膨胀、腐蚀操作后,

提取第400行像素值v,接近于图像底线位置,

提取中间值(这里为白色)的数量和位置,

根据数量和位置,利用简单的数学公式,(首项+尾项)/2,计算出白色的中间位置,

然后对比实际的中间位置320(不需要改),计算出偏移量,

最后根据偏移量计算出电机应有的转角。

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)
    # 转化为灰度图
    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)
    # 膨胀,白区域变大
    dst = cv2.dilate(dst, none, iterations=2)
    cv2.imshow("dst2", dst)
    # # 腐蚀,白区域变小 #
    dst = cv2.erode(dst, none, iterations=6)
    cv2.imshow("dst3", dst)
    # 单看第400行的像素值v
    color = dst[400]
    try:
        # 找到白色的像素点个数,如寻黑色,则改为0
        white_count = np.sum(color == 255)
        # 找到白色的像素点索引,如寻黑色,则改为0
        white_index = np.where(color == 255)
        # 防止white_count=0的报错
        if white_count == 0:
            white_count = 1
        # 找到黑色像素的中心点位置
        # 计算方法应该是边缘检测,计算白色边缘的位置和/2,即是白色的中央位置。
        center = (white_index[0][white_count - 1] + white_index[0][0]) / 2
        # 计算出center与标准中心点的偏移量,因为图像大小是640,因此标准中心是320,因此320不能改。
        direction = center - 320
        print(direction)
    except:
        continue
    if cv2.waitkey(1) & 0xff == ord('q'):
        break
cap.release() #释放cap
cv2.destroyallwindows()#销毁所有窗口

2.树莓派gpio应用

# coding:utf-8 
# 实现树莓派小车的变速控制 
import rpi.gpio as gpio 
# 定义引脚 
in1 = 12 
in2 = 16 
in3 = 18 
in4 = 22 
# 设置gpio口为board编号规范,从左到右,从上到下。 
gpio.setmode(gpio.board) 
# 设置gpio口为输出 
gpio.setup(in1, gpio.out) 
gpio.setup(in2, gpio.out) 
gpio.setup(in3, gpio.out) 
gpio.setup(in4, gpio.out) 
# 设置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 
# 加入摄像头模块,让小车实现自动循迹行驶 
# 思路为:摄像头读取图像,进行二值化,将白色的赛道凸显出来 
# 选择下方的一行像素,黑色为0,白色为255 # 找到白色值的中点 
# 目标中点与标准中点(320)进行比较得出偏移量 
# 根据偏移量来控制小车左右轮的转速 
# 考虑了偏移过多失控->停止;偏移量在一定范围内->高速直行(这样会速度不稳定,已删) 
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 
# 设置gpio口为board编号规范 
gpio.setmode(gpio.board) 
# 设置gpio口为输出 
gpio.setup(pin1, gpio.out) 
gpio.setup(pin2, gpio.out) 
gpio.setup(pin3, gpio.out) 
gpio.setup(pin4, gpio.out) 
# 设置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) 
    # 转化为灰度图 
    gray = cv2.cvtcolor(frame, cv2.color_bgr2gray) 
    # 大津法二值化 
    retval, dst = cv2.threshold(gray, 0, 255, cv2.thresh_otsu) 
    # 膨胀,白区域变大 
    dst = cv2.dilate(dst, none, iterations=2) 
    cv2.imshow("dst", dst)
    # # 腐蚀,白区域变小 # 
    #dst = cv2.erode(dst, none, iterations=6) 
    # 单看第400行的像素值s 
    color = dst[400] 
    try:
        # 找到白色的像素点个数,如寻黑色,则改为0
        white_count = np.sum(color == 255)
        # 找到白色的像素点索引,如寻黑色,则改为0
        white_index = np.where(color == 255)
        # 防止white_count=0的报错
        if white_count == 0:
            white_count = 1
        # 找到黑色像素的中心点位置
        # 计算方法应该是边缘检测,计算白色边缘的位置和/2,即是白色的中央位置。
        center = (white_index[0][white_count - 1] + white_index[0][0]) / 2
        # 计算出center与标准中心点的偏移量,因为图像大小是640,因此标准中心是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) 
    # 右转 
    elif direction >= 0: 
        # 限制在70以内 
        if direction > 70: 
            direction = 70 
        pwm1.changedutycycle(30 + direction) 
        pwm2.changedutycycle(0) 
        pwm3.changedutycycle(30) 
        pwm4.changedutycycle(0) 
    # 左转 
    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()

到此这篇关于使用python编写一个视觉巡线程序的文章就介绍到这了,更多相关python视觉巡线内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

  • 简单聊聊Python中多线程与类方法的交互

    简单聊聊Python中多线程与类方法的交互

    在python编程中,多线程是一种提高程序运行效率的有效手段。特别是在处理i/o密集型任务时,多线程能够显著减少程序的等待时间。然而,多线程编程也带来了新的问题... [阅读全文]
  • python中_init_.py的作用

    最近有几个小伙伴问了我一个经典问题:“__init__.py 到底有啥用?”其实这个问题挺常见的,尤其是对python新手来说简直就是一团迷雾。今天就站在一…

    2025年01月04日 前端脚本
  • python subprocess.run中的具体使用

    python subprocess.run中的具体使用

    一、详解subprocess.run 是 python 3.5 及以上版本中引入的一个函数,用于运行子进程。它是 subprocess 模块的一部分,提供了一种... [阅读全文]
  • python中poetry安装依赖

    前言poetry 是一个用于管理 python 项目的依赖和构建过程的工具。它简化了包管理和虚拟环境的创建,让开发者更容易管理项目的依赖关系。它的出现让我们对依赖卸载更干净。1. …

    2025年01月04日 前端脚本
  • 浅析Python中的基本交易算法应用

    浅析Python中的基本交易算法应用

    在金融市场中,算法交易已成为一种重要的交易方式。它通过自动化的程序来执行交易策略,可以在短时间内分析大量数据并做出交易决策。python语言由于其强大的数据处理... [阅读全文]
  • python中GIL锁的实现

    python中GIL锁的实现

    什么是python的 gil 锁?gil的全称是global interpreter lock(全局解释器锁),它是 cpython(python 的主流实现)... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com