在學習SPL世界冠軍B-Human的框架程序和具體實現中覺得我們與世界冠軍相差的太遠了。即使是北京大學功夫隊(參見http://www.mech.pku.edu.cn/robot/fourleg/cn/index.htm)與世界頂尖隊伍相差的也很多。北大功夫隊在代碼量、代碼結構、效果上都沒有世界一流隊伍的好。這和我們整個國家的教育體制,培養方法都有關係。我等P民能做的就是儘自己一份微薄之力。
在B-Human裏,圖像的預處理是利用Colortable的。預處理做好了纔有後面的高效的識別。視覺毫無疑問是仿人足球比賽的最重要的基礎。所以如果你是做仿人機器人或者是以視覺爲主導的機器人,預處理一定要做好了。切勿急躁。接下來,是產生顏色表的一個準備工作:顏色表中的幾類顏色顯示在一個RGB三維模型中。這樣做我認爲有一個好處是你可以觀察到所學習的幾類顏色在RGB空間中所佔的位置、數量以及它們是否有交叉。
在這裏闡述一下利用顏色表進行預處理的工作原理(以足球比賽爲背景加以舉例說明)。首先需要人工採集顏色形成顏色表(colorTable[256][256][256] ),具體就是先通過機器人的攝像頭採集場地圖像,然後確定將要你選的顏色,比如綠色(可以把綠色標記爲1),接下來點擊圖像上的綠色,假設你點擊的同時就獲取了你所點擊處的像素值RBG(210,201,30)。那麼這樣賦值 colorTable[210][201][30] = 1;這個像素點的顏色就被標記到顏色表中了。 採集綠色的多種情況(畢竟由於攝像頭,光線等原因造成顏色像素的改變)。當然只是這樣並不夠,你還需要進行擴展,例如你可以將colorTable[211][201][30] 直接賦值爲1。然而在RGB空間中表現不出顏色的色相,也就是你不能直接通過修改RGB值來找到與其相似的顏色,以後再討論。同理你可以將紅色定義爲2,學習紅色。最後你的顏色表中,即colorTable[256][256][256],其實元素的值爲0或者1或者2.
利用顏色表進行預處理。建立好了顏色表處理起來就簡單了。將處理的圖像中的每一個像素點的RGB值取出來作爲索引。如圖像的第一個像素的的RGB值爲(140,32,52,)。那麼查看 colorTable[140][32][52]的值爲多少,如果爲1,那麼這個像素點就爲綠色,如果爲2就爲紅色,如果是0顏色未知。當然這個顏色表可以包含多種顏色,在SPL中有7中之多。
好了,閒話少說,看看怎樣用OpenGl顯示三維立體空間,並在空間中顯示顏色類型。我所使用的的環境爲 Win7+VS2008+OpenGl。OpenGl的配置見http://www.360doc.com/content/10/1127/16/1393127_72890611.shtml 。程序可以使用鼠標拖動三維立體旋轉。(程序來自網絡經過個人修改)。
// 立方體.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#pragma comment( lib, "glaux.lib" )
#pragma comment( lib, "glu32.lib" )
#pragma comment( lib, "opengl32.lib" )
#define GLUT_DISABLE_ATEXIT_HACK
#include <math.h>
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>
#include <stdio.h>
#include <io.h>
#include <GL/glut.h>
#define bool int
#define false 0
#define true 1
#define M_PI 3.1415926
int winWidth, winHeight;
float angle = 0.0, axis[3], trans[3];
bool trackingMouse = false;
bool redrawContinue = false;
bool trackballMove = false;
void colorcube(void);
/* Draw the cube */
GLfloat vertices[][3] = {
{-1.0,-1.0,-1.0}, {1.0,-1.0,-1.0}, {1.0,1.0,-1.0}, {-1.0,1.0,-1.0},
{-1.0,-1.0,1.0}, {1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}
};
// GLfloat space[][3] = {
// {-0.023,-0.023,-0.023}, {0.023,-0.023,-0.023}, {0.023,0.023,-0.023}, {-0.023,0.023,-0.023},
// {-0.023,-0.023,0.023}, {0.023,-0.023,0.023}, {0.023,0.023,0.023}, {-0.023,0.023,0.023}
// };
GLfloat space[8][3];
GLfloat colors[][3] = {
{0.0,1.0,0.0}, {1.0,0.0,0.0}, {1.0,1.0,0.0}, {0.0,1.0,0.0},
{0.0,0.0,1.0}, {1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0}
};
void polygon(int a, int b, int c , int d, int face)
{
/* draw a polygon via list of vertices */
glBegin(GL_LINE_LOOP);//選項畫連續的線
glColor3fv(colors[6]);
glVertex3fv(vertices[a]);
glVertex3fv(vertices[b]);
glVertex3fv(vertices[c]);
glVertex3fv(vertices[d]);
glEnd();
glBegin(GL_POLYGON); //畫指定的顏色粒子
glColor3fv(colors[0]);
glVertex3fv(space[a]);//指定粒子的各個頂點
glVertex3fv(space[b]);
glVertex3fv(space[c]);
glVertex3fv(space[d]);
glEnd();
}
void colorSpace(char r,char g,char b)
{
r = r-32;
g = g-32;
b = b-32;
// GLfloat space[][3]=
// {
// {-0.02*r,-0.02*g,-0.02*b}, {0.02*r,-0.02*g,-0.02*b}, {0.02*r,0.02*g,-0.02*b}, {-0.02*r,0.02*g,-0.02*b},
// {-0.02*r,-0.02*g,0.02*b}, {0.02*r,-0.02*g,0.02*b}, {0.02*r,0.02*g,0.02*b}, {-0.02*r,0.02*g,0.02*b}
//
// };
space[0][0] = 0.02*r-0.003;
space[0][1] = 0.02*g-0.003;
space[0][2] = 0.02*b-0.003;
space[1][0] = 0.02*r+0.003;
space[1][1] = 0.02*g-0.003;
space[1][2] = 0.02*b-0.003;
space[2][0] = 0.02*r+0.003;
space[2][1] = 0.02*g+0.003;
space[2][2] = 0.02*b-0.003;
space[3][0] = 0.02*r-0.003;
space[3][1] = 0.02*g+0.003;
space[3][2] = 0.02*b-0.003;
space[4][0] = 0.02*r-0.003;
space[4][1] = 0.02*g-0.003;
space[4][2] = 0.02*b+0.003;
space[5][0] = 0.02*r+0.003;
space[5][1] = 0.02*g-0.003;
space[5][2] = 0.02*b+0.003;
space[6][0] = 0.02*r+0.003;
space[6][1] = 0.02*g+0.003;
space[6][2] = 0.02*b+0.003;
space[7][0] = 0.02*r-0.003;
space[7][1] = 0.02*g+0.003;
space[7][2] = 0.02*b+0.003;
colorcube();
}
void colorcube(void)
{
/* map vertices to faces */
polygon(1,0,3,2,0);
polygon(3,7,6,2,1);
polygon(7,3,0,4,2);
polygon(2,6,5,1,3);
polygon(4,5,6,7,4);
polygon(5,4,0,1,5);
}
/* These functions implement a simple trackball-like motion control */
float lastPos[3] = {0.0F, 0.0F, 0.0F};
int curx, cury;
int startX, startY;
void trackball_ptov(int x, int y, int width, int height, float v[3])
{
float d, a;
/* project x,y onto a hemisphere centered within width, height */
v[0] = (2.0F*x - width) / width;
v[1] = (height - 2.0F*y) / height;
d = (float) sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = (float) cos((M_PI/2.0F) * ((d < 1.0F) ? d : 1.0F));
a = 1.0F / (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *= a;
v[1] *= a;
v[2] *= a;
}
void mouseMotion(int x, int y)
{
float curPos[3], dx, dy, dz;
trackball_ptov(x, y, winWidth, winHeight, curPos);
if(trackingMouse)
{
dx = curPos[0] - lastPos[0];
dy = curPos[1] - lastPos[1];
dz = curPos[2] - lastPos[2];
if (dx || dy || dz) {
angle = 90.0F * sqrt(dx*dx + dy*dy + dz*dz);
axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
lastPos[0] = curPos[0];
lastPos[1] = curPos[1];
lastPos[2] = curPos[2];
}
}
glutPostRedisplay();
}
void startMotion(int x, int y)
{
trackingMouse = true;
redrawContinue = false;
startX = x; startY = y;
curx = x; cury = y;
trackball_ptov(x, y, winWidth, winHeight, lastPos);
trackballMove=true;
}
void stopMotion(int x, int y)
{
trackingMouse = false;
angle = 0.0f;
axis[0] = 0.0f;
axis[1] = 0.0f;
axis[2] = 0.0f;
if (startX != x || startY != y)
{
redrawContinue = true;
}
else
{
angle = 0.0F;
redrawContinue = false;
trackballMove = false;
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
/* view transform */
if (trackballMove)
{
glRotatef(angle, axis[0], axis[1], axis[2]);//控制三維立旋轉的函數
}
colorcube();
int r = 25;
int g = 13;
int b = 34;
for (int i=0;i<4;i++)
{
for (int j =0;j<8;j++)
{
for (int k =0;k<16;k++)
{
colorSpace(r+i,g+j,b+k);
}
}
}
glutSwapBuffers();
}
void mouseButton(int button, int state, int x, int y)
{
if(button==GLUT_RIGHT_BUTTON)
exit(0);
if(button==GLUT_LEFT_BUTTON)
switch(state)
{
case GLUT_DOWN:
y=winHeight-y;
startMotion(x,y);
break;
case GLUT_UP:
stopMotion(x,y);
break;
}
}
void myReshape(int w, int h)
{
glViewport(0, 0, w, h);
winWidth = w;
winHeight = h;
}
void spinCube()
{
if (redrawContinue) glutPostRedisplay();//glutPostRedisplay 標記當前窗口需要重新繪製
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);//指定雙緩存RGB顯示與深度緩存模式
glutInitWindowSize(500, 500);
glutCreateWindow("colorcube");
glutReshapeFunc(myReshape); //窗口改變時,指定所調用的回調函數
glutDisplayFunc(display);
glutIdleFunc(spinCube);
glutMouseFunc(mouseButton); //註冊鼠標回調函數
glutMotionFunc(mouseMotion);
glEnable(GL_DEPTH_TEST); //If enabled, do depth comparisons and update the depth buffer. See glDepthFunc and glDepthRange
glMatrixMode(GL_PROJECTION); //GL_PROJECTION,對投影矩陣應用隨後的矩陣操作
glLoadIdentity(); //該函數的功能是重置當前指定的矩陣爲單位矩陣
glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);//將當前的可視空間設置爲正投影空間範圍2.0 -2.0
glMatrixMode(GL_MODELVIEW); //GL_MODELVIEW,對模型視景矩陣堆棧應用隨後的矩陣操作
glutMainLoop();
}
本文作者email: [email protected]
本文創建日期: 2012-4-1
原文地址鏈接:http://blog.csdn.net/liuying_1001/article/