1. 程式人生 > >用Opencv實時畫運動軌跡的思路

用Opencv實時畫運動軌跡的思路

程式設計時發現用cvcircle只能畫出目標的當前位置,通過百度發現一種思路,目前正在實驗中。。

你獲取了手心位置當前的座標以後用來做起點,再持續跟蹤,把下一個手心座標做終點畫線,就這麼一直畫不就是運動軌跡了麼
就是儲存當前捕捉到的座標a,然後下次捕捉到座標b的時候用這對座標畫線,更新a座標為b的值,再捕捉到下一座標b畫線,重複就行了
畫線是用line函式啊,你ciecle當然是一個點了。另外不用陣列存座標,用一個變數就行了,變數的作用域要確保在跟蹤函式之外,可以用全域性變數存。

根據上述思路進行了大膽的嘗試!然後發現還是不行,只要當前影象一更新,之前畫的軌跡就全都沒了。

所以採取了下列思路:

開一個黑屏,畫紅色軌跡,等原背景影象全部更新完了,直接對著畫素值全部貼在背景影象上。。笨辦法

但是最終也實現了“實時”的顯示軌跡。。。

關鍵程式碼如下:   

			//建立全黑影象
			lineimage = cvCreateImage(cvSize(frame.cols, frame.rows),  IPL_DEPTH_8U, 3);		
			int width=lineimage->width;
			int height=lineimage->height;
			for(i;i<height;i++)
			{
					uchar* pData=(uchar*)(lineimage->imageData+i*lineimage->widthStep);
			         for(int j=0;j<width;j++)
					 {
						 pData[3*j]=0; pData[3*j+1]=0; pData[3*j+2]=0;
					 }
			}

雖然到後面發現開不開黑屏完全無所謂,只要知道自己的軌跡是用什麼鮮豔的顏色標出來的就行了,和預設生成影象顏色畫素值RGB任何一個只要不同就行了。

在這裡友情提醒:在RGB影象儲存時預設每個畫素的儲存順序是BGR!!!!

// 計算重心

         double posX = moment10 / area;
         double posY = moment01 / area;		 

		 centerpoint.x = posX;
		 centerpoint.y = posY;
		 cvCircle( sourceimage, centerpoint , 3 , CV_RGB(255,0,0), 1, 8, 0 );

		 if(( centerpoint.x > 0) && ( centerpoint.y > 0))
		 {
			 if (j == 1)
			 {
				 startpoint = centerpoint;
				 endpoint = startpoint;
				 j = 2;
			 }
			 if((j > 1) && ( centerpoint.x > 0) && ( centerpoint.y > 0))
			 {
				 endpoint = centerpoint;
				 cvLine( lineimage, startpoint, endpoint, CV_RGB( 255, 0, 0), 1);
				 startpoint = endpoint;
			 }
		 }

//將軌跡貼到背景影象上
		    int width = lineimage->width;
			int height = lineimage->height;
			for(int k = 0; k < height; k++)
			{
					uchar* pData = (uchar*)(lineimage->imageData + k*lineimage->widthStep);
			        uchar* pbData = (uchar*)(backimage->imageData + k*backimage->widthStep);
			         for(int j = 0; j < width; j++)
					 {
						 if( pData[3*j+2] == 255)
						     {
								 pbData[3*j] = 0;
								 pbData[3*j+1] = 0;
								 pbData[3*j+2] = 0;
							}
					 }
			}