色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

小型雙輪差速底盤視覺循跡功能的實現

jf_72402704 ? 來源:jf_72402704 ? 作者:jf_72402704 ? 2023-03-03 17:05 ? 次閱讀

1. 任務描述

機器人小車上搭載攝像頭,攝像頭采集圖像信息并通過WiFi將信息傳遞給PC端,然后PC端使用OpenCV對攝像頭讀取到的視頻進行灰度化、高斯濾波、腐蝕、膨脹等處理,使圖像分為黑白兩色。PC端進行圖像信息處理并將處理結果傳遞為下位機,下位機接收上位機處理的圖像信息結果后便會控制小車相應運動,小車運動包含前進、左轉、右轉、停止。

pYYBAGQBuqyAKr0iAAAnlrKhp_M591.jpg

?2. 電子硬件

在這個示例中,我們采用了以下硬件,請大家參考:

主控板 Basra(兼容Arduino Uno)
擴展板 Bigfish2.1
電池 7.4V鋰電池
通信 2510通信轉接板
WiFi路由器
其它 攝像頭x1、計算機x1

3. 功能實現

視覺小車巡黑線工作原理:

(1) 攝像頭采集圖像信息;

(2) 通過 WiFi 將圖像信息傳遞給 PC 端(VS2015 配置的 OpenCV 環境);

(3) 在 PC 端使用 OpenCV 對攝像頭讀取到的視頻進行灰度化、高斯濾波、腐蝕、膨脹等處理,使圖像分為黑白兩色,采用 RGB 顏色模型作為黑白顏色判斷;

(4) 將圖像對稱分成左右兩半,分別判斷左、右計算檢測在顯示的攝像范圍內的黑色像素區域所占比例=黑色像素范圍/顯示的攝像范圍;

(5) 比較兩側黑色像素區域所占比例大小確定前進方向,如果左側比例大于右側,則小車左偏離,進行右轉;

(6) PC端進行圖像信息處理,將處理結果傳遞為下位機,下位機控制小車進行相應的運動;

3.1硬件連接

接線說明:

① 將2510通信轉接板連接到擴展板的擴展塢上面;

② 用3根母對母杜邦線將2510通信轉接板與WiFi路由器連接起來,GND-GND、RX-RX、TX-TX;

③ 找到1根USB線,一端連接到2510通信轉接板接口上,另一端連接到WiFi路由器USB接口上;

④ 將攝像頭線連接到WiFi路由器接口上。

poYBAGQBuqyANV06AAAxAGkw5eM599.jpgpYYBAGQBuq2AUsRrAAB42LtiKvQ675.jpg

3.2示例程序

編程環境:Arduino 1.8.19

① 下位機例程:

下位機接收上位機處理的圖像信息結果控制小車相應運動,小車運動包含前進、左轉、右轉、停止。

參考例程代碼(car.ino)如下:【詳細例程源代碼詳見https://www.robotway.com/h-col-113.html】

/*------------------------------------------------------------------------------------

  版權說明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 機器譜 2023-02-02 https://www.robotway.com/

  -----------------------------------------------------------------------------------

/*

  wift car:

  2019/08/19:

  JN

  left: 9, 5;

  right: 10, 6;  

*/



const String FORWARD = "F";

const String BACK = "B";

const String LEFT = "L";

const String RIGHT = "R";

const String STOP = "S";



int speed_left = 41;

int speed_right = 41;



void setup() {

  Serial.begin(9600);

  pinMode(5, OUTPUT);

  pinMode(6, OUTPUT);

 

 

 

  pinMode(9, OUTPUT);

  pinMode(10, OUTPUT);

  Stop();

  delay(1000);

}



void loop() {

  String data = SerialRead();

 

  //if(data != ""){   

    if(data == FORWARD)

      Forward();

    else if(data == BACK)

      Back();

    else if(data == LEFT)

      Left();

    else if(data == RIGHT)

      Right();   

    else if(data == STOP)

      Stop();

// }

}



String SerialRead(){

  String str;

  while(Serial.available()){

    str += char(Serial.read());

  }

  return str;

}



void Forward(){

  analogWrite(9, speed_left);

  analogWrite(5, 0);

  analogWrite(6, 0);

  analogWrite(10, speed_right);

}



void Back(){

  analogWrite(9, 0);

  analogWrite(5, speed_left);

  analogWrite(6, speed_right);

  analogWrite(10, 0);

}



void Left(){

  analogWrite(9, 0);

  analogWrite(5, speed_left);

  analogWrite(6, 0);

  analogWrite(10, speed_right);

}



