วันศุกร์ที่ 21 กันยายน พ.ศ. 2561

โปรเจค หุ่นยนต์ติดตามวัตถุ Raspberry Pi + OpenCV



โปรเจคหุ่นยนต์ติดตามวัตถุ Raspberry Pi + OpenCV โปรเจคนี้จะทำหุ่นยนต์ติดตามวัตถุ จากการถ่ายภาพของ Camera V2 Module  โดยใช้ลูกบอลสีเหลือง ในตัวอย่างใช้เป็นลูกเทนนิสเป็นวัตถุ แล้วให้หุ่นยนต์ติดตามวัตถุนั้น



อุปกรณ์ที่ใช้











ขั้นตอนการทำงาน


1.
 การติดตั้ง Linux ให้กับ Raspberry โดยใช้ไฟล์ image


2. การใช้งาน GPIO ใน Raspberry Pi ด้วย Python



3. การประกอบหุ่นยนต์ Raspberry Pi


4. วิธีเปิดใช้งาน Remote Desktop ไปยัง Raspberry Pi


5. ทดสอบการเคลื่อนที่ของหุ่นยนต์ Raspberry Pi



6. การติดตั้ง OpenCV 3 และการติดตามวัตถุ



7. โปรเจค หุ่นยนต์ติดตามวัตถุ Raspberry Pi + OpenCV



7.1 การตรวจหาสีของ Raspberry Pi และ OpenCV

โดยปกติแล้วกล้องของเราจะทำงานร่วมกับโหมดสี RGB ซึ่งสามารถเข้าใจได้โดยคิดว่าเป็นสีที่เป็นไปได้ทั้งหมดซึ่งสามารถทำได้จากไฟสามสีสำหรับสีแดงเขียวและน้ำเงิน แต่เราจะทำงานกับ BGR (สีฟ้า, สีเขียว, สีแดง) แทน

ตามที่อธิบายไว้ด้านบน BGR มีพิกเซลแสดงด้วยพารามิเตอร์ 3 สีฟ้าสีเขียวและสีแดง พารามิเตอร์แต่ละตัวมักมีค่าตั้งแต่ 0 ถึง 255 (หรือ O ถึง FF ในเลขฐานสิบหก) ตัวอย่างเช่นพิกเซลสีน้ำเงินบริสุทธิ์บนหน้าจอคอมพิวเตอร์ของคุณจะมีค่า B 255 ค่าของ G เท่ากับ 0 และค่า R เท่ากับ 0



OpenCV ทำงานร่วมกับรูปแบบสี HSV (Hue, Saturation, Value) ที่เป็นตัวแทนทางเลือกของรูปแบบสี RGB ซึ่งออกแบบโดยนักวิจัยกราฟิกคอมพิวเตอร์ในยุค 70 ให้สอดคล้องกับวิสัยทัศน์ของมนุษย์มากขึ้นในการรับรู้
คุณลักษณะของสี


ดังนั้นถ้าต้องการติดตามสีบางอย่างโดยใช้ OpenCV ต้องกำหนดโดยใช้ HSV Model

สมมติว่าต้องติดตามวัตถุสีเหลืองเป็นลูกเทนนิสที่แสดงภาพข้างต้น ที่ง่ายก็คือการหาองค์ประกอบของ BGR โดยสามารถใช้โปรแกรมออกแบบใด ๆ เพื่อค้นหาสี เช่น โปรแกรม Photoshop

1. เลือกไปที่สี ที่ต้องการ เช่นสีของลูกเทนนิส
2. คลิกเพื่อดูค่าสี
3. แสดงค่าสี BRG




จะได้โมเดลแบบ BGR คือ

Blue: 51
Green: 254
Red: 237


ต่อไปเราต้องแปลงโมเดล BGR (51, 254, 237) ให้เป็นแบบ HSV ซึ่งจะกำหนดด้วยขอบเขตบนและล่าง จากนั้นให้เรียกใช้โค้ดด้านล่าง โดยมีขั้นตอนดังนี้ 

เปิดโปรแกรม เทอมินอล (Root Terminal)

สร้างโฟลเดอร์ tracking_robot โดยใช้คำสั่ง


mkdir tracking_robot


เปิดโปรแกรม Python 3 (IDLE) เขียนโค้ดดังนี้



'''
BGR to HSV Color Conversion
    Create by Henry Dang ==> See the tutorial here:
    https://henrydangprg.com/2016/06/26/color-detection-in-python-with-opencv/
Adapted by Marcelo Rovai - MJRoBot.org @8Feb18
'''

import sys
import numpy as np
import cv2

blue = sys.argv[1]
green = sys.argv[2]
red = sys.argv[3]  

