RoBoard魔人的機器人日誌

2019/5/14

[Jetson Nano] 用攝影機來定位物體

大家好,

今天本魔要來和大家分享如何用 Jetson Nano 接攝影機來定位物體,

和上一篇一樣,

定位物體的方法有下列這些:

  1. facenet (偵測臉部)
  2. multiped (偵測複數行人與行李箱)
  3. pednet (偵測行人)
  4. coco-bottle (偵測瓶子)
  5. coco-dog (偵測狗)

如果各位用的鏡頭是 CSI camera 就只要直接執行指令就可以了,輸入:
$ ./detectnet-camera facenet
$ ./detectnet-camera multiped
$ ./detectnet-camera pednet
$ ./detectnet-camera coco-bottle
$ ./detectnet-camera coco-dog
$ ./detectnet-camera                # 不輸入時使用 multiped 方法

但因為本魔使用的是 USB Camera,

所以必須要更改設定,

首先輸入:
$ ls -ltrh /dev/video*
你將會找到所有視訊裝置的編號,

知道我們的 USB Camera 是編號幾之後就可以更改程式的設定了,輸入:
$ sudo gedit ~/jetson-inference/detectnet-camera/detectnet-camera.cpp
然後將 DEFAULT_CAMERA 改為剛剛我們找到的編號,

本魔電腦偵測到的為 0,如圖:



修改完成後就可以儲存並關閉 gedit 了。

接著我們要重新編譯程式,輸入:
$ cd ~/getson-inference/build/
$ cmake ../
$ make
$ sudo make install
完成後就可以回到 bin 資料夾,並執行程式囉!輸入:
$ cd aarch64/bin/
$ ./detectnet-camera facenet
本魔使用的是 facenet 來定位臉部,

畢竟要辨識其它物體還要特地找有點麻煩。

第一次建造模型同樣會花費較多時間,所以請耐心等待一下。

接著你會看到你的鏡頭畫面被顯示在螢幕上了,

我們快點來試試看有什麼臉可以辨識吧!

首先是 3D 列印的一個達爾文頭像:


看來只能定位到本魔的臉而已呢!

 接著拿蕾姆的公仔來試試:


看來還是只有定位出本魔阿!

再來試試之前一樣用 3D 列印印出的骷髏頭,

本魔還幫它加上了頭髮和眼睛嘴巴,


竟然辨識到了!

是不是本魔畫得太維妙維肖了呢!?



本篇的教學就到此為止啦~,

各位一樣可以嘗試用看看其它的方法哦!

喜歡這個系列的話可以追蹤我的blogger哦,

Jetson Nano 官方教學基本上到此為止啦~,

接下來的教學因為要在 PC 上跑,

所以還不確定什麼時候會整理出來和大家分享哦。

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/13

[Jetson Nano] 定位圖像中的物體

大家好,

今天本魔要繼續和分享如何用 Jetson Nano 來定位圖像中的物體,

在官方提供的範例中我們可以辨識定位以下這些物體:

  1. ped-100 (偵測行人)
  2. multiped-500 (偵測複數行人與行李箱)
  3. facenet-120 (偵測臉部)
  4. coco-airplane (偵測飛機)
  5. coco-bottle (偵測瓶子)
  6. coco-chair (偵測椅子)
  7. coco-dog (偵測狗)

知道有這些方法可以使用後我們可以很簡單的執行 detectnet-console 這隻程式來做辨識定位,

開啟 Terminal 視窗並輸入:
$ cd ~/jetson-inference/build/aarch64/bin/
進入 bin 資料夾後執行 detectnet-console,輸入:
$ ./detectnet-console dog_0.jpg output-1.jpg coco-dog
將 dog_0 這張圖輸出成 output-1 並使用 coco-dog 這個方法,

在第一次執行時一樣會較花時間,請耐心等待。

執行完後在資料夾下會多出一張 output-1 的圖片,

我們可以打開來看:


有狗的部分都被框起來了呢!

看來有準確的定位。

我們繼續執行指令,輸入:
$ ./detectnet-console dog_1.jpg output-2.jpg coco-dog
因為 coco-dog 有執行過了,所以這一次會較快一些,

