update: 2016/08/11
reference:
1. openframeworks
2. GitHub - kashimAstro/ofxGPIO
3. I touchs: Raspberry Pi: Connected Arduino Using I2C
A. 功能測試: opencvHaarFinderExample
// 單張照片臉部辨識
$ cd /home/pi/of_v0.9.3/examples/addons/opencvHaarFinderExample
$ make
$ ./bin/opencvHaarFinderExample // 結果
B. 功能測試: videoGrabberExample
// USB Web Cam
$ cd /home/pi/of_v0.9.3/examples/video/videoGrabberExample
$ make
$ ./bin/videoGrabberExample
// 結果
C. Face Detection With USB Webcam
1. addons.make
ofxOpenCv
***********************************************
2. main.cpp
#include "ofMain.h"
#include "ofApp.h"
//========================================================================
int main( ){
ofSetLogLevel(OF_LOG_VERBOSE);
// read config file
vector<string> _linesOfTheFile;
ofBuffer _buffer = ofBufferFromFile("config.txt");
for (auto line : _buffer.getLines()){
_linesOfTheFile.push_back(line);
}
// local variables
int _debug = ofToBool(_linesOfTheFile[1]);
int _camWidth = ofToInt(_linesOfTheFile[4]);
int _camHeight = ofToInt(_linesOfTheFile[7]);
bool _fullScreen = ofToBool(_linesOfTheFile[10]);
// show debug message
if(_debug) {
ofLog() << "****** main()";
ofLog() << "debug: " << _debug;
ofLog() << "OpenGL width: " << _camWidth;
ofLog() << "OpenGL height: " << _camHeight;
ofLog() << "fullScreen: " << _fullScreen;
}
// fullScreen
if(_fullScreen) {
// set camWidth & camHeight as window's
ofSetupOpenGL(_camWidth, _camHeight, OF_FULLSCREEN);
}
// window
else {
// set camWidth & camHeight as window's
ofSetupOpenGL(_camWidth, _camHeight, OF_WINDOW);
}
// this kicks off the running of my app
// can be OF_WINDOW or OF_FULLSCREEN
// pass in width and height too:
ofRunApp(new ofApp());
}
***********************************************
3. ofApp.h
#pragma once
#include "ofMain.h"
#include "ofxCvHaarFinder.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
//@add for VideoGrabber
ofVideoGrabber vidGrabber;
//@add for CvHaarFinder
//ofImage img;
ofxCvHaarFinder finder;
//@add second record
float countROI;
long readSeconds; // read from totalSeconds record file
long writeSeconds; // write to totalSeconds record file
long latestSeconds; // latestSeconds
// config file
bool debug;
int camWidth;
int camHeight;
bool fullScreen;
int frameRate;
bool concurrentVisit;
float minROI;
float maxROI;
float weightROI;
string recordFile;
};
***********************************************
4. ofApp.cpp
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofSetLogLevel(OF_LOG_VERBOSE);
// read config file
vector<string> linesOfTheFile;
ofBuffer buffer = ofBufferFromFile("config.txt");
for (auto line : buffer.getLines()){
linesOfTheFile.push_back(line);
}
//for (int i = 0; i < linesOfTheFile.size(); i++) {
// ofLog(OF_LOG_VERBOSE, "cur.width = %s", linesOfTheFile[i].c_str());
//}
debug = ofToBool(linesOfTheFile[1]);
camWidth = ofToInt(linesOfTheFile[4]);
camHeight = ofToInt(linesOfTheFile[7]);
fullScreen = ofToBool(linesOfTheFile[10]);
frameRate = ofToInt(linesOfTheFile[13]);
concurrentVisit = ofToBool(linesOfTheFile[16]);
minROI = ofToFloat(linesOfTheFile[19]);
maxROI = ofToFloat(linesOfTheFile[22]);
weightROI = ofToFloat(linesOfTheFile[25]);
recordFile = linesOfTheFile[28];
if(debug)
{
ofLog() << "****** ofApp::setup()";
ofLog() << "debug: " << debug;
ofLog() << "camWidth: " << camWidth;
ofLog() << "camHeight: " << camHeight;
ofLog() << "fullScreen: " << fullScreen;
ofLog() << "frameRate: " << frameRate;
ofLog() << "concurrentVisit: " << concurrentVisit;
ofLog() << "minROI: " << minROI;
ofLog() << "maxROI: " << maxROI;
ofLog() << "weightROI: " << weightROI;
ofLog() << "recordFile: " << recordFile;
}
// read totalSeconds record file
vector<string> totalSecondsFile;
ofBuffer sbuffer = ofBufferFromFile(recordFile);
for (auto line : sbuffer.getLines()){
totalSecondsFile.push_back(line);
}
readSeconds = ofToFloat(totalSecondsFile[0]);
if(debug)
{
ofLog() << "****** read totalSeconds record file";
ofLog() << "readSeconds: " << readSeconds;
}
//ofSetFrameRate(5);
ofSetFrameRate(frameRate);
//@add for VideoGrabber
//we can now get back a list of devices.
vector<ofVideoDevice> devices = vidGrabber.listDevices();
for(int i = 0; i < devices.size(); i++){
if(devices[i].bAvailable){
ofLogNotice() << devices[i].id << ": " << devices[i].deviceName;
}else{
ofLogNotice() << devices[i].id << ": " << devices[i].deviceName << " - unavailable ";
}
}
vidGrabber.setDeviceID(0);
//vidGrabber.setDesiredFrameRate(60);
vidGrabber.setDesiredFrameRate(frameRate);
vidGrabber.initGrabber(camWidth, camHeight);
ofSetVerticalSync(true);
//@add for CvHaarFinder
//img.load("test.jpg");
finder.setup("haarcascade_frontalface_default.xml");
//finder.findHaarObjects(img);
}
//--------------------------------------------------------------
void ofApp::update(){
//@add for VideoGrabber
ofBackground(100, 100, 100);
vidGrabber.update();
//@add for CvHaarFinder
if(vidGrabber.isFrameNew()){
ofPixels & pixels = vidGrabber.getPixels();
finder.findHaarObjects(pixels);
}
}
//--------------------------------------------------------------
void ofApp::draw(){
//@add for VideoGrabber
ofSetHexColor(0xffffff);
vidGrabber.draw(0, 0);
//@add for CvHaarFinder
//img.draw(0, 0);
ofNoFill();
for(unsigned int i = 0; i < finder.blobs.size(); i++) {
ofRectangle cur = finder.blobs[i].boundingRect;
//if(debug){
// ofLog(OF_LOG_VERBOSE, "ROI width = %f", cur.width);
// ofLog(OF_LOG_VERBOSE, "ROI height = %f", cur.height);
//}
//if((cur.width >= 50.0 && cur.width <= 150.0) &&
// (cur.height >= 50.0 && cur.height <= 150.0)) {
if((cur.width >= (minROI * camWidth) && cur.width <= (maxROI * camWidth)) &&
(cur.height >= (minROI * camWidth) && cur.height <= (maxROI * camWidth))) {
countROI++;
ofSetColor(255, 0, 0); // red color
ofDrawRectangle(cur.x, cur.y, cur.width, cur.height);
if(debug) {
ofSetColor(ofColor::yellow);
ofDrawBitmapString("ROI = " + ofToString(cur.width) + " x " + ofToString(cur.height), camWidth/5, camHeight/1.02);
}
// not concurrent Visit
if(!concurrentVisit){
break;
}
}
else {
ofSetColor(0, 0, 255); // blue color
ofDrawRectangle(cur.x, cur.y, cur.width, cur.height);
}
}
// writeSeconds
writeSeconds = readSeconds + (countROI / frameRate * weightROI); // weightROI: for calibrate detect missing
if(writeSeconds > latestSeconds){
// Write data
if(debug) {
// totalSeconds record file
ofLog() << "****** write totalSeconds record file: " << writeSeconds;
}
ofBuffer secondsBuff;
secondsBuff.set(ofToString(writeSeconds));
bool fileWritten = ofBufferToFile(recordFile, secondsBuff);
latestSeconds = writeSeconds;
}
if(debug){
// show message
ofSetColor(ofColor::white);
ofDrawBitmapString("total seconds: " + ofToString(writeSeconds), camWidth/5, camHeight/1.2);
ofDrawBitmapString(ofToString(minROI * camWidth) + " <= ROI <= " + ofToString(maxROI * camWidth), camWidth/5, camHeight/1.1);
}
ofSetColor(100, 100, 100);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
//@add for VideoGrabber
if(key == 'd' || key == 'D'){
debug = !debug;
}
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
}
***********************************************
5. bin/data 資料夾
a. haarcascade_frontalface_default.xml // from ofxOpenCv
b. totalSeconds.txt // record second
0
c. config.txt // config file
# debug (true/false)
false
# cam width (int)
320
# cam height (int)
240
# full screen (true/false)
false
# frame rate (int)
5
# concurrent visit (true/false)
false
# minimum width ratio of ROI(region of interest) (float)
0.125
# maximum width ratio of ROI(region of interest) (float)
0.5
# weight of ROI (float)
1.0
# recordFile (string)
totalSeconds.txt
-----------------------------------------------------------------------------------------------
* 無法正常作用(可能要配合 ofx 0.9.2) *
D. 利用 GPIO( or I²C: Inter-Integrated Circuit) 傳送資料給 Arduino
1. 參考: I touchs: Raspberry Pi: Connected Arduino Using I2C
> 讓 Raspberry Pi 的 I2C 功能啟用, 並且記下以下的資料
$ ls /dev/i2c*
/dev/i2c-1
以及 Arduino 裡的定義:
#define SLAVE_ADDRESS 0x04
2. 安裝 ofxGPIO
$ cd /home/pi/of_v0.9.3/addons
$ git clone https://github.com/kashimAstro/ofxGPIO
3. 修改專案的 addons.make 檔案如下:
/home/pi/of_v0.9.3/apps/myApps/DPHeadTrackingUSB/addons.make
ofxOpenCv
ofxGPIO
4. 修改 ofApp.h 如下:
/home/pi/of_v0.9.3/apps/myApps/DPHeadTrackingUSB/src/ofApp.h
#pragma once
#include "ofMain.h"
#include "ofxCvHaarFinder.h"
//@add for GPIO
#include "ofxGPIO.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
//@add for GPIO
//void exit();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
//@add for VideoGrabber
ofVideoGrabber vidGrabber;
//@add for CvHaarFinder
//ofImage img;
ofxCvHaarFinder finder;
//@add second record
float countROI;
long readSeconds; // read from totalSeconds record file
long writeSeconds; // write to totalSeconds record file
long latestSeconds; // latestSeconds
// config file
bool debug;
int camWidth;
int camHeight;
bool fullScreen;
int frameRate;
bool concurrentVisit;
float minROI;
float maxROI;
float weightROI;
string recordFile;
//@add for I2C
//I2CBus * bus;
//@add for GPIO
//GPIO ofxGPIO;
GPIO* ofxGPIO;
};
5. 修改 ofApp.cpp 如下:
/home/pi/of_v0.9.3/apps/myApps/DPHeadTrackingUSB/src/ofApp.cpp
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofSetLogLevel(OF_LOG_VERBOSE);
// read config file
vector<string> linesOfTheFile;
ofBuffer buffer = ofBufferFromFile("config.txt");
for (auto line : buffer.getLines()){
linesOfTheFile.push_back(line);
}
//for (int i = 0; i < linesOfTheFile.size(); i++) {
// ofLog(OF_LOG_VERBOSE, "cur.width = %s", linesOfTheFile[i].c_str());
//}
debug = ofToBool(linesOfTheFile[1]);
camWidth = ofToInt(linesOfTheFile[4]);
camHeight = ofToInt(linesOfTheFile[7]);
fullScreen = ofToBool(linesOfTheFile[10]);
frameRate = ofToInt(linesOfTheFile[13]);
concurrentVisit = ofToBool(linesOfTheFile[16]);
minROI = ofToFloat(linesOfTheFile[19]);
maxROI = ofToFloat(linesOfTheFile[22]);
weightROI = ofToFloat(linesOfTheFile[25]);
recordFile = linesOfTheFile[28];
if(debug)
{
ofLog() << "****** ofApp::setup()";
ofLog() << "debug: " << debug;
ofLog() << "camWidth: " << camWidth;
ofLog() << "camHeight: " << camHeight;
ofLog() << "fullScreen: " << fullScreen;
ofLog() << "frameRate: " << frameRate;
ofLog() << "concurrentVisit: " << concurrentVisit;
ofLog() << "minROI: " << minROI;
ofLog() << "maxROI: " << maxROI;
ofLog() << "weightROI: " << weightROI;
ofLog() << "recordFile: " << recordFile;
}
// read totalSeconds record file
vector<string> totalSecondsFile;
ofBuffer sbuffer = ofBufferFromFile(recordFile);
for (auto line : sbuffer.getLines()){
totalSecondsFile.push_back(line);
}
readSeconds = ofToFloat(totalSecondsFile[0]);
if(debug)
{
ofLog() << "****** read totalSeconds record file";
ofLog() << "readSeconds: " << readSeconds;
}
//ofSetFrameRate(5);
ofSetFrameRate(frameRate);
//@add for VideoGrabber
//we can now get back a list of devices.
vector<ofVideoDevice> devices = vidGrabber.listDevices();
for(int i = 0; i < devices.size(); i++){
if(devices[i].bAvailable){
ofLogNotice() << devices[i].id << ": " << devices[i].deviceName;
}else{
ofLogNotice() << devices[i].id << ": " << devices[i].deviceName << " - unavailable ";
}
}
vidGrabber.setDeviceID(0);
//vidGrabber.setDesiredFrameRate(60);
vidGrabber.setDesiredFrameRate(frameRate);
vidGrabber.initGrabber(camWidth, camHeight);
ofSetVerticalSync(true);
//@add for CvHaarFinder
//img.load("test.jpg");
finder.setup("haarcascade_frontalface_default.xml");
//finder.findHaarObjects(img);
//@add for GPIO
//bus = new I2CBus("/dev/i2c-1");
//bus->addressSet(0x04);
//@add for GPIO (pin)
//ofxGPIO.setup("7");
//ofxGPIO.export_gpio();
//ofxGPIO.setdir_gpio("out");
ofxGPIO = new GPIO("7");
ofxGPIO->export_gpio();
ofxGPIO->setdir_gpio("out");
}
//--------------------------------------------------------------
void ofApp::update(){
//@add for VideoGrabber
ofBackground(100, 100, 100);
vidGrabber.update();
//@add for CvHaarFinder
if(vidGrabber.isFrameNew()){
ofPixels & pixels = vidGrabber.getPixels();
finder.findHaarObjects(pixels);
}
}
//--------------------------------------------------------------
void ofApp::draw(){
//@add for VideoGrabber
ofSetHexColor(0xffffff);
vidGrabber.draw(0, 0);
//@add for CvHaarFinder
//img.draw(0, 0);
ofNoFill();
for(unsigned int i = 0; i < finder.blobs.size(); i++) {
ofRectangle cur = finder.blobs[i].boundingRect;
//if(debug){
// ofLog(OF_LOG_VERBOSE, "ROI width = %f", cur.width);
// ofLog(OF_LOG_VERBOSE, "ROI height = %f", cur.height);
//}
//if((cur.width >= 50.0 && cur.width <= 150.0) &&
// (cur.height >= 50.0 && cur.height <= 150.0)) {
if((cur.width >= (minROI * camWidth) && cur.width <= (maxROI * camWidth)) &&
(cur.height >= (minROI * camWidth) && cur.height <= (maxROI * camWidth))) {
countROI++;
ofSetColor(255, 0, 0); // red color
ofDrawRectangle(cur.x, cur.y, cur.width, cur.height);
if(debug) {
ofSetColor(ofColor::yellow);
ofDrawBitmapString("ROI = " + ofToString(cur.width) + " x " + ofToString(cur.height), camWidth/5, camHeight/1.02);
}
// not concurrent Visit
if(!concurrentVisit){
break;
}
}
else {
ofSetColor(0, 0, 255); // blue color
ofDrawRectangle(cur.x, cur.y, cur.width, cur.height);
}
}
// writeSeconds
writeSeconds = readSeconds + (countROI / frameRate * weightROI); // weightROI: for calibrate detect missing
if(writeSeconds > latestSeconds){
// Write data
if(debug) {
// totalSeconds record file
ofLog() << "****** write totalSeconds record file: " << writeSeconds;
}
ofBuffer secondsBuff;
secondsBuff.set(ofToString(writeSeconds));
bool fileWritten = ofBufferToFile(recordFile, secondsBuff);
latestSeconds = writeSeconds;
//@add for GPIO
//bus->writeByte(0x04, writeSeconds);
//usleep(50000); // sleep for 0.05 second
//@add for test
/*
bus->writeByte(0x04,1);
usleep(500000); // sleep for 0.5 second
bus->writeByte(0x04,0);
usleep(500000); // sleep for 0.5 second
*/
//@add for GPIO
//ofxGPIO.setval_gpio("1");
//usleep(50000); // sleep for 0.05 second
//ofxGPIO.setval_gpio("0");
//usleep(50000); // sleep for 0.05 second
ofxGPIO->setval_gpio("1");
usleep(50000); // sleep for 0.05 second
ofxGPIO->setval_gpio("0");
usleep(50000); // sleep for 0.05 second
}
if(debug){
// show message
ofSetColor(ofColor::white);
ofDrawBitmapString("total seconds: " + ofToString(writeSeconds), camWidth/5, camHeight/1.2);
ofDrawBitmapString(ofToString(minROI * camWidth) + " <= ROI <= " + ofToString(maxROI * camWidth), camWidth/5, camHeight/1.1);
}
ofSetColor(100, 100, 100);
}
/*
//--------------------------------------------------------------
void ofApp::exit(){
//@add for GPIO
ofxGPIO.unexport_gpio();
}
*/
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
//@add for VideoGrabber
if(key == 'd' || key == 'D'){
debug = !debug;
}
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
}
6. 編譯與執行:
$ cd /home/pi/of_v0.9.3/apps/myApps/DPHeadTrackingUSB
$ make
$ ./bin/DPHeadTrackingUSB
7. 開機後自動執行: (console 的訊息會出不來, 建議改成在 .bashrc 裡執行程式)
$ cd
$ touch startHeadTracking.sh
$ chmod 755 startHeadTracking.sh
$ sudo nano startHeadTracking.sh
#!/bin/bash
sleep 5
cd /home/pi/of_v0.9.3/apps/myApps/DPHeadTrackingUSB
./bin/DPHeadTrackingUSB
$ cat startHeadTracking.sh
$ sudo crontab -e
....
@reboot /home/pi/startHeadTracking.sh
$ sudo crontab -l
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。