利用顏色表進行圖像預處理1:OpenGl顯示三維顏色表

在學習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/

發佈了59 篇原創文章 · 獲贊 91 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章