について記事にしました。
動画
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 件のコメント:
コメントを投稿