color = np.uint8([[[blue, green, red]]])
hsv_color = cv2.cvtColor(color, cv2.COLOR_BGR2HSV)

hue = hsv_color[0][0][0]

print("Lower bound is :"),
print("[" + str(hue-10) + ", 100, 100]\n")

print("Upper bound is :"),

print("[" + str(hue + 10) + ", 255, 255]")


หรือดาวน์โหลดโค้ดจากลิงค์ด้านล่าง



https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/bgr_hsv_converter.py


Save ไปที่ โฟลเดอร์ tracking_robot และตั้งชื่อเป็น bgr_hsv_converter.py

การทดสอบต้องมีสภาพแวดล้อมแบบเสมือนของ OpenCV  คือ ต้องเห็นข้อความ (cv) ก่อนหน้าพร้อมท์ 


โดยใช้คำสั่ง

source ~/.profile 
workon cv
cd tracking_robot
python bgr_hsv_converter.py 51 254 237
.



โปรแกรมจะพิมพ์ขอบด้านบนและด้านล่างของสีวัตถุของเรา ซึ่งเราจะใช้ค่านี้ไปเขียนโค้ด หุ่นยนต์ติดตามวัตถุ ที่ colorLower และ colorUpper ต่อไป




7.2 เขียนโค้ด หุ่นยนต์ติดตามวัตถุ


เปิดโปรแกรม Python 3 (IDLE) เขียนโค้ดดังนี้



#######
# Author: RobotSiam.com
# Date: 22 September 2018
#######

# import the necessary packages
from __future__ import print_function
from imutils.video import VideoStream
import argparse
import imutils
import time
import cv2
import os
import RPi.GPIO as GPIO

#set GPIO numbering mode and define output pins
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(35,GPIO.OUT)
GPIO.setup(37,GPIO.OUT)

def forWard():
 print("Going Forwards")
 GPIO.output(11,True)
 GPIO.output(13,False)
 GPIO.output(35,True)
 GPIO.output(37,False)
 time.sleep(0.1)
 GPIO.output(11,False)
 GPIO.output(13,False)
 GPIO.output(35,False)
 GPIO.output(37,False)

def backWard():
 print("Going Backwards")
 GPIO.output(11,False)
 GPIO.output(13,True)
 GPIO.output(35,False)
 GPIO.output(37,True)
 time.sleep(0.1)
 GPIO.output(11,False)
 GPIO.output(13,False)
 GPIO.output(35,False)
 GPIO.output(37,False)

def turnRight():
 print("Going Right")
 GPIO.output(11,False)
 GPIO.output(13,False)
 GPIO.output(35,True)
 GPIO.output(37,False)
 time.sleep(0.1)
 GPIO.output(11,False)
 GPIO.output(13,False)
 GPIO.output(35,False)
 GPIO.output(37,False)

def turnLeft():
 print("Going Left")
 GPIO.output(11,True)
 GPIO.output(13,False)
 GPIO.output(35,False)
 GPIO.output(37,False)
 time.sleep(0.1)
 GPIO.output(11,False)
 GPIO.output(13,False)
 GPIO.output(35,False)
 GPIO.output(37,False)

def Stop():
 print("Stopping")
 GPIO.output(11,False)
 GPIO.output(13,False)
 GPIO.output(35,False)
 GPIO.output(37,False)

# position servos to present object at center of the frame
def mapPosition (x, y):

    if (x < 200):
        turnLeft()

    elif (x > 300):
        turnRight()

    elif (x >= 200 and x <= 300):
        forWard()
      

# initialize the video stream and allow the camera sensor to warmup
print("[INFO] waiting for camera to warmup...")
vs = VideoStream(0).start()
time.sleep(2.0)

# define the lower and upper boundaries of the object
# to be tracked in the HSV color space
colorLower = (22, 100, 100)
colorUpper = (42, 255, 255)


# loop over the frames from the video stream
while True:
# grab the next frame from the video stream, Invert 180o, resize the
# frame, and convert it to the HSV color space
frame = vs.read()
frame = imutils.resize(frame, width=500)
frame = imutils.rotate(frame, angle=0)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# construct a mask for the object color, then perform
# a series of dilations and erosions to remove any small
# blobs left in the mask
mask = cv2.inRange(hsv, colorLower, colorUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)

# find contours in the mask and initialize the current
# (x, y) center of the object
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
center = None

# only proceed if at least one contour was found
if len(cnts) > 0:
# find the largest contour in the mask, then use
# it to compute the minimum enclosing circle and
# centroid
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

# only proceed if the radius meets a minimum size
if radius > 10:
# draw the circle and centroid on the frame,
# then update the list of tracked points
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)