void Right(){

  analogWrite(9, speed_left);

  analogWrite(5, 0);

  analogWrite(6, speed_right);

  analogWrite(10, 0);

}



void Stop(){

  analogWrite(9, speed_left);

  analogWrite(5, speed_left);

  analogWrite(6, speed_right);

  analogWrite(10,speed_right);

}

② 上位機例程:

上位機(Visual Studio 2015.net下配置OpenCV環境)進行圖像信息處理。下面提供一個參考例程(MainWindow.xaml.cs),大家可嘗試根據實驗效果改寫。

/*******************************************************************************************

版權說明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 機器譜 2023-02-02 https://www.robotway.com/

---------------------------------------------------------------------------------------

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

using System.Windows.Media.Animation;

using System.Threading;

using OpenCvSharp;

using System.Drawing;

using System.Drawing.Imaging;

using System.Net;

using System.Net.Sockets;



namespace Tracking_Car

{

    /// 

    /// Tracking_Car

    /// 

    public partial class MainWindow : System.Windows.Window

    {

        //定義視頻,控制地址以及控制端口變量

        static string CameraIp = "http://192.168.8.1:8083/?action=stream";

        static string ControlIp = "192.168.8.1";

        static string Port = "2001";



        //定義上位機發送的控制命令變量

        //定義命令變量

        string CMD_FORWARD = "", CMD_TURN_LEFT = "", CMD_TURN_RIGHT = "", CMD_STOP = "";



        /*

         * 指針角度對應各顏色

         * 25 -> 紅色

         * 90 -> 綠色

         * 150 -> 藍色

         */

        int ANGLE_LEFT = 0;

        int ANGLE_GO = 0;

        int ANGLE_RIGHT = 0;



        //黑色像素在左右兩側所占比例

        double numOfleft = 0.0;

        double numOfright = 0.0;



        //創建視頻圖像實例

        VideoCapture capture = new VideoCapture(CameraIp); //圖像大小:寬度 X 長度 = 160 X 120;

        Mat frame = new Mat();   //存儲視頻每一幀圖像像素

        Mat result = new Mat(); //存儲二值化圖像



        static byte[] kernelValues = { 0, 1, 0, 1, 1, 1, 0, 1, 0 }; // cross (+)

        Mat kernel = new Mat(3, 3, MatType.CV_8UC1, kernelValues);



        //圖像中心線坐標

        int x1, y1, x2, y2;

        //窗口面積

        float area;



        //視頻顯示切換變量

        Boolean isChange = false;

        //循跡開始開關變量

        Boolean isBegin = false;



        public MainWindow()

        {

            InitializeComponent();

        }



        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            Assignment();

        }



        //變量賦值函數

        private void Assignment()

        {

            ANGLE_LEFT = 25;

            ANGLE_GO = 90;

            ANGLE_RIGHT = 150;



            rateLeft.Height = 10;

            rateRight.Height = 10;



            x1 = 80;

            y1 = 0;

            x2 = x1;

            y2 = 120;

            area = 160 * 120 / 2;



            CMD_FORWARD = "F";

            CMD_TURN_LEFT = "L";

            CMD_TURN_RIGHT = "R";

            CMD_STOP = "S";

        }



        /// 

        /// MatToBitmap(Mat image)

        /// 

        public static Bitmap MatToBitmap(Mat image)

        {

            return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(image);

        }



        /// 

        /// BitmapToBitmapImage(System.Drawing.Bitmap bitmap)

        /// 

        public static BitmapImage BitmapToBitmapImage(Bitmap bitmap)

        {

            using (MemoryStream stream = new MemoryStream())

            {

                bitmap.Save(stream, ImageFormat.Png); //格式選Bmp時,不帶透明度



                stream.Position = 0;

                BitmapImage result = new BitmapImage();

                result.BeginInit();

                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."

                // Force the bitmap to load right now so we can dispose the stream.

                result.CacheOption = BitmapCacheOption.OnLoad;

                result.StreamSource = stream;

                result.EndInit();

                result.Freeze();

                return result;

            }

        }



        //顏色指示動畫函數

        int angelCurrent = 0;

        private void ColorIndicate(int where)

        {

            RotateTransform rt = new RotateTransform();

            rt.CenterX = 130;

            rt.CenterY = 200;



            this.indicatorPin.RenderTransform = rt;



            double timeAnimation = Math.Abs(angelCurrent - where) * 5;

            DoubleAnimation da = new DoubleAnimation(angelCurrent, where, new Duration(TimeSpan.FromMilliseconds(timeAnimation)));

            da.AccelerationRatio = 0.8;

            rt.BeginAnimation(RotateTransform.AngleProperty, da);



            switch (where)

            {

                case 25:

                    dirDisplay.Content = "左轉";

                    break;

                case 90:

                    dirDisplay.Content = "前進";

                    break;

                case 150:

                    dirDisplay.Content = "右轉";

                    break;

                default:

                    dirDisplay.Content = "方向指示";

                    break;

            }



            angelCurrent = where;

        }



        //檢測函數

        private void ColorDetect() {

            //將攝像頭RGB圖像轉化為灰度圖,便于后續算法處理

            Mat gray = frame.CvtColor(ColorConversionCodes.BGR2GRAY);

            //進行高斯濾波

            Mat binary = gray.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);

            //閉運算,先膨脹后腐蝕,消除小型黑洞

            Cv2.Dilate(binary, binary, null);

            Cv2.Erode(binary, binary, kernel);



            result = binary.Clone();

            result.Line(new OpenCvSharp.Point(x1, y1), new OpenCvSharp.Point(x2, y2), new Scalar(255, 255, 255), 1);



            float rateOfleft = 0, rateOfRight = 0;

            var indexer = result.GetGenericIndexer();

            for (int i = 0; i < result.Rows; i++) {

                for (int j = 0; j < result.Cols; j++) {

                    int B = indexer[i, j][0];

                    int G = indexer[i, j][1];

                    int R = indexer[i, j][2];



                    if (B == 0 && G == 0 && R == 0) {

                        if (j <= x1) {

                            numOfleft++;

                        }

                        else

                        {

                            numOfright++;

                        }

                    }

                }

            }



            rateOfleft = (float)(numOfleft) / area * 100;

            rateOfRight = (float)(numOfright) / area * 100;

            rateLeft.Height = rateOfleft;

            rateRight.Height = rateOfRight;

            numOfleft = 0;

            numOfright = 0;

        }



        //命令發送函數

        void SendData(string data)

        {

            try

            {

                IPAddress ips = IPAddress.Parse(ControlIp.ToString());//("192.168.8.1");

                IPEndPoint ipe = new IPEndPoint(ips, Convert.ToInt32(Port.ToString()));//把ip和端口轉化為IPEndPoint實例

                Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//創建一個Socket



                c.Connect(ipe);//連接到服務器



                byte[] bs = Encoding.ASCII.GetBytes(data);

                c.Send(bs, bs.Length, 0);//發送測試信息

                c.Close();

            }

            catch (Exception e)

            {

                MessageBox.Show(e.Message);

            }

        }



        //方向指示更新及命令發送

        private void CommandSend() {

            double l = rateLeft.Height;

            double r = rateRight.Height;



            if (isBegin) {

                if (Math.Abs(l - r) < 20)   //兩側黑色軌跡基本相同,前進

                {

                    ColorIndicate(ANGLE_GO);

                    SendData(CMD_FORWARD);

                }

                else if ((l - r) < -50)     //左側黑色軌跡小于右側,右轉

                {

                    ColorIndicate(ANGLE_RIGHT);

                    SendData(CMD_TURN_RIGHT);



                }

                else if ((l - r) > 50)      //右側黑色軌跡小于左側,左轉

                {

                    ColorIndicate(ANGLE_LEFT);

                    SendData(CMD_TURN_LEFT);

                }

            }

        }



        //視頻顯示函數

        private void ThreadCapShow()

        {



            while (true)

            {

                try

                {

                    capture.Read(frame); // same as cvQueryFrame

                    if (frame.Empty())

                        break;



                    this.Dispatcher.Invoke(

                        new Action(

                            delegate

                            {

                                if (isChange)

                                {

                                    //檢測圖像左右兩側黑色像素所占的比例,并顯示圖像

                                    ColorDetect();

                                    originImage.Source = BitmapToBitmapImage(MatToBitmap(result));

                                    CommandSend();

                                    result = null;

                                }

                                else

                                {

                                    originImage.Source = BitmapToBitmapImage(MatToBitmap(frame));

                                }

                            }

                            ));

                    //Cv2.WaitKey(100);

                    //bitimg = null;

                }

                catch { }

            }

        }



        //加載視頻

        private void loadBtn_Click(object sender, RoutedEventArgs e)

        {

            if (originImage.Source != null) return;

            Thread m_thread = new Thread(ThreadCapShow);

            m_thread.IsBackground = true;

            m_thread.Start();

        }



        //切換視頻顯示,顯示檢測結果

        private void changeBtn_Click(object sender, RoutedEventArgs e)

        {

            if (!isChange)

            {

                isChange = true;

                changeBtn.Content = "返回";

            }

            else

            {

                isChange = false;

                changeBtn.Content = "切換";

                //指針角度歸零

                ColorIndicate(0);

                rateLeft.Height = 10;

                rateRight.Height = 10;

                result = null;

            }

        }


        //循跡開始

        private void bgeinBtn_Click(object sender, RoutedEventArgs e)

        {

            isBegin = true;

        }

        //循跡停止

        private void stopBtn_Click(object sender, RoutedEventArgs e)

        {

            isBegin = false;

            SendData(CMD_STOP);

        }

    }

}

