2024年4月1日月曜日

Raspberry Pi ロボットカー OpenCV(画像認識)

2019年に製作したRaspberry Pi ロボットカー OpenCV(画像認識)
について記事にしました。
Mean-Shift 法を用いた移動物体追跡による制御を行いました。 


同ブログ関連記事:【Raspberry Pi ロボットカー回路図

 


動画


画像認識
ピンク色のふたを追跡します。














OpenCV インストール
$ sudo apt-get update ; sudo apt-get upgrade   #システム環境をアップデートしておく
$ sudo apt-get install build-essential cmake cmake-qt-gui  #cmakeをインストール
$ sudo apt-get install build-essential git cmake pkg-config libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
libgtk2.0-dev libatlas-base-dev gfortran  #必要なパッケージをインストール
$ sudo apt-get install python3-dev python3-pip  #Python3関連のセットアップ
$ cd ~
$ git clone https://github.com/Itseez/opencv.git
$ cd opencv
$ git checkout 3.2.0
$ cd 
$ sudo pip3 install numpy  #numpyのインストール
$ cd opencv
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE \  #OpenCVのインストール
>     -D CMAKE_INSTALL_PREFIX=/usr/local \
>     -D INSTALL_PYTHON_EXAMPLES=ON \
>     -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
>     -D BUILD_EXAMPLES=ON ..


# Remove previous version
$ sudo apt autoremove libopencv3
# Install 
wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.4.0-20180115.1_armhf.deb
$ sudo apt install -y ./libopencv3_3.4.0-20180115.1_armhf.deb
$ sudo ldconfig
$ cd opencv
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release \
>    -D CMAKE_INSTALL_PREFIX=/usr/local \
>    -D OPENCV_EXTRA_MODULES_PATH=/home/npi/opencv_contrib-3.3.1/modules \
>    -DENABLE_VFPV3=ON \
>    -DENABLE_NEON=ON \
>    -DBUILD_TESTS=OFF \
>    -DWITH_TBB=OFF \
>    -D INSTALL_PYTHON_EXAMPLES=ON \
>    -D BUILD_EXAMPLES=ON ..



プログラム(meanshift_car.py
# -*- coding: utf-8 -*-
import smbus
import numpy as np
import cv2
import time
import Adafruit_PCA9685
import RPi.GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306 
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont 

disp = Adafruit_SSD1306.SSD1306_128_64(rst=0)
FONT = '/usr/share/fonts/truetype/fonts-japanese-gothic.ttf' 
disp.begin()
disp.clear()
disp.display()
image = Image.new('1', (128, 64) ) 
draw = ImageDraw.Draw(image) 
size1 = ImageFont.truetype(FONT, 20 )
image = Image.open('robot5.ppm').convert('1')
disp.image(image)
disp.display()
i2c = smbus.SMBus(1)
i2c.write_byte_data(0x3c ,0x00 ,0x2f)#スクロールon

GPIO.setmode(GPIO.BCM) 
GPIO.setup(5, GPIO.OUT)      #AIN1
GPIO.setup(6, GPIO.OUT)      #BIN1
GPIO.setup(12, GPIO.OUT)   #AIN2
GPIO.setup(13, GPIO.OUT)   #BIN2

AIN1= GPIO.PWM(5,100)            #GPIO05 as PWM output, with 100Hz frequency
BIN1= GPIO.PWM(6,100)            #GPIO06 as PWM output, with 100Hz frequency 
AIN2 = GPIO.PWM(12,100)         #GPIO12 as PWM output, with 100Hz frequency
BIN2= GPIO.PWM(13,100)           #GPIO13 as PWM output, with 100Hz frequency 
AIN1.start(0)
BIN1.start(0)
AIN2.start(0)
BIN2.start(0)
def car_s():
AIN1.ChangeDutyCycle(0)
BIN1.ChangeDutyCycle(0)
AIN2.ChangeDutyCycle(0)
BIN2.ChangeDutyCycle(0)
def car_f():
AIN1.ChangeDutyCycle(10)
BIN1.ChangeDutyCycle(10)
AIN2.ChangeDutyCycle(0)
BIN2.ChangeDutyCycle(0)
def car_r():
AIN1.ChangeDutyCycle(10)
BIN1.ChangeDutyCycle(0)
AIN2.ChangeDutyCycle(0)
BIN2.ChangeDutyCycle(10)
def car_l():
AIN1.ChangeDutyCycle(0)
BIN1.ChangeDutyCycle(10)
AIN2.ChangeDutyCycle(10)
BIN2.ChangeDutyCycle(0)
def car_b():
AIN1.ChangeDutyCycle(0)
BIN1.ChangeDutyCycle(0)
AIN2.ChangeDutyCycle(10)
BIN2.ChangeDutyCycle(10)

pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)

cap = cv2.VideoCapture(0)
cap.set(3, 320)
cap.set(4, 320)
x, y, w, h = 75, 75, 100, 100
track_window = (x, y, w, h)
ret,frame = cap.read()
roi = frame[y:y+h, x:x+w]
hsv_roi =  cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
img_mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], img_mask, [180], [0,180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )

while(True):
    ret, frame = cap.read()
    now_degree_x, now_degree_y, move_degree_x, move_degree_y = 300, 250, 0, 0
    if ret == True:
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180], 1)
        ret, track_window = cv2.meanShift(dst, track_window, term_crit)
        x,y,w,h = track_window
        img_dst = cv2.rectangle(frame, (x,y), (x+w, y+h), (255,255,255), 3)
        img_x = int(x+w/2)
        img_y = int(y+h/2)
        move_degree_x = now_degree_x - (img_x-160)*0.06
        move_degree_y = now_degree_y + (img_y-160)*0.06
        print('deg: ', move_degree_x , move_degree_y)
        pwm.set_pwm(0, 0, int(move_degree_x))
        pwm.set_pwm(1, 0, int(move_degree_y)) 
        if move_degree_x < 292:
car_r()
time.sleep(0.5)
car_s()
        if move_degree_x > 306:
car_l()
time.sleep(0.5)
car_s()
        if move_degree_y <246:
car_b()
time.sleep(0.5)
car_s()
        if move_degree_y >= 254:
car_f()
time.sleep(0.5)
car_s()
       
       
        now_degree_x = now_degree_x + move_degree_x
        now_degree_y = now_degree_y + move_degree_y
        cv2.circle(img_dst, (img_x, img_y), 10, (0,180,0), -1)
        cv2.imshow('SHOW MEANSHIFT IMAGE', img_dst)
       
        k = cv2.waitKey(1)
        if k == ord('q'):
            break
    else:
        break

cap.release()
cv2.destroyAllWindows()







0 件のコメント:

コメントを投稿

Raspberry Pi Donkey Car スマートカー

  2020年に製作したDonkey Car スマートカー について記事にしました。 Donkey CarはRaspberry Pi のカメラからコースを ディープラーニングさせ自動走行を行います。(動画は白線上を自動走行)   動画