您的位置:首页 > 运维架构

利用颜色表进行图像预处理1:OpenGl显示三维颜色表

2012-04-01 16:22 549 查看
在学习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: liuying31195@126.com

本文创建日期: 2012-4-1

原文地址链接:http://blog.csdn.net/liuying_1001/article/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