×

使用OpenCV的车道跟随机器人

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-26

分享资料个

描述

Small Intro

在这个项目中,我 使用OpenCVRaspberry pi设计了一个车道跟随机器人

poYBAGNY0PqAAF9QAAFUdW8kQe0964.png
样本输出
 

Step 1 : Importing Libraries

首先我们导入 OpenCV、Numpy、数学和串行库。

import cv2
import numpy as np
import math
import serial

Step 2 : Read Image from your directory

image = cv2.imread(r'C:\Users\aasai\Desktop\new1.jpeg')
 
 
 
pYYBAGNY0P2AJGGRAAHxcoztTiI58.jpeg
 
1 / 2Raspi 相机拍摄的图像
 

Step 3 : Color Conversion

将我们的 BGR 图像转换为灰色。灰度图像仅包含 [0-255] 范围内的值。

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
poYBAGNY0P-AHTVvAAB_RS_taN8837.png
灰度图像
 

Step 4 : Image Smoothing

图像模糊/平滑图像平滑以减少噪点。它是在各种低通滤波器内核的帮助下完成的。这里我们使用了高斯核。了解更多关于不同内核的信息。点击这里

# given input image, kernel width =5 height = 5, Gaussian kernel standard deviation
k_width = 5
k_height = 5
blurred = cv2.GaussianBlur(gray, (k_width, k_height), 0)
poYBAGNY0QKAKCNDAABQAuvrJSM575.png
平滑图像
 

Step 5 : Edge Detection

Canny边缘检测算法是一种流行的边缘检测算法,用于检测图像中的边缘。为了保留图像中的高梯度值,我们选择低阈值和高阈值。这将帮助我们保留图像中的强边缘。

# Find the edges in the image using canny detector
threshold1 = 80
threshold2 = 80
edged = cv2.Canny(blurred, threshold1, threshold2)
pYYBAGNY0QSARSBSAABu4rfyowA742.png
边缘检测
 

Step 6 : Find Lines

霍夫变换是一种特征提取方法,用于检测图像中的简单形状,如圆形、线条等。在这里,您可以了解更多相关信息。

# it will return line coordinates,it will return 3darray.
lines = cv2.HoughLinesP(edged,1,np.pi/180,max_slider,minLineLength,maxLineGap)

for x in range(0, len(lines)):
    for x1,y1,x2,y2 in lines[x]:
        # draw line in image using cv2.line function.
        cv2.line(image,(x1,y1),(x2,y2),(255,0,0),3)
        theta=theta+math.atan2((y2-y1),(x2-x1))
        print(theta)

About theta calculation:

atan2() 函数以弧度为单位返回值,表示 -pi 和 pi 之间的值,表示 (x, y) 点与正 x 轴的角度 theta。

poYBAGNY0QeAZZ-aAABGJ1jseAg791.jpg
来源:https://www.learnopencv.com/hough-transform-with-opencv-c-python/
 
 
 
 
poYBAGNY0QmAUARjAACcg2gE_Yg571.png
 
1 / 2
 

您可以使用这行代码获取第一行的坐标。

for x1,y1,x2,y2 in lines[0]:
pYYBAGNY0QyAYoI2AAAHHCf3jU0387.png
行[0]的输出
 

Step 7 : Decision Making Part

现在,我们要设置阈值,根据阈值和θ值之间的差异,我们将向arduino发送命令以驱动特定方向的电机。

threshold=5
if(theta>threshold):
    print("Go left")
if(theta<-threshold):
    print("Go right")
if(abs(theta)<threshold):
    print("Go straight")

Step 8 : Integrate

poYBAGNY0Q6AKI8QAAE9vrqsQCU514.png
示意图
 

Arduino Code :

Arduino将从 Raspberry Pi 串行端口接收命令。

// assign pin num
int right_pin = 12;
int left_pin = 13;
int const ENA = 10;  
int const ENB = 11; 


// initial command
int command = 0;

void setup()

{
  pinMode(right_pin, OUTPUT);
  pinMode(left_pin, OUTPUT);
  pinMode(ENA, OUTPUT);   // set all the motor control pins to outputs
  pinMode(ENB, OUTPUT);

  Serial.begin(115200);
  
  while (!Serial);
  
  Serial.println("Opencv Lane Detect Autonomous Robot");

}

void loop() {

if (Serial.available())

{
  //int state = Serial.parseInt();
  int state = Serial.read();

  if (state == 4)
  {
    
    digitalWrite(left_pin, LOW);
    digitalWrite(right_pin, HIGH);
    digitalWrite(ENA, HIGH);
    digitalWrite(ENB, HIGH);
    Serial.println("Left");
  }

  if (state == 2)
  {
    digitalWrite(left_pin, LOW);
    digitalWrite(right_pin, LOW);
    digitalWrite(ENA, HIGH);
    digitalWrite(ENB, HIGH);
    Serial.println("Right");
    Serial.println("Reverse");
  }

  if (state == 3)
  {
    digitalWrite(left_pin, HIGH);
    digitalWrite(right_pin, LOW);
    digitalWrite(ENA, HIGH);
    digitalWrite(ENB, HIGH);

  Serial.println("Right");
  }
  if (state == 1)
  {
    digitalWrite(left_pin, HIGH);
    digitalWrite(right_pin, HIGH);
    digitalWrite(ENA, HIGH);
    digitalWrite(ENB, HIGH);

  Serial.println("Forward");
  }
  if (state == 5)
  {
    digitalWrite(left_pin, LOW);
    digitalWrite(right_pin, LOW);
    digitalWrite(ENA, LOW);
    digitalWrite(ENB, LOW);

  Serial.println("Stop");
  }
}
}
poYBAGNY0RSAfwUpAALj6T63YF027.jpeg
 

 

感谢信

感谢OpenCV Python 文档

Thanks阅读这个项目。希望这个项目能给你一些关于 OpenCV Lane Follow 机器人的见解,你可以按照给定的步骤做同样的事情。

我在沉默中努力工作,我的机器人制造噪音。
poYBAGNY0RaAO5FaAABP1ONlmvo543.jpg
来源:https://www.google.com/url?sa=i&url=https%3A%2F%2Fitaliandirectory.eu%2Fwill-robots-eventually-able-insert-key-lock%2F&psig=AOvVaw0q_aR0pBfINA7scyxOyS4x&ust=1588470268487000&source=images&cd= vfe&ved=0CA0QjhxqFwoTCODb4YaHlOkCFQAAAAAdAAAAABAP
 

 


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'使用OpenCV的车道跟随机器人',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);