用Opencv實時畫運動軌跡的思路
阿新 • • 發佈:2019-01-03
程式設計時發現用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;
}
}
}