基於RealSense的點雲處理軟件開發(點雲顯示部分)

年前事情總是一件接一件,老闆前天晚上吃散夥飯的時候問過我自動標定的事情之後就又要我用RealSenseD435做一下點雲拼接,跟我說了一下思路就要開始趕緊做,昨天上午就在玩UE4沒做,中午吃完飯看到他有點慌,怕他啥時候突擊檢查,所以說花了一下午時間先把軟件的顯示部分做好,今天早上還沒起牀就又聽到外面有人拖着行李箱走了,心裏賊不爽,上午還是寫篇博客放鬆放鬆吧,順便把點雲顯示部分記錄分享一下,閒話不多說,那麼我們就直接進入主題,先分享思路,再細說內容,代碼我也沒有優化,基本上很雜很亂,但是實現效果還可以吧,準備今天下午或者放假回去了優化優化代碼。

首先,硬件方面我用的是Intel的RealSenseD435這款相機,軟件的方面的話我用的是MFC,之後如果有時間我還想做一款QT版本的,因爲感覺MFC真的是使用手感沒有QT舒服,我軟件目前顯示部分的話就是用的OpenGL來顯示,關於MFC的基於對話框的程序中,是沒有直接的OpenGL的控件,我看網上大多數都是使用的基於文檔形式來嵌入OpenGL的,我也按照網上前輩們的方法做了,但是感覺用起來還是沒有基於對話框版本的方便(可能目前我的意識還比較菜吧,哈哈),關於使用OpenGL嵌入MFC,此處可能我理解有些錯誤,歡迎大佬指教,就我看來可能就是將OpenGL的繪製跟pictureBox控件連接到一起,也就是將OpenGL的句柄與pictureBox控件的句柄聯繫到一起,

我們可以看到,上面是作爲pictureBox控件的句柄變量,下面就是OpenGL渲染時候的設備上下文句柄,然後就是要將這兩個句柄之間以正確的關係聯繫在一起,先上圖,

此處做法就是先獲取pictureBox控件的句柄,前兩句就是獲取到了控件句柄,然後下面兩個if中間的SetWindowPixelFormat(hrenderDC)函數就是設置OpenGL跟控件相連之後的格式,其中該函數的內容我貼在下面

