J'ai travaillé avec Processing et Cinder pour modifier l'entrée Kinect à la volée. Cependant, je voudrais également enregistrer le flux complet (profondeur + couleur + accéléromètre, et tout ce qui s'y trouve). J'enregistre pour pouvoir essayer différents effets/traitements sur le même matériel. Parce que je ne fais que l'apprentissage de Cinder and Processing est assez lent/laggy, j'ai eu du mal à trouver des conseils sur une stratégie pour capturer le flux - n'importe quoi (de préférence dans Cinder, oF ou Processing) serait vraiment utile.Quelle est la méthode la plus fiable pour enregistrer un flux Kinect en vue d'une lecture ultérieure?
Répondre
J'ai déjà essayé Processing et OpenFrameworks. Le traitement est plus lent lors de l'affichage des deux images (profondeur et couleur). OpenFrameworks ralentit un peu en écrivant les données sur le disque, mais voici l'approche de base:
- Setup Openframeworks (ouvert et compiler un échantillon pour vous assurer que vous êtes opérationnel)
- Télécharger le ofxKinect addon et copier l'exemple projet comme décrit sur github.
- Une fois que vous avez l'exemple et DE ofxKinect en cours d'exécution, il est juste une question d'ajouter quelques variables pour enregistrer vos données:
Dans cette configuration de base, j'ai créé quelques cas ofImage et un booléen pour basculer l'épargne. Dans l'exemple, les buffers profondeur et RGB sont sauvegardés dans des instances ofxCvGrayscaleImage, mais je n'ai pas utilisé OF et OpenCV assez pour savoir comment faire quelque chose d'aussi simple que d'enregistrer une image sur le disque, c'est pourquoi j'ai utilisé deux instances. Je ne sais pas à quel point vous êtes à l'aise avec Processing, OF, Cinder, donc, pour les arguments, je suppose que vous savez que vous êtes loin du traitement, mais vous êtes encore en train de vous attaquer au C++.
DE est assez similaire à la transformation, mais il y a quelques différences:
- Dans le traitement que vous avez déclaration des variables et ils sont l'utilisation dans le même fichier. Dans OF vous avez un fichier .h où vous déclarez que vous êtes des variables et le fichier .cpp où vous initialisez et utilisez vos variables. Dans Processing, vous avez les méthodes setup() (initialize variables) et draw() (mise à jour des variables et draw to screen), alors que dans OF vous avez setup() (comme dans Processing), update() (update seulement, rien de visuel) et draw() (dessiner à l'écran en utilisant les valeurs mises à jour)
- Lorsque vous travaillez avec des images, puisque vous codez en C++, vous devez d'abord allouer de la mémoire, par opposition à Processing/Java où vous avez gestion de la mémoire.
Il ya plus de différences que je ne vais pas détailler ici. Ne consultez OF for Processing Users sur le wiki
Retour à l'exemple exampleKinect, voici ma configuration de base:
.h:
#pragma once
#include "ofMain.h"
#include "ofxOpenCv.h"
#include "ofxKinect.h"
class testApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void exit();
void drawPointCloud();
void keyPressed (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 windowResized(int w, int h);
ofxKinect kinect;
ofxCvColorImage colorImg;
ofxCvGrayscaleImage grayImage;
ofxCvGrayscaleImage grayThresh;
ofxCvGrayscaleImage grayThreshFar;
ofxCvContourFinder contourFinder;
ofImage colorData;//to save RGB data to disk
ofImage grayData;//to save depth data to disk
bool bThreshWithOpenCV;
bool drawPC;
bool saveData;//save to disk toggle
int nearThreshold;
int farThreshold;
int angle;
int pointCloudRotationY;
int saveCount;//counter used for naming 'frames'
};
et le fichier .cpp:
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup() {
//kinect.init(true); //shows infrared image
kinect.init();
kinect.setVerbose(true);
kinect.open();
colorImg.allocate(kinect.width, kinect.height);
grayImage.allocate(kinect.width, kinect.height);
grayThresh.allocate(kinect.width, kinect.height);
grayThreshFar.allocate(kinect.width, kinect.height);
//allocate memory for these ofImages which will be saved to disk
colorData.allocate(kinect.width, kinect.height, OF_IMAGE_COLOR);
grayData.allocate(kinect.width, kinect.height, OF_IMAGE_GRAYSCALE);
nearThreshold = 230;
farThreshold = 70;
bThreshWithOpenCV = true;
ofSetFrameRate(60);
// zero the tilt on startup
angle = 0;
kinect.setCameraTiltAngle(angle);
// start from the front
pointCloudRotationY = 180;
drawPC = false;
saveCount = 0;//init frame counter
}
//--------------------------------------------------------------
void testApp::update() {
ofBackground(100, 100, 100);
kinect.update();
if(kinect.isFrameNew()) // there is a new frame and we are connected
{
grayImage.setFromPixels(kinect.getDepthPixels(), kinect.width, kinect.height);
if(saveData){
//if toggled, set depth and rgb pixels to respective ofImage, save to disk and update the 'frame' counter
grayData.setFromPixels(kinect.getDepthPixels(), kinect.width, kinect.height,true);
colorData.setFromPixels(kinect.getCalibratedRGBPixels(), kinect.width, kinect.height,true);
grayData.saveImage("depth"+ofToString(saveCount)+".png");
colorData.saveImage("color"+ofToString(saveCount)+".png");
saveCount++;
}
//we do two thresholds - one for the far plane and one for the near plane
//we then do a cvAnd to get the pixels which are a union of the two thresholds.
if(bThreshWithOpenCV){
grayThreshFar = grayImage;
grayThresh = grayImage;
grayThresh.threshold(nearThreshold, true);
grayThreshFar.threshold(farThreshold);
cvAnd(grayThresh.getCvImage(), grayThreshFar.getCvImage(), grayImage.getCvImage(), NULL);
}else{
//or we do it ourselves - show people how they can work with the pixels
unsigned char * pix = grayImage.getPixels();
int numPixels = grayImage.getWidth() * grayImage.getHeight();
for(int i = 0; i < numPixels; i++){
if(pix[i] < nearThreshold && pix[i] > farThreshold){
pix[i] = 255;
}else{
pix[i] = 0;
}
}
}
//update the cv image
grayImage.flagImageChanged();
// find contours which are between the size of 20 pixels and 1/3 the w*h pixels.
// also, find holes is set to true so we will get interior contours as well....
contourFinder.findContours(grayImage, 10, (kinect.width*kinect.height)/2, 20, false);
}
}
//--------------------------------------------------------------
void testApp::draw() {
ofSetColor(255, 255, 255);
if(drawPC){
ofPushMatrix();
ofTranslate(420, 320);
// we need a proper camera class
drawPointCloud();
ofPopMatrix();
}else{
kinect.drawDepth(10, 10, 400, 300);
kinect.draw(420, 10, 400, 300);
grayImage.draw(10, 320, 400, 300);
contourFinder.draw(10, 320, 400, 300);
}
ofSetColor(255, 255, 255);
stringstream reportStream;
reportStream << "accel is: " << ofToString(kinect.getMksAccel().x, 2) << "/"
<< ofToString(kinect.getMksAccel().y, 2) << "/"
<< ofToString(kinect.getMksAccel().z, 2) << endl
<< "press p to switch between images and point cloud, rotate the point cloud with the mouse" << endl
<< "using opencv threshold = " << bThreshWithOpenCV <<" (press spacebar)" << endl
<< "set near threshold " << nearThreshold << " (press: + -)" << endl
<< "set far threshold " << farThreshold << " (press: < >) num blobs found " << contourFinder.nBlobs
<< ", fps: " << ofGetFrameRate() << endl
<< "press c to close the connection and o to open it again, connection is: " << kinect.isConnected() << endl
<< "press s to toggle saving depth and color data. currently saving: " << saveData << endl
<< "press UP and DOWN to change the tilt angle: " << angle << " degrees";
ofDrawBitmapString(reportStream.str(),20,656);
}
void testApp::drawPointCloud() {
ofScale(400, 400, 400);
int w = 640;
int h = 480;
ofRotateY(pointCloudRotationY);
float* distancePixels = kinect.getDistancePixels();
glBegin(GL_POINTS);
int step = 2;
for(int y = 0; y < h; y += step) {
for(int x = 0; x < w; x += step) {
ofPoint cur = kinect.getWorldCoordinateFor(x, y);
ofColor color = kinect.getCalibratedColorAt(x,y);
glColor3ub((unsigned char)color.r,(unsigned char)color.g,(unsigned char)color.b);
glVertex3f(cur.x, cur.y, cur.z);
}
}
glEnd();
}
//--------------------------------------------------------------
void testApp::exit() {
kinect.setCameraTiltAngle(0); // zero the tilt on exit
kinect.close();
}
//--------------------------------------------------------------
void testApp::keyPressed (int key) {
switch (key) {
case ' ':
bThreshWithOpenCV = !bThreshWithOpenCV;
break;
case'p':
drawPC = !drawPC;
break;
case '>':
case '.':
farThreshold ++;
if (farThreshold > 255) farThreshold = 255;
break;
case '<':
case ',':
farThreshold --;
if (farThreshold < 0) farThreshold = 0;
break;
case '+':
case '=':
nearThreshold ++;
if (nearThreshold > 255) nearThreshold = 255;
break;
case '-':
nearThreshold --;
if (nearThreshold < 0) nearThreshold = 0;
break;
case 'w':
kinect.enableDepthNearValueWhite(!kinect.isDepthNearValueWhite());
break;
case 'o':
kinect.setCameraTiltAngle(angle); // go back to prev tilt
kinect.open();
break;
case 'c':
kinect.setCameraTiltAngle(0); // zero the tilt
kinect.close();
break;
case 's'://s to toggle saving data
saveData = !saveData;
break;
case OF_KEY_UP:
angle++;
if(angle>30) angle=30;
kinect.setCameraTiltAngle(angle);
break;
case OF_KEY_DOWN:
angle--;
if(angle<-30) angle=-30;
kinect.setCameraTiltAngle(angle);
break;
}
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y) {
pointCloudRotationY = x;
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{}
C'est une configuration très basique. N'hésitez pas à modifier (ajouter l'angle d'inclinaison aux données sauvegardées, etc.) Je suis à peu près sûr qu'il existe des façons d'améliorer cette vitesse (par ex.ne pas mettre à jour ofxCvGrayscaleImage instances et ne pas tirer des images à l'écran lors de l'enregistrement, ou empiler quelques images et de les écrire à l'intervalle par opposition à sur chaque image, etc.)
Goodluck
- 1. PHP fiable-quelle est la méthode?
- 2. Quelle est la méthode la plus fiable pour définir un contrôle profondément imbriqué dans Windows Forms?
- 3. En Perl, quelle est la méthode la plus fiable pour déterminer le paquet d'un coderef?
- 4. Quelle est la méthode clearfix la plus fiable pour le HTML dans les emails?
- 5. Quelle est la méthode la plus fiable pour vérifier l'installation de Firefox?
- 6. Méthode la plus simple pour enregistrer les flux rss externes
- 7. Quelle est la méthode la plus simple pour obtenir un flux à partir d'une chaîne
- 8. Quelle est la méthode la plus rapide pour analyser le flux RSS en PHP?
- 9. Quelle méthode MySQL INSERT serait la plus rapide et la plus fiable?
- 10. Quelle est la différence entre une vue et un flux?
- 11. Quelle est la partie la plus fiable de la chaîne user-agent pour détecter Internet Explorer?
- 12. Quelle est la partie la plus fiable de la chaîne user-agent pour détecter Internet Explorer?
- 13. Octave: quelle méthode est la plus efficace
- 14. À partir d'un navigateur Web (IE), quelle est la méthode la plus fiable pour exécuter des commandes locales?
- 15. Quelle est la méthode la plus simple pour écrire un fichier avec l'interface de fichier Chrome?
- 16. Méthode la plus efficace pour modifier un flux de données
- 17. Quelle est la méthode la plus simple pour changer le bureau en un clic
- 18. Quelle est la méthode la plus efficace pour appliquer un style CSS en utilisant jQuery?
- 19. Quelle est la méthode la plus fiable pour déterminer le système d'exploitation d'un visiteur d'un site Web?
- 20. Enregistrer UIWebView ActiveElement pour une utilisation ultérieure
- 21. Quelle méthode pour détecter le mode d'exécution du script php est plus fiable?
- 22. Quelle est la granularité la plus fine de la géolocalisation fiable?
- 23. Quelle est la méthode la plus simple pour comparer de grandes quantités de texte similaire?
- 24. Préchargement/mise en cache de vidéos pour lecture ultérieure
- 25. Quelle est la méthode d'aide récursive la plus légitime?
- 26. Quelle est la méthode de hachage la plus sécurisée? (PHP)
- 27. Quelle est la méthode fiable de mesure du temps dans un système d'étranglement du processeur?
- 28. Quelle est la méthode des trois20 pour passer des objets entre les contrôleurs de vue?
- 29. Quelle méthode pour contracter un objet est plus efficace?
- 30. Quelle est la méthode la plus efficace pour affecter des threads en fonction du scénario suivant?
Utilisez-vous ou OpenNI Le SDK de Microsoft? – Artium
que voulez-vous dire par valeur d'accéléromètre? –
Merci pour les questions, désolé je n'étais pas plus précis! Je n'utilise pas Microsoft SDK, et j'ai le plus d'expérience en utilisant la bibliothèque Processing (par Shiffman, je crois) et le bloc Cinder (par R Hodgin) ... Je comprends que la Kinect a un accéléromètre dedans (I ' Je ne suis pas tout à fait sûr pourquoi il est là - peut-être pour détecter quand il est sur une surface non plane?), et ce serait génial de pouvoir enregistrer la sortie complète, y compris tous les autres capteurs. Mais ce n'est pas essentiel, si cela rend la question plus facile à répondre ... Merci encore, AKA – AKA