4. 資料內容


?①視覺循跡-程序源代碼
?②視覺循跡-樣機3D文件

審核編輯黃宇

?

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 機器人
    +關注

    關注

    211

    文章

    28618

    瀏覽量

    207916
  • 編程
    +關注

    關注

    88

    文章

    3636

    瀏覽量

    93896
收藏 人收藏

    評論

    相關推薦

    小型平行履帶底盤的制作分享

    小型平行履帶底盤可以通過兩側履帶的 運動 來實現前進、后退、原地轉向、大半徑轉向等基本行駛功能
    的頭像 發表于 01-12 14:50 ?3163次閱讀
    <b class='flag-5'>小型</b>平行履帶<b class='flag-5'>底盤</b>的制作分享

    第13章-循跡功能 STM32智能小車循跡教程 PID循跡算法分析

    、視覺控制、電磁循跡、RTOS等功能。 講解一下我們小車里面的循跡部分,包括紅外基礎使用,無PID循跡和有PID
    的頭像 發表于 08-21 16:27 ?1779次閱讀
    第13章-<b class='flag-5'>循跡</b><b class='flag-5'>功能</b> STM32智能小車<b class='flag-5'>循跡</b>教程 PID<b class='flag-5'>循跡</b>算法分析

    如何搭建實體機器人ros底盤

    目錄介紹一、底盤主控板二、嵌入式開發板1. 與上位機pc的關系2. 與STM32主控板的關系介紹自下而上的分析實體機器人(分輪機器人)搭建中的關鍵過程。一、底盤主控板本部分搭建實體
    發表于 01-20 07:36

    底盤的設計資料分享

    SLAM+語音機器人DIY系列:(四)底盤設計——1.stm32主控硬件設計摘要 運動底盤是移動機器人的重要組成部分,不像激光雷達、IMU、麥克風、音響、攝像頭這些通用部件可以直接買到,很難
    發表于 02-14 06:29

    使用以雙灰度傳感器實現的曲線循跡以及矩形循跡的資料說明

    在這次課程中,我們小組選定的課題是循跡小車,在長達數周的辛苦付出中,我組小車已能實現功能有1.紅遙控小車2.以灰度傳感器實現矩形循跡3.以
    發表于 12-23 08:00 ?12次下載
    使用以雙灰度傳感器<b class='flag-5'>實現</b>的曲線<b class='flag-5'>循跡</b>以及矩形<b class='flag-5'>循跡</b>的資料說明

    小型雙節履帶底盤的制作

    1.運動功能說明 雙節履帶車可以通過兩個驅動輪的運動來實現前進、后退、原地轉向、大半徑轉向等基本行駛功能,并可通過舵機關節模塊進行小臂的
    的頭像 發表于 01-07 10:56 ?867次閱讀
    <b class='flag-5'>小型</b>雙節履帶<b class='flag-5'>底盤</b>的制作

    小型雙輪底盤的制作

    小型雙輪底盤可以通過兩個驅動輪的 運動 來
    的頭像 發表于 01-13 15:17 ?2923次閱讀
    <b class='flag-5'>小型</b><b class='flag-5'>雙輪</b><b class='flag-5'>差</b><b class='flag-5'>速</b><b class='flag-5'>底盤</b>的制作

    小型三節履帶底盤的制作

    雙節履帶車可以通過兩個驅動輪的運動來實現前進、后退、原地轉向、大半徑轉向等基本行駛功能,并可通過舵機關節模塊進行小臂的抬起和落下。通過底盤
    的頭像 發表于 01-29 09:15 ?1232次閱讀
    <b class='flag-5'>小型</b>三節履帶<b class='flag-5'>底盤</b>的制作

    如何實現雙輪底盤躲避懸崖的功能?

    1. 功能說明 ? ? ? ?本實驗使用的樣機為R023樣機小型雙輪底盤。在樣機前方安裝3個
    的頭像 發表于 03-03 17:08 ?399次閱讀
    如何<b class='flag-5'>實現</b><b class='flag-5'>雙輪</b><b class='flag-5'>差</b><b class='flag-5'>速</b><b class='flag-5'>底盤</b>躲避懸崖的<b class='flag-5'>功能</b>?

    如何讓小型雙輪底盤實現雙灰度循跡功能?

    1. 功能說明 ? ?在機器人車體上安裝2個 灰度傳感器 ,實現機器人按照下圖所指定的路線進行導航運動,來模擬倉庫物流機器人按指定路線行進的工作過程。 ? 2. 使用樣機 ? ? 本實驗使用的樣機為
    的頭像 發表于 03-03 17:14 ?494次閱讀
    如何讓<b class='flag-5'>小型</b><b class='flag-5'>雙輪</b><b class='flag-5'>差</b><b class='flag-5'>速</b><b class='flag-5'>底盤</b><b class='flag-5'>實現</b>雙灰度<b class='flag-5'>循跡</b><b class='flag-5'>功能</b>?

    雙輪底盤三灰度循跡功能實現

    1. 功能說明 ? ? 在小型雙輪底盤樣機前方安裝3個 灰度傳感器 ,
    的頭像 發表于 03-03 17:29 ?836次閱讀
    <b class='flag-5'>雙輪</b><b class='flag-5'>差</b><b class='flag-5'>速</b><b class='flag-5'>底盤</b>三灰度<b class='flag-5'>循跡</b><b class='flag-5'>功能</b>的<b class='flag-5'>實現</b>

    小型平行履帶底盤實現雙灰度循跡功能

    1. 功能說明 ? ?在小型平行履帶底盤樣機上安裝2個 灰度傳感器 ,實現機器人沿指定路線進行運動的效果。 2. 使用樣機 ? ?本實驗使用的樣機為R026a樣機。 3.
    的頭像 發表于 03-09 08:52 ?458次閱讀
    <b class='flag-5'>小型</b>平行履帶<b class='flag-5'>底盤</b><b class='flag-5'>實現</b>雙灰度<b class='flag-5'>循跡</b><b class='flag-5'>功能</b>

    電機與無刷電機的區別是什么 電機和無刷電機哪個好

    電機與無刷電機的區別是什么?結構上,無刷電機和電機有相似之處,也有轉子和定子,只不過和
    發表于 03-27 15:07 ?1.2w次閱讀

    DGT-01M四輪移動機器人底盤

    DGT-01M 機器人底盤是一款多功能行業應用的實用新型產品,是一種四輪運載平臺,采用四輪結構,原地轉向,體型小,靈活性強,并且采用模塊化設計,具有相對獨立性、互換性、通用性,模塊
    發表于 12-23 09:37 ?2次下載

    第19.2章-星曈科技 openmv H7 plus openmv視覺循跡功能-完成視覺識別指定區域 OpenMV視覺模塊循跡 STM32F103C8T6視覺巡線

    第19.2章-【星曈科技】openmv H7 plus openmv視覺循跡功能-完成視覺識別指定區域 OpenMV視覺模塊
    的頭像 發表于 08-20 11:28 ?582次閱讀
    主站蜘蛛池模板: 无码137片内射在线影院| 精品国产90后在线观看| 成人亚洲乱码在线| 国产人妻麻豆蜜桃色| 久久精品亚洲AV中文2区金莲| 欧美精品一区二区三区视频| 人妻插B视频一区二区三区| 任你躁国语自产二区在线播放| 百性阁综合社区| 同桌上课把奶露出来给我玩| 亚洲偷偷自拍免费视频在线| 久久国内精品| 涩涩游戏盒| 99久久夜色精品国产亚洲AV卜| 欧美亚洲色帝国| 国产99久久亚洲综合精品西瓜tv | 亚洲男人的天堂久久精品麻豆| 37大但人文艺术A级都市天气| 内射人妻无码色AV麻豆去百度搜| 穿着丝袜被男生强行啪啪| 午夜伦午夜伦锂电影| 空姐厕所啪啪啪| 亚洲天码中字| 欧美日韩另类在线观看视频| 国产AV果冻传奇麻豆| 乌克兰粉嫩摘花第一次| 久99久热只有精品国产99| 99久久精品国内| 摥管专用动态图399期| 国产在线观看成人| qvod快播在线观看| 蜜桃传媒在线观看入口| 亚洲精品久久无码AV片银杏| 给我免费播放片bd国语| 亚洲中文在线精品国产| 日产久久视频| 99久久99| 无码人妻99久久密AV| 久久精品手机观看| 高潮久久久久久久久不卡 | 妹妹好色网|