0

我有一個攝像頭,我從哪裏接收ByteBuffer爲每個幀。我從ByteBuffer中提取640px x 480px 11位灰度圖像,並將其保存爲[640] [480]。我這樣做是因爲我不需要它作爲圖像,我認爲這會更快(如果我錯了,請糾正我)。什麼將是一個很好的算法來找到圖像移位(Java)

現在每秒完成約30次。對於每一幀,程序將保存相差20以上的任何值,並且小於當前像素的現有值到該像素的值。它在我的簡短[640] [480]中有效地創建了背景圖片。

現在,對於這個問題,相機可能會移動,從而移動背景。我從一個不移動的相機中獲得的背景已經改變了每一幀很多(也有很大的利潤)。真的,它只是足夠穩定,可以提取大的前景物體。所以我需要一個算法,可以告訴我相機的多少以及圖像的偏移,所以我知道哪些區域是圖像中的新區域,但大多數區域仍然可用。

我能想到的唯一的辦法就是掃描每一個可能的遷移的圖像,看哪個最匹配,因爲就像我說的,它可能只是無法比擬的那麼好,但仍然是最好的搭配。有沒有更好的方法來解決這個問題?因爲這樣我會掃描整個圖像每幀大約1,2萬次......

另外我不使用加工或OpenCV的或任何這樣的庫。

編輯: 我忘了提一個很重要的細節,圖像是深度圖,照明不會影響它。

編輯:下面是一些代碼,我用的是開放Kinect的庫檢索來自Kinect的深度圖。我還不知道如何解析的信息,這是我得到它的工作至今的唯一途徑:

public static short[][] background = new short[640][480]; 

public void onFrameReceived(FrameMode format, ByteBuffer frame, int timestamp) { 

    for(int n=0; n<frame.limit()/2; n++) { 

     int index = n*2; 
     short Gray = (0xff - frame.get(index) & 0xff) | ((3-frame.get(index+1) & 0x3) * 255); 

     short x = n%640; 
     short y = n/640; 

     if(background[x][y] > Gray + 10 || background[x][y] == 0) { 
      background[x][y] = Gray; 
     } 
    } 
} 

我得到每幀2個字節從中我試圖提取11位值,表示物體離我的kinect有多遠。我不知道如何去做這件事,但它是這樣工作的,所以我稍後會保存這個問題。

附加信息:frame.limit()是字節緩衝區中的字節數。 frame.get從我的bytebuffer中獲取一個字節。出於某種原因,Kinect的向我發送的字節向後順序...

+0

http://en.wikipedia.org/wiki/Image_registration –

+0

難道是某個地方小lightsource(pointmarker)在現場簡化移檢測是否可行? – fvu

+0

不幸的是,它不得不在很多不同的設置下工作,對於背景可以說很少。此外,它是一個深度圖。 –

回答

1

您應該使用的圖片庫,它比你自己的實現更容易,更強大和更高效。爲了檢測背景偏移,我會計算圖像的漸變並將其與前一幅相比較。模糊圖像可能很有趣。您可以使用二次函數來比較前一個梯度和當前梯度之間的誤差。

+0

我想,我得到了JavaCV的工作,所以我會用它... –

1

這是我會怎樣確定是否相機移動。當然,一些填充和方差將要被添加到「detectChange()」,但由於我不熟悉你的數據結果,我不能確定的是:

//pick 100 points at random 
private static Point[] keys = new Point[100]; 

//initially set to the values of background at the key points 
private static short[] keyValues = new short[100]; 


private bool detectChange() 
{ 
    boolean changed = false; 
    int amtchanged = 0; 
    for(int i = 0; i < 100; i++) 
    { 
     //point some variance here for leeway 
     if(background[keys[i].x][keys[i].y] != keyValues[i]) 
      amtchanged++; 
    } 

    if(amtchanged > 75) 
     changed = true; 

    return changed 
} 

public void onFrameReceived(FrameMode format, ByteBuffer frame, int timestamp) { 

    if(detectChange()) 
    { 
     //find where they went to determine 
     //the camera's pan 
    } 

    //the rest of your code. 

    for(int i = 0; i < 100; i++) 
    { 
     //update the keys to the new data 
     keyValues[i] = background[keys[i].x][keys[i].y]; 
    } 
} 
+0

感謝您付出的努力,值得我在可以(如果有的話)時給予+1。無論哪種方式,我決定在這一方面採取另一種方式。 –

相關問題