• 【毕业设计】树莓派寻迹小车 车道线检测 - 机器视觉 单片机 嵌入式 物联网



    0 前言

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

    为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

    🚩 基于树莓派寻迹小车 车道线检测 系统

    🥇学长这里给一个题目综合评分(每项满分5分)

    • 难度系数:4分
    • 工作量:4分
    • 创新点:3分

    🧿 选题指导, 项目分享:

    https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


    1 简介

    自动驾驶汽车是现代世界的新趋势之一。他们使用非常复杂的控制系统和工程技术来操纵车辆。道路车道检测是车辆导航中的重要内容之一。

    本项目使用 Raspberry pi 3 和计算机视觉技术的简单快速的车道检测。为了快速计算,这里尽量避免使用线性回归方法。这种方法在低噪声环境下效果很好,但对于复杂的场景,需要先进的统计和图像处理技术。

    2 主要器件

    • 树莓派 Pi 3型

    • 亚马逊网络服务树莓pi 3夜视摄像头

      在这里插入图片描述

    3 实现效果

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    4 设计原理

    硬件设置

    将相机与您的 Pi 连接

    步骤一(必要库的安装)

    sudo apt-get install libjpeg8-dev  #JPEG支持库
    sudo apt-get install imagemagick
    sudo apt-get install libv4l-dev   #4l是小写"L"
    sudo apt-get install cmake  #下载编译工具
    
    • 1
    • 2
    • 3
    • 4

    步骤二

    git clone https://github.com/jacksonliam/mjpg-streamer.git(若未安装git,则需先进行安装sudo apt-get install git)
    
    
    cd mjpg-streamer/mjpg-streamer-experimental #进入下载目录后进入左侧路径
    
    • 1
    • 2
    • 3
    • 4

    步骤三

    make all  #编译
    sudo make install #安装
    (编译,安装完后的文件)
    
    vi start.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5

    将打开的脚本文件修改成以下截图的样式(将input_uvc.so换成input_raspicam.so)uvc是usb口的摄像头。

    sudo raspi-config #打开摄像头(具体步骤如下)
    
    • 1

    最后选择Finish,再选择Yes进行重启
    步骤四

    ./start.sh 
    
    • 1

    进行启动摄像头(此时摄像头上的红灯亮起)

    在保持摄像头启动的情况下,在浏览器输入 http://树莓派IP地址:8080,回车 显示如下页面,点击页面左侧,Stream栏,显示监视画面

    软件设置

    为 python 安装 OpenCV。按照这些说明安装 OpenCV。这些说明是从https://raspberrypi.stackexchange.com复制的。

    通用:

    sudo apt-get update
    sudo apt-get upgrade
    sudo rpi-update
    sudo reboot
    sudo apt-get install build-essential git cmake pkg-config
    sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
    sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
    sudo apt-get install libxvidcore-dev libx264-dev
    sudo apt-get install libgtk2.0-dev
    sudo apt-get install libatlas-base-dev gfortran
    cd ~
    git clone 
    cd opencv
    git checkout 3.1.0
    cd ~
    git clone 
    cd opencv_contrib
    git checkout 3.1.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    如果您想在 Python 3 中使用 OpenCV:

    sudo apt-get install python3-dev
    wget 
    sudo python3 
    pip install numpy
    cd ~/opencv
    mkdir build
    cd build
    cmake -D CMAKE_BUILD_TYPE=RELEASE \
        -D CMAKE_INSTALL_PREFIX=/usr/local \
        -D INSTALL_C_EXAMPLES=OFF \
        -D INSTALL_PYTHON_EXAMPLES=ON \
        -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
        -D BUILD_EXAMPLES=ON ..
    make -j4
    sudo make install
    sudo ldconfig
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    将以上配置完成大约需要 2 个小时。在此期间,我们可以了解一下 Hough-Transform,这项技术是大多数实用车道检测算法背后的关键。

    霍夫变换(Hough transform)

    霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。Hough变换是图像处理中从图像中识别几何形状的基本方法之一。Hough变换的基本原理在于利用点与线的对偶性,将原始图像空间的给定的曲线通过曲线表达形式变为参数空间的一个点。这样就把原始图像中给定曲线的检测问题转化为寻找参数空间中的峰值问题。也即把检测整体特性转化为检测局部特性。比如直线、椭圆、圆、弧线等。

    matlab代码实现

    I  = imread('circuit.tif');
    rotI = imrotate(I,33,'crop');
    BW = edge(rotI,'canny');
    [H,T,R] = hough(BW);
    imshow(H,[],'XData',T,'YData',R,...
                'InitialMagnification','fit');
    xlabel('\theta'), ylabel('\rho');
    axis on, axis normal, hold on;
    P  = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
    x = T(P(:,2)); y = R(P(:,1));
    plot(x,y,'s','color','white');
    % Find lines and plot them
    lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);
    figure, imshow(rotI), hold on
    max_len = 0;
    for k = 1:length(lines)
       xy = [lines(k).point1; lines(k).point2];
       plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
    
       % Plot beginnings and ends of lines
       plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
       plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
    
       % Determine the endpoints of the longest line segment
       len = norm(lines(k).point1 - lines(k).point2);
       if ( len > max_len)
          max_len = len;
          xy_long = xy;
       end
    end
    
    % highlight the longest line segment
    plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','blue');
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    5 部分核心代码

    from picamera.array import PiRGBArray
    import RPi.GPIO as GPIO
    from picamera import PiCamera
    import time
    import cv2
    import numpy as np
    import math
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(7, GPIO.OUT)
    GPIO.setup(8, GPIO.OUT)
    theta=0
    minLineLength = 5
    maxLineGap = 10
    camera = PiCamera()
    camera.resolution = (640, 480)
    camera.framerate = 30
    rawCapture = PiRGBArray(camera, size=(640, 480))
    time.sleep(0.1)
    for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
       image = frame.array
       gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
       blurred = cv2.GaussianBlur(gray, (5, 5), 0)
       edged = cv2.Canny(blurred, 85, 85)
       lines = cv2.HoughLinesP(edged,1,np.pi/180,10,minLineLength,maxLineGap)
       if(lines !=None):
           for x in range(0, len(lines)):
               for x1,y1,x2,y2 in lines[x]:
                   cv2.line(image,(x1,y1),(x2,y2),(0,255,0),2)
                   theta=theta+math.atan2((y2-y1),(x2-x1))
       #print(theta)GPIO pins were connected to arduino for servo steering control
       threshold=6
       if(theta>threshold):
           GPIO.output(7,True)
           GPIO.output(8,False)
           print("left")
       if(theta<-threshold):
           GPIO.output(8,True)
           GPIO.output(7,False)
           print("right")
       if(abs(theta)<threshold):
          GPIO.output(8,False)
          GPIO.output(7,False)
          print "straight"
       theta=0
       cv2.imshow("Frame",image)
       key = cv2.waitKey(1) & 0xFF
       rawCapture.truncate(0)
       if key == ord("q"):
           break
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    GPIO 引脚连接到 Arduino mega 用于伺服电机控制。

    #include 
    Servo myservo;
    void setup() {
      myservo.attach(10);//attach servo motor PWM(orange) wire to pin 10 
      pinMode(0, INPUT);//attach GPIO 7&8 pins to arduino pin 0&1
      pinMode(1,INPUT);
    void loop() {
               if(digitalRead(0)==HIGH && digitalRead(1)==LOW)
                    {
                          myservo.write(118);
                    }
              if(digitalRead(1)==HIGH && digitalRead(0)==LOW)
                    {
                          myservo.write(62);
                    }
              if(digitalRead(1)==LOW && digitalRead(0)==LOW)
                    {
                           myservo.write(90);
                    } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    6 最后

  • 相关阅读:
    42.集群调优策略—Index 写调优-1
    中国与外国互免签证协定一览表(更新至2022年7月8日)
    remount of the / superblock failed: Permission denied remount failed
    插值与拟合的区别以及如何选取
    Zabbix登录绕过漏洞复现(CVE-2022-23131)
    品牌低价的形式有哪些
    docker-compose 部署示例
    JavaScript:获取实时年份、月份、日期
    95 后阿里 P7 晒出工资单:狠补了这些个技术栈,真的香啊
    Elasticsearch入门教程(未完成)
  • 原文地址:https://blog.csdn.net/m0_71572576/article/details/126398754