完成後一樣開啟 output-2 來看:


我們繼續執行:
$ ./detectnet-console dog_2.jpg output-3.jpg coco-dog


在馬路上趴著的狗也能定位出來呢!

接著辨識瓶子,因為 coco-bottle 和剛剛的方法不同,所以一樣會執行較久,輸入:
$ ./detectnet-console bottle_0.jpg output-4.jpg coco-bottle

這隻貓可愛

即使旁邊有其它物體也能準確定位出瓶子,

接著試試看飛機:
$ ./detectnet-console airplane_0.jpg output-5.jpg coco-airplane


本魔嚴重懷疑這張官方提供的圖是P上去的!

這兩台飛機飛這麼近沒有航空法上的問題嗎!?

總之還是辨識出來了~,

接著辨識複數行人與行李箱:
$ ./detectnet-console peds-001.jpg output-6.jpg multiped


 4個人都被準確的定位出來了呢!

繼續執行:
$ ./detectnet-console peds-002.jpg output-7.jpg multiped


即便只有背影也不會誤判呢!

接著試試一個較複雜的圖,輸入:
$ ./detectnet-console peds-003.jpg output-8.jpg multiped


行人和行李箱都被定位出來了,

但中間的女生拖著的行李箱似乎沒定位到呢!

是不是那裡的人太密集了呢?

繼續看下一張,輸入:
$ ./detectnet-console peds-004.jpg output-9.jpg multiped


側身照一樣可以精準的定位出來,

接下來本魔也測試了一下非官方提供的圖片:


沒錯,就是當時的史加納團隊照,

即使蹲著也可以定位呢!

但為什麼本魔被特別再框一次了呢!?

看來 Jetson Nano 連本魔的霸王色霸氣都能定位到阿,太厲害了!



本篇的教學就到此為止啦~,

各位一樣可以嘗試用其它圖片來測試看看哦!

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期都會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/10

[Jetson Nano] 用攝影機來辨識物體

大家好,

上一篇已經和各位介紹了如何讀取圖片來辨識物體,

今天本魔要繼續和大家分享如何用 Jetson Nano 接 USB Camera 來辨識物體。

如果各位用的鏡頭是 CSI camera 就只要直接執行指令就可以了,輸入:
$ cd ~/jetson-inference/build/aarch64/bin/
$ ./imagenet-camera googlenet
但因為本魔使用的是 USB Camera,

所以必須要更改設定,

首先輸入:
$ ls -ltrh /dev/video*
你將會找到所有視訊裝置的編號,

知道我們的 USB Camera 是編號幾之後就可以更改程式的設定了,輸入:
$ sudo gedit ~/jetson-inference/imagenet-camera/imagenet-camera.cpp
然後將 DEFAULT_CAMERA 改為剛剛我們找到的編號,

本魔電腦偵測到的為 0,如圖:


修改完成後就可以儲存並關閉 gedit 了。

接著我們要重新編譯程式,輸入:
$ cd ~/jetson-inference/build/
$ cmake ../
$ make
$ sudo make install
完成後就可以回到 bin 資料夾,並執行程式囉!輸入:
$ cd aarch64/bin/
$ ./imagenet-camera googlenet 
接著你會看到你的鏡頭畫面被顯示在螢幕上了:


左上角可以看到和之前範例一樣的物體描述,

本魔隨意拿了手邊的幾樣東西來測試了一下:


隨手拿了一個馬克杯辨識結果為 Coffee mug,正確!


手上剛好握著滑鼠,來辨識一下,Computer mouse,正確!


夏天快到了,拿個小電風扇來辨識一下,Electric fan,電扇無誤!


針筒...,syringe,注射器無誤!

咦?你問我為什麼會帶著針筒?

不要問,很可怕!



本篇的教學就到此為止啦~,

各位一樣可以嘗試用其它物品來測試看看哦!

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期都會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/9

[Jetson Nano] 自己寫一個圖像識別程式

大家好,

今天本魔要繼續和大家分享如何自己寫一個圖像識別程式,