BOOL COpenGLPictureDlg::SetWindowPixelFormat(HDC hDC)
{
	PIXELFORMATDESCRIPTOR pixelDesc;
	pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	pixelDesc.nVersion = 1;
	pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | 
		PFD_SUPPORT_OPENGL |
		PFD_DOUBLEBUFFER |
		PFD_TYPE_RGBA;
	pixelDesc.iPixelType = PFD_TYPE_RGBA;
	pixelDesc.cColorBits = 32;
	pixelDesc.cRedBits = 0;
	pixelDesc.cRedShift = 0;
	pixelDesc.cGreenBits = 0;
	pixelDesc.cGreenShift = 0;
	pixelDesc.cBlueBits = 0;
	pixelDesc.cBlueShift = 0;
	pixelDesc.cAlphaBits = 0;
	pixelDesc.cAlphaShift = 0;
	pixelDesc.cAccumBits = 0;
	pixelDesc.cAccumRedBits = 0;
	pixelDesc.cAccumGreenBits = 0;
	pixelDesc.cAccumBlueBits = 0;
	pixelDesc.cAccumAlphaBits = 0;
	pixelDesc.cDepthBits = 0;
	pixelDesc.cStencilBits = 1;
	pixelDesc.cAuxBuffers = 0;
	pixelDesc.iLayerType = PFD_MAIN_PLANE;
	pixelDesc.bReserved = 0;
	pixelDesc.dwLayerMask = 0;
	pixelDesc.dwVisibleMask = 0;
	pixelDesc.dwDamageMask = 0;
	PixelFormat = ChoosePixelFormat(hDC,&pixelDesc);
	if(PixelFormat==0) // Choose default
	{
		PixelFormat = 1;
		if(DescribePixelFormat(hDC,PixelFormat,
			sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
		{
			return FALSE;
		}
	}
	if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)
	{ 
		return FALSE;
	}
	return TRUE;
}

大家可以看到這個設置函數其實就是用的一個像素格式描述表,這個表功能作用大概就是要你先把等下要使用OpenGL的繪製模式給表述清楚,例如要使用單緩衝還是雙緩衝模式,像代碼片段中的第四個變量賦值就是規定的模式,就是規定了雙緩衝模式,繪製類型就是典型的RGBA模式,支持OpenGL繪製,然後下面賦值部分其實大多數根據變量命名就能知道是什麼意思,我這裏也就不一一贅述了,這裏設置完格式之後我們就要使用CreateViewGLContext(hrenderDC)來將OpenGL與pictureBox連接到一起了,

BOOL COpenGLPictureDlg::CreateViewGLContext(HDC hDC)
{
	hrenderRC = wglCreateContext(hDC);

	if(hrenderRC==NULL)
		return FALSE;

	if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
		return FALSE;

	return TRUE;
}

我們可以看到這個函數內容很少,就是使用wglCreateContext函數將hrenderRC和傳進來的句柄參數連接到一起,它的作用是創建一個新的OpenGL渲染描述表,並且繪製到參數句柄對應的設備上去,然後wglMakeCurrent(hDC,hrenderRC)這個函數作用就是使OpenGL渲染時候繪製到對應的設備上,所有後續的OpenGL調用線程都要在這個設備 HDC上繪製 ,當然後續如果想更改,或者使用多線程繪製時候,這個函數就要起很大作用,主線程和分線程之間可能就需要使用這個函數來進行不同的繪製功能了,這些都是題外話,我就不多說了,有興趣的朋友大佬可以一起交流交流,我也是個小白,至此其實就已經完成了OpenGL綁定到pictureBox控件上了,根據上面我貼出來的部分,後面也就是OpenGL的基本配置了,像視角,觀察位置,近遠距離,方向,投影模式等等這些就也不多說什麼,只是說一下glulookat和gluperspective,一個是調整觀察角度,一個是調整視角和物體顯示比例以及最近可觀察點和最遠可觀察點,這兩個函數初始化配置OpenGL的時候非常需要注意。

至此其實就已經做完了顯示部分,但是這種初級顯示如果真的用起來就太不舒服了,因爲初期可能還需要微調一下位置和旋轉角度,所以說我就又加進去了鼠標滾輪可以平移和縮放功能,這個其實就非常簡單了,直接在類嚮導裏面找到對應的消息WM_MOUSEWHEEL就能生成對應的滾輪函數,裏面函數內容的話就是

這個紅色框框部分也就是主體內容,其中m_Scale就是初始化繪製時候縮放的一個變量,也就是glScalef這個函數要用到的,然後像平移和旋轉的思路就是在初始化繪製的時候將glTranslatef和glRotatef對應的參數做成一個可變變量,然後使用對應消息響應函數就能輕鬆實現旋轉平移以及縮放功能了,大體上到這基本上就已經完成了所有顯示需要做的部分,接下來就是採集點云然後繪製就完事了,先給大家貼一個帶顏色的點雲顯示效果圖,

這裏主要是我進行了一個簡單的點雲下采樣,效果好像不太好,後續還需要進行進一步的修改,關於RealSenseD435的點雲採集部分的話我是使用的網上一個大佬封裝過的一個類,他的類的將原來RealsenseD435對應的SDK的功能封裝的相當方便了,像深度對齊顏色和顏色對齊深度這兩個直接調用他的函數就行了,當然還是建議弄懂一下這些具體實現要好一點,還有就是根據採集的彩色圖上的點找到對應的三維座標這個他的類也做好了,不得不說,大佬還是大佬,我還是隻是一個代碼搬運工,點雲採集部分的話其實很簡單就是分別採集點以及對應的顏色數據,感覺也不用贅述太多,可能就是深度對齊顏色和顏色對齊深度這部分有些許門道,這個我後續會對這個部分再寫一篇博客記錄一下的,那麼今天點雲顯示部分就先說到這,資源後續我會上傳到我的csdn上,有興趣評閱的朋友可以下載看看。

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