# position Servo at center of circle
mapPosition(int(x), int(y))


# show the frame to our screen
cv2.imshow("Frame", frame)

# if [ESC] key is pressed, stop the loop
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
            break

# do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff \n")
Stop()
GPIO.cleanup()
cv2.destroyAllWindows()
vs.stop()





หรือดาวน์โหลดโค้ดจากลิงค์ด้านล่าง



https://drive.google.com/open?id=1vS7fyTyQcsKD5ECAk4a3dcjlPopU2Q0S


Save ไปที่ โฟลเดอร์ tracking_robot และตั้งชื่อเป็น following_robot.py




7.3 ทดสอบการทำงาน หุ่นยนต์ติดตามวัตถุ


เสียบสาย USB ของ Power Bank ต่อเข้ากับ 5V  Micro USB ของบอร์ด Raspberry Pi ยังไม่ต้องเปิดเพาเวอร์สวิตซ์ ของ Motor Driver


การทดสอบต้องมีสภาพแวดล้อมแบบเสมือนของ OpenCV  คือ ต้องเห็นข้อความ (cv) ก่อนหน้าพร้อมท์ 

ทดสอบการติดตามวัตถุของหุ่นยนต์โดยใช้คำสั่ง

source ~/.profile 
workon cv
cd 
tracking_robot
python following_robot.py




โปรแกรมเริ่มทำงาน




การตัดสินใจของหุ่นยนต์มีดังนี้




x 0 , y 0 ของ หน้าจอภาพ Frame อยู่ที่มุมขวา-ล่าง

x >= 200 and x <= 300   วัดจากหน้าจอภาพ Frame เมื่อ x อยู่ระหว่าง 200 ถึง 300 พิกเซล ให้หุ่นยนต์ตรงไป



x < 200  วัดจากหน้าจอภาพ Frame เมื่อ x น้อยกว่า 200 พิกเซล ให้หุ่นยนต์เลี้ยวซ้าย




x > 300  วัดจากหน้าจอภาพ Frame เมื่อ x มากกว่า 300 พิกเซล ให้หุ่นยนต์เลี้ยวขวา




เปิด เพาเวอร์สวิตซ์ จะมีไฟสีแดงติดที่ Motor Driver


ทดสอบการทำงาน



กด Q ถ้าต้องการออกจากโปรแกรม หรือ กด Ctrl + C เพื่อออกจากโปรแกรม


วีดีโอผลลัพธ์การทำงานของ โปรเจค หุ่นยนต์ติดตามวัตถุ Raspberry Pi + OpenCV



หมายเหตุ : เรียบเรียงและแก้ไขดัดแปลงจากบทความด้านล่าง


AUTOMATIC VISION OBJECT TRACKING

วันพุธที่ 19 กันยายน พ.ศ. 2561

การติดตั้ง OpenCV 3 และการติดตามวัตถุ





OpenCV คือ โปรแกรมที่พัฒนาขึ้นโดยได้รับการสนับสนุนจาก Intel Corporation จำกัด เป็นซอฟต์แวร์ แบบเปิดเผยรหัส (Library Open Source) สำหรับใช้ในการประมวลผลภาพ (Image Processing) เพื่อให้สามารถนำไปต่อยอดพัฒนาโปรแกรมต่าง ๆ ได้ง่าย ใช้ได้บนระบบปฏิบัติการที่เป็น Linux และ Microsoft Windows และสามารถพัฒนาโปรแกรมได้หลากหลายภาษา

**** การใช้ประโยขน์ ****

เพื่อให้การพัฒนาโปรแกรมทางด้าน การมองเห็นของคอมพิวเตอร์ (Computer Vision) คือสามารถประมวลผลภาพดิจิตอลได้ทั้งภาพนิ่ง และภาพเคลื่อนไหวเช่น ภาพจากกล้อง VDO หรือ VDO File เป็นไปได้อย่างสะดวก มีฟังก์ชันสำเร็จรูปสำหรับจัดการข้อมูลภาพ และการประมวลผลภาพพื้นฐานเช่น การหาขอบภาพ การกรองข้อมูลภาพ 


1. การติดตั้ง OpenCV 3

เปิดโปรแกรม เทอมินอล (Root Terminal)




ขั้นตอนที่ 1

-อัพเดตและปรับปรุงแพคเกจของ Raspberry Pi Firmware

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update



-เมื่อทำการอัพเดตเรียบร้อยต้องทำการรีบูทเครื่องใหม่

sudo reboot


-ติดตั้งฟังก์ชันเพิ่มเติม

sudo apt-get install build-essential cmake pkg-config