上一篇我們已經用官方的範例做出分類辨識的效果了,

今天要來做一個更完整的辨識程式,

首先打開 Terminal 視窗並輸入:


$ mkdir ~/my-recognition
$ cd ~/my-recognition
$ touch my-recognition.cpp
$ touch CMakeLists.txt
完成後你會看到家目錄下多了一個 my-recognition 資料夾,

並且裡面有 my-recognition.cpp 與 CMakeLists.txt,

如下圖:


接著我們下載一些官方提供的範例圖片:

$ wget https://github.com/dusty-nv/jetson-inference/raw/master/data/images/black_bear.jpg 
$ wget https://github.com/dusty-nv/jetson-inference/raw/master/data/images/brown_bear.jpg
$ wget https://github.com/dusty-nv/jetson-inference/raw/master/data/images/polar_bear.jpg 
完成後會多出三張圖:


接著可以來寫程式囉!

用 gedit 來開啟 my-recognition.cpp 編輯:
$ gedit my-recognition.cpp

接著在 貼上下面的程式:

// include imageNet header for image recognition
#include 

// include loadImage header for loading images
#include 

// main entry point
int main( int argc, char** argv )
{
 // a command line argument containing the image filename is expected,
 // so make sure we have at least 2 args (the first arg is the program)
 if( argc < 2 )
 {
  printf("my-recognition:  expected image filename as argument\n");
  printf("example usage:   ./my-recognition my_image.jpg\n");
  return 0;
 }

 // retrieve the image filename from the array of command line args
 const char* imgFilename = argv[1];

 // these variables will be used to store the image data and dimensions
 // the image data will be stored in shared CPU/GPU memory, so there are
 // pointers for the CPU and GPU (both reference the same physical memory)
 float* imgCPU    = NULL;    // CPU pointer to floating-point RGBA image data
 float* imgCUDA   = NULL;    // GPU pointer to floating-point RGBA image data
 int    imgWidth  = 0;       // width of the image (in pixels)
 int    imgHeight = 0;       // height of the image (in pixels)
  
 // load the image from disk as float4 RGBA (32 bits per channel, 128 bits per pixel)
 if( !loadImageRGBA(imgFilename, (float4**)&imgCPU, (float4**)&imgCUDA, &imgWidth, &imgHeight) )
 {
  printf("failed to load image '%s'\n", imgFilename);
  return 0;
 }

 // load the GoogleNet image recognition network with TensorRT
 // you can use imageNet::ALEXNET to load AlexNet model instead
 imageNet* net = imageNet::Create(imageNet::GOOGLENET);

 // check to make sure that the network model loaded properly
 if( !net )
 {
  printf("failed to load image recognition network\n");
  return 0;
 }

 // this variable will store the confidence of the classification (between 0 and 1)
 float confidence = 0.0;

 // classify the image with TensorRT on the GPU (hence we use the CUDA pointer)
 // this will return the index of the object class that the image was recognized as (or -1 on error)
 const int classIndex = net->Classify(imgCUDA, imgWidth, imgHeight, &confidence);


 // make sure a valid classification result was returned 
 if( classIndex >= 0 )
 {
  // retrieve the name/description of the object class index
  const char* classDescription = net->GetClassDesc(classIndex);

  // print out the classification results
  printf("image is recognized as '%s' (class #%i) with %f%% confidence\n", 
     classDescription, classIndex, confidence * 100.0f);
 }
 else
 {
  // if Classify() returned < 0, an error occurred
  printf("failed to classify image\n");
 }

 // free the network's resources before shutting down
 delete net;

 // this is the end of the example!
 return 0;
}



簡單的說明一下這段程式在做些什麼,

首先用第二個引數來讀取圖片,然後載入圖像辨識網路 (GOOGLENET),

接著會將載入的圖片做分類與看相似度,

最後將結果輸出至銀幕上。

接著我們要寫 CMakeLists.txt,一樣用 gedit 來開啟 CMakeLists.txt 編輯:
$ gedit CMakeLists.txt
接著貼上:

# require CMake 2.8 or greater
cmake_minimum_required(VERSION 2.8)

