Yesterday, I had done a performance testing.
A test program attached this post.
It's a processing time from capturing a RBG data via OpenNI -Xtion to writing a formated data.
A test path is below.
Xtion -> OpenNI (RGB, Depth) -> OpenCV (conversion format, writing) -> SD-card
(1)Capturer : 640x480, RGB24
(2)Pieces of writing format type are bmp, dib, jpd, jp2, png, pbm, pgm, ppm, ras, and tiff.
RESULT
(1) It's take 15-20 sec from capturing to writing SD-card.
processing time (sec)
Initialize OpenNI : 4 - 5
Capture depth & RBG : 0 - 1
Merge : 3 - 4
Convert & save : 4 - 5
Terminate : 4 - 5
( Processing time on MacMini (i5 2.5GHz 8G) is 2sec. )
(2) Processing time depends data format a little.
Jpeg format is faster than png, 2-3 seconds.
(3) There aren't a difference of processing time between clock speed 700MHz and 800MHz.
Next performance testing is a following process.
Capture (Raspberry Pi) --- depth & RGB (UDP) --> Receive (other machine).
This test use a function of Cooperative control of RDCS.
Peace!
/*****************************************************************************************
Sample snapshot & save program (No Warranty)
******************************************************************************************/
OpenNI 1.5.4
Sensor 5.1.2.1
OpenCV 2.4
Xtion Pro Live
(1) Raspberry Pi 800MHz and 700MHz
Arch Linux arm 3.2.27-8-ARCH+
gcc (GCC) 4.7.1 20120721
It need a compiler option "-mcpu=arm1176jzf-s".
(2) Macmini
Darwin Kernel Version 12.2.0
llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658)
(3) Windows
No test.
//---------------------------------------------------------------------------
// Includes
//---------------------------------------------------------------------------
#include <XnOS.h>
#include <opencv2/opencv.hpp>
#include <XnCppWrapper.h>
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
//#include <stdlib.h>
#include <time.h>
#include <math.h>
using namespace std;
using namespace xn;
using namespace cv;
//---------------------------------------------------------------------------
// Defines
//---------------------------------------------------------------------------
#define SAMPLE_XML_PATH "../../Config/SamplesConfig.xml"
//#define PR1(A)
//#define PR2(A, B)
#define PR1(A) std::cout << A << endl;
#define PR2(A, B) std::cout << A << ":" << B << endl;
#define ER1(A) std::cout << A << endl;
#define ER2(A, B) std::cout << A << ":" << B << endl;
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
XnStatus nRetVal = XN_STATUS_OK;
float* g_pDepthHist;
XnRGB24Pixel* g_pTexMap = NULL;
unsigned int g_nTexMapX = 0;
unsigned int g_nTexMapY = 0;
XnDepthPixel g_nZRes;
Context g_context;
xn::ScriptNode g_scriptNode;
xn::DepthGenerator g_depth;
xn::ImageGenerator g_image;
xn::DepthMetaData g_depthMD;
xn::ImageMetaData g_imageMD;
cv::Mat colorArr[3];
cv::Mat colorImage;
const XnRGB24Pixel* pImageRow;
const XnRGB24Pixel* pPixel;
void printTime(const char *msg) ;
//---------------------------------------------------------------------------
// Code
//---------------------------------------------------------------------------
/************************************************************************
*** Callback glutIdle
*************************************************************************/
void printTime(const char *msg) {
time_t timer;
struct tm *date;
char str[256];
timer = time(NULL);
date = localtime(&timer);
PR2(msg, asctime(date));
}
/************************************************************************
*** main
*************************************************************************/
int main(int argc, char* argv[])
{
XnStatus rc;
EnumerationErrors errors;
IplImage bgrIpl;
cv::Mat bgrImage;
int i, iFrame, iClean;
int iCnt = 0;
char framenumber[10];
std::stringstream ss;
std::string str_frame_number;
// -------------------------------------------------------------------------
// check argument.
// -------------------------------------------------------------------------
if (argc != 4) {
PR1("argument error. output file, format (jpg, png), count.");
return 1;
}
iFrame = atoi(argv[3]);
if (iFrame < 1 || iFrame > 100) {
ER1("frame 1-100.");
return 1;
}
if (!(strcmp(argv[2], "bmp") == 0 ||
strcmp(argv[2], "dib") == 0 ||
strcmp(argv[2], "jpg") == 0 ||
strcmp(argv[2], "jp2") == 0 ||
strcmp(argv[2], "png") == 0 ||
strcmp(argv[2], "pbm") == 0 ||
strcmp(argv[2], "pgm") == 0 ||
strcmp(argv[2], "ppm") == 0 ||
strcmp(argv[2], "ras") == 0 ||
strcmp(argv[2], "tiff") == 0
)) {
ER1("format error.");
return 1;
}
// -------------------------------------------------------------------------
// set up OpenNI camera.
// -------------------------------------------------------------------------
// read a device configuration file and initialyze
rc = g_context.InitFromXmlFile(SAMPLE_XML_PATH, g_scriptNode, &errors);
if (rc == XN_STATUS_NO_NODE_PRESENT){
XnChar strError[1024];
errors.ToString(strError, 1024);
ER1(strError);
return (rc);
}else if (rc != XN_STATUS_OK){
ER2("Open failed ", xnGetStatusString(rc));
return (rc);
}
// Searches for an existing created node of a specified type and returns a reference to it.
rc = g_context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_depth);
if (rc != XN_STATUS_OK){
ER1("No depth node exists! Check your XML.");
return 1;
}
// Searches for an existing created node of a specified type and returns a reference to it.
rc = g_context.FindExistingNode(XN_NODE_TYPE_IMAGE, g_image);
if (rc != XN_STATUS_OK){
ER1("No image node exists! Check your XML.");
return 1;
}
PR1("first genelation*******************");
g_depth.GetMetaData(g_depthMD);
g_image.GetMetaData(g_imageMD);
PR1("***********************************");
// Hybrid mode isn't supported in this sample
if (g_imageMD.FullXRes() != g_depthMD.FullXRes() || g_imageMD.FullYRes() != g_depthMD.FullYRes()){
ER1 ("The device depth and image resolution must be equal!");
return 1;
}
// RGB is the only image format supported.
if (g_imageMD.PixelFormat() != XN_PIXEL_FORMAT_RGB24){
ER1("The device image format must be RGB24");
return 1;
}
// Texture map init
g_nTexMapX = (((unsigned short)(g_depthMD.FullXRes()-1) / 512) + 1) * 512;
g_nTexMapY = (((unsigned short)(g_depthMD.FullYRes()-1) / 512) + 1) * 512;
g_pTexMap = (XnRGB24Pixel*)malloc(g_nTexMapX * g_nTexMapY * sizeof(XnRGB24Pixel));
g_nZRes = g_depthMD.ZRes();
g_pDepthHist = (float*)malloc(g_nZRes * sizeof(float));
rc = g_context.WaitAnyUpdateAll();
if (rc != XN_STATUS_OK){
ER2("Read failed ", xnGetStatusString(rc));
return 1;
}
// -------------------------------------------------------------------------
// main routine.
// -------------------------------------------------------------------------
for (i = 0; i < iFrame; i++) {
printTime("start generation");
g_depth.GetMetaData(g_depthMD);
g_image.GetMetaData(g_imageMD);
printTime("end generation");
}
printTime("start output");
g_depth.GetAlternativeViewPointCap().SetViewPoint(g_image);
pImageRow = g_imageMD.RGB24Data();
colorArr[0] = cv::Mat(g_imageMD.YRes(), g_imageMD.XRes(),CV_8U);
colorArr[1] = cv::Mat(g_imageMD.YRes(), g_imageMD.XRes(),CV_8U);
colorArr[2] = cv::Mat(g_imageMD.YRes(), g_imageMD.XRes(),CV_8U);
printTime("create new matrix");
PR2("g_imageMD.YRes", g_imageMD.YRes());
for (int y = 0; y < g_imageMD.YRes(); y++){
pPixel = pImageRow;
uchar* Bptr = colorArr[0].ptr<uchar>(y);
uchar* Gptr = colorArr[1].ptr<uchar>(y);
uchar* Rptr = colorArr[2].ptr<uchar>(y);
for(int x=0; x < g_imageMD.XRes() ;++x , ++pPixel){
Bptr[x] = pPixel->nBlue;
Gptr[x] = pPixel->nGreen;
Rptr[x] = pPixel->nRed;
}
pImageRow += g_imageMD.XRes();
}
printTime("start merge");
cv::merge(colorArr, 3, colorImage);
printTime("start save");
sprintf(framenumber,"%s.%s",argv[1], argv[2]);
ss << framenumber;
ss >> str_frame_number;
std::string str_aux = str_frame_number;
bgrIpl = colorImage;
cvSaveImage(str_aux.c_str(), &bgrIpl);
printTime("end output");
//g_context.Shutdown();
return 0;
}
ロボット使ってトマト作れば楽だなぁ...やってみっか!
農業ロボット開発記録
日本中で100台以上動かしちゃった(^^)/
I'm developing robots that do tomato harvesting, settled planting ,,,,and many tasks.
The goal of production cost of robot is $2,000 per unit.
Because it is necessary a lot of robots, in order to innovate the farming.
I use Raspberry Pi as robot controller to develop low cost robots.
TOMATO FARM website -> CLICK!
0 件のコメント:
コメントを投稿