-ทำการติดตั้ง image I/O packages พวกนามสกุล JPEG, PNG, TIFF, etc

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


-ทำการติดตั้ง GTK development library จะทำให้เราสามารถ compile highgui ซึ่งเป็น module ย่อย ของ OpenCV ซึ่งฟังก์ชันนี้จะทำให้เราสามารถเปิดรูปภาพออกมาที่หน้าจอได้

sudo apt-get install libgtk2.0-dev


การดำเนินงานภายใน OpenCV จำนวนมาก (เช่นการดำเนินการเมทริกซ์) สามารถเพิ่มประสิทธิภาพได้มากขึ้นโดยการติดตั้งการพึ่งพาพิเศษบางอย่าง

sudo apt-get install libatlas-base-dev gfortran


ขั้นตอนที่ 2


-ในขั้นตอนนี้ มีขั้นตอนการดำเนินการติดตั้ง โดยที่เราต้องไปเลือก OpenCV version 3 จาก OpenCV repository(ถ้ามีversion ใหม่กว่านี้ให้เลือกตัวนั้น)

cd ~
wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.4.3.zip
unzip opencv.zip

-เพื่อการติดตั้งที่สมบูรณ์ของ OpenCV 3 ให้ไปดึงไฟล์จาก opencv_contrib

wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.4.3.zip
unzip opencv_contrib.zip


ขั้นตอนที่ 3


ก่อนที่เราจะเริ่มคอมไพล์ OpenCV บน Raspberry Pi 3 ต้องติดตั้ง pip ผู้จัดการ package ของ Python:

wget https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py

-ใช้ virtualenv หรือ virtualenvwrapper เพื่อให้สามารถแสดงภาพได้หลายภาพ นิยมใช้ virtualenvwrapper มากกว่าเพราะมีฟังก์ชันหลากหลาย

sudo pip install virtualenv virtualenvwrapper
sudo rm -rf ~/.cache/pip

-ต้องเข้าไปที่ ~/.profile เพื่อเพิ่มข้อความ 2 บรรทัด โดยใช้คำสั่ง

echo -e "\n# virtualenv and virtualenvwrapper" >> ~/.profile
echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.profile
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.profile



ตอนนี้เราได้อัปเดตโปรไฟล์ ~ / .profile แล้ว และจำเป็นต้องโหลดใหม่เพื่อให้แน่ใจว่าการเปลี่ยนแปลงจะมีผลแล้ว โดย

source ~/.profile


การสร้างสภาพแวดล้อมเสมือน 
OpenCV

ต่อไปให้สร้างสภาพแวดล้อมเสมือน OpenCV ที่เราจะใช้สำหรับการพัฒนา Image Processing และ Computer Vision

mkvirtualenv cv -p python2
mkvirtualenv cv -p python3


หลังจากนั้นจะสามารถใช้ workon ได้


source ~/.profile
workon cv


ต้องเห็นข้อความ (CV) ก่อนหน้าพร้อมท์ แสดงว่าอยู่ในสภาพแวดล้อมเสมือน 
OpenCV แล้ว


ทำการติดตั้ง numpy ดังนี้

pip install numpy




ขั้นตอนที่ 4 

-ขณะนี้เราพร้อมที่จะ compile OpenCV

source ~/.profile
workon cv

cd ~/opencv-3.4.3/
mkdir build
cd build




เมื่อมั่นใจว่าคุณอยู่ในสภาพแวดล้อมเสมือน cv แล้วเราสามารถตั้งค่าการสร้าง CMake ของเราโดยใช้ 

cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D INSTALL_C_EXAMPLES=ON \ -D INSTALL_PYTHON_EXAMPLES=OFF \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.4.3/modules \ -D BUILD_EXAMPLES=ON ..





ติดตั้ง OpenCV


make clean
make
sudo make install

จะใช้เวลาติดตั้งนานพอสมควร



เมื่อครบ 100 % และ ทำการติดตั้งจนกระทั่ง เสร็จสมบูรณ์

แล้วใช้คำสั่ง


sudo ldconfig



เชื่อมโยง OpenCV เข้ากับสภาพแวดล้อมเสมือน cv  สำหรับ Python 2.7:

cd ~/.virtualenvs/cv/lib/python2.7/site-packages/
ln -s /usr/local/lib/python2.7/site-packages/cv2.so cv2.so

ตรวจสอบการทำงาน


source ~/.profile 
workon cv
python


ทดลองนำเข้า cv2  และ ตรวจสอบเวอร์ชั่น ของ  OpenCV โดยคำสั่ง

 
 import cv2
 
 
 cv2.__version__