# declare my-recognition project
project(my-recognition)

# import jetson-inference and jetson-utils packages.
# note that if you didn't do "sudo make install"
# while building jetson-inference, this will error.
find_package(jetson-utils)
find_package(jetson-inference)

# CUDA and Qt4 are required
find_package(CUDA)
find_package(Qt4)

# setup Qt4 for build
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})

# compile the my-recognition program
cuda_add_executable(my-recognition my-recognition.cpp)

# link my-recognition to jetson-inference library
target_link_libraries(my-recognition jetson-inference)



完成後就可以編譯囉!輸入:

$ cd ~/my-recognition
$ cmake .
$ make
完成後就可以執行程式來進行辨識啦!

輸入:
$ ./my-recognition polar_bear.jpg

輸出結果 ice bear、polar bear 是北極熊無誤!

輸入:
$ ./my-recognition brown_bear.jpg


結果是 brown bear 棕熊無誤。

輸入:
$ ./my-recognition black_bear.jpg


結果是 American black bear 美國黑熊,「真的假的?連國家都辨識的出來阿?」

玩到這裡同事 Vic 忽然說,該不會它只能辨識這些官方圖片吧?

所以本魔就上網找了一隻猴子,畢竟也是有毛髮的動物,到底有沒有辦法辨別呢?


結果是 guenon monkey 正確,本魔找的時候不知道牠的品種是長尾猴呢!

結果 Vic 不信邪說了:「該不會檔名會影響它的辨識吧?」

所以本魔又找了一張金剛的圖片,並將檔名存為 aaa.jpg,


結果是 gorilla 大猩猩,本魔還以為會辨識出 King kong 呢!

上網查了一下,原來金剛就是大猩猩,只是金剛是通俗的講法,

所以還是算辨識正確!



本篇的教學就到此為止啦~,

各位一樣可以嘗試用其它圖片來測試看看哦!

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期都會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/8

[Jetson Nano] 用 ImageNet 對圖像進行分類

大家好,

今天本魔要繼續和大家分享如何用 Jetson Nano 來做圖像分類,

這是上次我們安裝的 Hello AI World 其中一個範例,

首先我們要將目錄切換至我們上次編譯完的目錄下,開啟 Terminal 視窗並輸入:
$ cd jetson-inference/build/aarch64/bin
然後執行 imagenet-console 這支程式,輸入:
$ ./imagenet-console orange_0.jpg output_0.jpg
第一個參數 orange_0.jpg 是你要讓他進行分類的圖片,

第二個參數 output_0.jpg 則是你要匯出的圖片。

在第一次運行程序時,TensorRT 可能需要幾分鐘優化網絡,

但運行完成後,優化的網絡將會存起來,因此之後的運行速度會比較快。

完成後各位可以到資料夾下看看是不是多了一個 output_0.jpg 的圖片,


或是各位可以輸入:
$ display orange_0.png
也可以看到輸出後的圖片:


可以看到左上角它會顯示分類的名稱與相似度,

很明顯這是一顆柳橙,

我們可以再匯入其它圖片試試,
$ ./imagenet-console granny_smith_1.jpg output_1.jpg


一樣可以用 display 指令來開啟圖片:
$ display output_1.png

很明顯這是一顆青蘋果,

它的英文讓本魔困惑了一下,Granny Smith?史密斯奶奶?

結果上了 wiki 查了一下原來是澳洲青蘋,

以下是 wiki 的描述:
它是在1868年在澳大利亞一次無意中由一位「老奶奶」瑪麗亞·安·舍伍德·史密斯(Maria Ann Sherwood Smith)繁殖的。因此其英文名成為紀念這位史密斯老奶奶(Granny Smith)

原來是個人名阿!長知識了呢!



本篇的教學就到此為止啦~,

各位可以嘗試用其它圖片來測試看看哦!

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期都會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/7

[Jetson Nano] 官方範例介紹與安裝

大家好,

今天本魔要和大家分享 NVIDIA 在 Jetson Nano 上的開源範例。

我們可以在 NVIDIA 的官方教學中找到兩個範例,