ถ้าไม่มี error และ แสดงเวอร์ชั่นของ OpenCV ในตัวอย่างคือ 3.4.3

แสดงว่า 
OpenCV ของเรานั้นพร้อมใช้งานแล้ว


นอกจากนี้เรายังจะใช้ imutils คอลเลกชันของ OpenCV เพื่ออำนวยความสะดวกในการทำงานขั้นพื้นฐานบางอย่าง (เช่นปรับขนาด) ได้ง่ายขึ้น

ทำการติดตั้ง imutils ดังนี้

source ~/.profile 
workon cv
pip install imutils



2. ทดสอบ โปรเจค ติดตามวัตถุ Ball Tracking with OpenCV


ให้ติดตั้งโปรแกรมถ่ายโอนไฟล์ SFTP Server ตามลิงค์ด้านล่าง


การติดตั้งโปรแกรมถ่ายโอนไฟล์ SFTP Server


ดาวน์โหลด โปรเจค ติดตามวัตถุ Ball Tracking with OpenCV


https://drive.google.com/open?id=1kRqn3hXl_eBJFPKqc-Os7VrxXNRIVuWv


คลายซิบ และ อัพโหลด ขึ้นสู่ 
Raspberry Pi 3 โดยใช้ โปรแกรม FileZilla (ไฟล์ซิลลา)



โปรเจค ติดตามวัตถุ Ball Tracking อัพโหลด ขึ้นสู่ Raspberry Pi 3 สำเร็จ





กลับไปที่ Raspberry Pi 3  เปิดโปรแกรม เทอมินอล (Root Terminal)  ใช้คำสั่ง


source ~/.profile 
workon cv
cd ball-tracking


แล้วใช้คำสั่ง

python ball_tracking.py --video ball_tracking_example.mp4




โปรแกรมจะเปิดไฟล์วีดีโอ และ แสดงการติดตามวัตถุ ที่เพิ่มเข้ามาจากการเขียนโปรแกรม




3. ทดสอบการติดตามวัตถุ จาก Camera V2 Module


ให้ติดตั้งติดตั้ง Camera V2 Module ตามลิงค์ด้านล่าง

การติดตั้งและการใช้งาน Camera V2 Module


ให้ติดตั้งติดตั้ง Motion ตามลิงค์ด้านล่าง

การติดตั้ง Motion และ ดูภาพกล้องผ่านทางหน้าเว็บเพจ


ต้องแก้ไขไฟล์ /etc/default/motion 

ถ้าเคยทำ "การติดตั้ง Motion และ ดูภาพกล้องผ่านทางหน้าเว็บเพจ" มาก่อน เพราะจะมีการแก้ค่าจาก no เป็น yes เอาไว้ (ถ้าไม่เคยทำก็ไม่ต้องแก้ไข) โดยแก้ไขให้กลับมาเป็น start_motion_daemon=no เหมือนเดิม

เปิดไฟล์ /etc/default/motion มาแก้ไข โดยใช้คำสั่ง


sudo nano /etc/default/motion



ค่าเดิม start_motion_daemon=yes แก้เป็น start_motion_daemon=no


จากนั้นบันทึก Ctrl + O แล้วตามด้วย Enter เพื่อบันทึกข้อมูลใหม่ แล้ว 
กด Ctrl + X เพื่อออกจากโปรแกรม

-เมื่อทำการอัพเดตเรียบร้อยต้องทำการรีบูทเครื่องใหม่


sudo reboot


ไปที่ Raspberry Pi 3  เปิดโปรแกรม เทอมินอล (Root Terminal) 


ติดตั้ง picamera ให้กับ OpenCV โดยใช้คำสั่ง

source ~/.profile 
workon cv
pip install picamera



ติดตั้ง GPIO ให้กับ OpenCV โดยใช้คำสั่ง

source ~/.profile 
workon cv
pip install RPi.GPIO




ทดสอบการติดตามวัตถุ จาก Camera V2 Module โดยใช้คำสั่ง

source ~/.profile 
workon cv
cd ball-tracking
python ball_tracking.py



ผลลัพธ์ ทดสอบการติดตามวัตถุ จาก Camera V2 Module  โดยใช้ลูกบอลสีเหลือง ในตัวอย่างใช้เป็นลูกเทนนิส จะเห็นเป็นภาพเคลื่อนไหวที่ถ่ายจากกล้อง และ แสดงการติดตามวัตถุ

...

หมายเหตุ : เรียบเรียงและแก้ไขดัดแปลงจากบทความด้านล่าง

Install guide: Raspberry Pi 3 + Raspbian Jessie + OpenCV 3

Ball Tracking with OpenCV

....