一個是 JetBot


它是用 Jetson Nano 控制的一台開源機器小車。

而另一個就是我將會拿來做系列教學的 Hello AI World

在此系列你將能夠操作 Jetson Nano 做出一系列目前最夯的 AI 深度學習的範例,

雖然不需寫程式,但能讓我們快速的瞭解如何使用這種 AI 程式。

那就開始今天的正題吧!

首先第一步,當然就是要安裝啦~!

在這之前我們可以看到 Github 下的教學要我們先安裝 JetPack 這個開發套件,

但我們並不需要做這一步哦,

各位有印象先前本魔有教各位製作 Jetson Nano 開機碟吧?

而這個 Jetson Nano Developer Kit SD 卡映像檔已經包含了這個 JetPack開發套件了,

所以使用官方 Imgae 的 Jetson Nano 系統上並不需要去做安裝囉!

「那我們今天就可以下課囉!」 (被毆

開玩笑的啦~本魔怎麼可能那麼黑心呢?

我們來下載原始碼並安裝吧!

我們在鍵盤上按下 Ctrl + Alt + T 來開啟 Terminal 視窗


首先我們要安裝 CMake 這隻程式,輸入:
$ sudo apt-get install git cmake
在使用 sudo 指令時會被要求輸入密碼哦,

這時候只要直接鍵入並按 ENTER 就可以了,

接下來系統就會開始下載並安裝 CMake 了。

接下來我們要將 Github 上的源始碼給 Clone 下來,

這一步會花較多時間,畢竟要將整隻程式下載下來,輸入:


$ cd ~/
$ git clone https://github.com/dusty-nv/jetson-inference
$ cd jetson-inference
$ git submodule update --init
完成後你會發現 Home 目錄下多了一個 jetson-inference 資料夾,

裡面包含了我們之後會用到的原始碼。

接下來我們在裡面建造一個資料夾 build,並執行 CMake:
$ mkdir build
$ cd build
$ cmake ../


執行 CMake 也是需要一點時間呢,

這隻程式將會幫忙生成 Makefile。

有了 Makefile ,當然就要來編譯並進行安裝啦~,
$ make
$ sudo make install
這兩個指令一樣會花較多時間。

完成 make

完成 make install

完成後基本上就可以準備來玩範例囉!

你會發現在 build 資料夾下多了許多檔案,

我們甚至可以直接開啟範例程式的原始碼來看看他們做了些什麼,

例如我們可以輸入:
$ gedit aarch64/include/imageNet.h
這可以讓我們看到 imageNet 這個圖像辨識程式的標頭檔,

或是也可以輸入:
$ gedit aarch64/include/detectNet.h
來看看 detectNet 這個圖像偵測的標頭檔。

我們可以稍微理解一下這些 AI 程式的架構,

程式碼的注解也相當完整呢!



本篇的教學就到此為止啦~,

下一篇將會和大家分享如何用這個 Hello AI World 辨識圖片中的物體哦!

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期都會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/3

[教學] 在Jetson Nano上安裝 ROS 系統

大家好,

今天要和大家分享如何在 Jetson Nano 上安裝 ROS,

畢竟這是本魔要學習的課題嘛~。

ROS上支援 Ubuntu 18.04 的版本為 ROS Melodic Morenia

此版本是 2018 年 5 月釋出的,並且將會支援到 2023 年的 5 月。

為了安裝 ROS,首先我們要在鍵盤上按下 Ctrl + Alt + T 來開啟 Terminal 視窗,



啟動後輸入指令,讓 Jetson Nano 接受 packages.ros.org 的軟體:
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
之後新增 apt 金鑰,輸入:
$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
並更新 apt,輸入:
$ sudo apt update
接下來就可以安裝 ROS 啦!在此安裝的是桌面版,輸入:
$ sudo apt install ros-melodic-desktop
在此注意一下:
雖然 ROS Desktop Full 是個更完整版本,但不建議用於嵌入式平台,
因為 2D / 3D 的模擬器都將同時安裝上去,這會使 ROM 佔用太多空間,
並且可能會因為計算量太大而無法在 Jetson Nano 上使用。

接下來做 rosdep 的初始化設定,輸入:
$ sudo rosdep init 
$ rosdep update
並且設置環境變數,輸入:
$ echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc 
$ source ~/.bashrc
到此為止 ROS 算是安裝完成囉!

但好像沒什麼實際感對吧?

那我們來跑個 ROS 的控制烏龜範例吧!

首先我們要安裝 turtlesim 功能包,輸入:
$ sudo apt install ros-melodic-turtlesim
安裝完成後我們需要按下 Ctrl + Alt + T 三次,開啟三個 Terminal 視窗,

首先第一個 Terminal 視窗,我們要創建 ROS Master 節點,輸入:


$ roscore
接著在第二個 Terminal 視窗,我們要開啟 turtlesim 的模擬小烏龜節點,輸入:
$ rosrun turtlesim turtlesim_node
最後在第三個 Terminal 視窗,我們要開啟 turtlesim 的鍵盤控制節點,輸入:
$ rosrun turtlesim turtle_teleop_key
最終你將會看到這樣的畫面,


在鍵盤控制節點的視窗點擊方向鍵即可控制小烏龜移動囉!


看得出來本魔畫的是什麼嗎XD?



本篇的教學就到此為止啦~,

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期都會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:

2019/5/2

[教學] 製作 Jetson Nano 開機碟

大家好,

今天本魔要來和大家分享如何製作一個 Jetson Nano 專用的開機 MicroSD 卡,

教學基本上與官方一致,如果不是英文苦手可以直接至官網學習

因為本魔的電腦是使用 Windows 作業系統,所以以下教學僅適用於 Windows,

如果有強烈需求請於下方留言,本魔會視情況增加其它系統的安裝教學。

首先我們需要以下的東西:

  • MicroSD 卡 (最低16GB)
  • MicroSD 卡讀卡機
  • USB 鍵盤滑鼠
  • 電腦顯示器(HDMI 或 DP)
  • 網路線或 USB WIFI 提供上網
  • Micro-USB 電源(5V⎓2A)
  • 一台電腦

接著下載並安裝 SD Memory Card formatter

安裝完後將 MicroSD 卡用讀卡機接上電腦,



開啟 SD Card Formatter 應用程式,你會看到這樣的畫面:


選取 MicroSD 卡的磁碟並直接點選 Format 選項,其餘設定使用預設即可。


點選是(Y),之後將會開始進行格式化。

接下來我們要準備將映像檔燒錄至 MicroSD 上,


並且安裝並執行 Etcher


首先選取方才我們下載的 Jetson Nano Developer Kit SD 卡映像檔,


接著選取 MicroSD 卡的磁碟,


選取完成後就可以按下 Flash 開始燒錄了!


過程需要花費一點時間,各位可以先去泡個茶來喝🍵。

完成後就可以將 MicroSD 卡戳上 Jetson Nano 了,

還記得插槽的位置嗎?

在 SoC Module 的背面哦!


然後接上鍵盤滑鼠與網路以及 Micro-USB 電源,

啟動後就可以看到 NVIDIA 的開機畫面,


接下來會有一連串的設定,

照著輸入即可,建議系統選用英文,各位若是有需要再改成中文,

否則在 Terminal 視窗下要切換中文路徑會非常麻煩。

閱讀過 licenses 後選取我同意並繼續

系統語言

鍵盤設定

時區設定

名稱與密碼,建議設置容易輸入的密碼
因為使用 sudo 指令時會需要經常性輸入密碼


系統重開之後就可以登入 Ubuntu 的作業系統囉!


下面這些介紹直接 Next 關掉就可以了!



可以看到在 Jetson Nano 上的系統是 Ubuntu 18.04 LTS,並且已經預先安裝好一些開發套件了!




本篇的教學就到此為止啦~,

喜歡這個系列的話可以追蹤我的blogger哦,

本魔近期會不定時更新此系列教學,

如果有疑問或任何指教也歡迎在下方留言提出哦!
Share:
技術提供:Blogger.

追蹤者