Што б добры алгарытм, каб знайсці змены малюнкаў (Java)

У мяне ёсць камера, з якой я атрымліваю ByteBuffer для кожнага кадра. Я выняць 640px х 480px 11 разраднае паўтонавыя малюнак з ByteBuffer і захаваць яго, каб кароткі [640] [480]. Я раблю гэта таму, што я не буду мець патрэбу ў выглядзе малюнка, і я думаў, што гэта будзе хутчэй (калі ласка, папраўце мяне, калі я памыляюся).

Зараз гэта робіцца каля 30 раз у секунду. З кожным кадрам праграма захавае любыя значэння, якія адрозніваюцца больш чым на 20, і якія менш, чым існае значэнне для бягучага пікселя ў да значэння гэтага пікселя. Гэта фактычна стварае фонавы малюнак у маім кароткім [640] [480].

Цяпер пытанне, камера можа перамяшчацца такім чынам, зрушваючы фон. А фон я атрымліваю ад ня рухаецца камеры ўжо змяняе шмат (і з вялікімі палямі) кожны кадр. На самой справе гэта толькі дастаткова стабільна, каб атрымаць вялікія пярэднія наземныя аб'екты. Так што я патрэбны алгарытм, які можа сказаць мне, колькі зрушыліся камеры і, такім чынам, малюнак, так што я ведаю, якія вобласці з'яўляюцца новымі ў вобразе, але ў асноўным, якія вобласці яшчэ прыдатныя да ўжывання.

Адзіны спосаб, якім я мог думаць толькі пра тое, каб адсканаваць малюнак для кожнага магчымага зруху і ўбачыць, якія матчы лепш, таму што, як я сказаў, гэта можа быць проста не супадаюць усё гэта добра, але ўсё роўна лепшы матч. Ці ёсць лепшы спосаб пайсці на гэты конт? Таму што такім чынам я павінен быў бы сканаваць увесь малюнак прыкладна 1,2 мільёна разоў за кадр ...

Акрамя таго, я не выкарыстоўваю апрацоўку або OpenCV або любыя такія бібліятэкі.

змяніць: Я забыўся згадаць вельмі важную дэталь, малюнак карты глыбіні так асвятлення не ўплывае на гэта.

Edit: Вось код, я выкарыстоўваю бібліятэку Open Kinect для атрымання карты глыбіні ад Kinect. Я не ведаю, як аналізаваць інфармацыю, гэта адзіны спосаб, я атрымаў яго на працу да гэтага часу:

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

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

    for(int n=0; n Gray + 10 || background[x][y] == 0) {
            background[x][y] = Gray;
        }
    }
}

Я атрымліваю 2 байта на кадр, з якога я спрабую атрымаць значэнне 11 біт, уяўляе, як далёка аб'ект знаходзіцца ад майго Kinect. Я паняцця не маю, як яшчэ ісці пра гэта, але гэта працуе як гэта так я выратую гэтае пытанне пазней.

Дадатковая інфармацыя: frame.limit() з'яўляецца сумай байтаў ў ByteBuffer. frame.get атрымлівае адзін байт з майго ByteBuffer. Па нейкай прычыне пасылае мне Kinect байты ў зваротным парадку ...

0
Можа быць, я павінен зваліцца метад аднімання фону, які я спрабую паспрабаваць тут? Ён можа працаваць лепш без яго ...
дададзена аўтар Samuel Willems, крыніца
Можа быць, я павінен зваліцца метад аднімання фону, які я спрабую паспрабаваць тут? Ён можа працаваць лепш без яго ...
дададзена аўтар Samuel Willems, крыніца
Можа быць, я павінен зваліцца метад аднімання фону, які я спрабую паспрабаваць тут? Ён можа працаваць лепш без яго ...
дададзена аўтар Samuel Willems, крыніца
Вядома, я магу дадаць некаторы код, гэта Java, хоць ...
дададзена аўтар Samuel Willems, крыніца
Вядома, я магу дадаць некаторы код, гэта Java, хоць ...
дададзена аўтар Samuel Willems, крыніца
Вядома, я магу дадаць некаторы код, гэта Java, хоць ...
дададзена аўтар Samuel Willems, крыніца
Хм гучыць, як гэта ... Дзякуй, я дам яму стрэлілі.
дададзена аўтар Samuel Willems, крыніца
Точно ... @ Mike Гэта боль ...
дададзена аўтар Samuel Willems, крыніца
На жаль, няма, ён павінен працаваць у шмат розных налад, мала што можна сказаць пра фонавым рэжыме. Акрамя таго, гэта карта глыбіні.
дададзена аўтар Samuel Willems, крыніца
Я не эксперт, але я думаю, што я б падысці да гэтага шляхам выбаркі 4 кутоў малюнка плюс цэнтр, і ўбачыць, калі я магу знайсці матч у існуючым малюнку. Ваш ўзор павінен быць дастаткова вялікім, каб выключыць нейкі рух з кута кадра, але досыць малы, каб зрабіць гэта хутка. Каб выключыць светлавыя пераходы ад вясёлкі камеры або змены агульнага асвятлення, я хацеў бы зрабіць матч, выкарыстоўваючы працэнт самых лёгкіх да самых цёмных.
дададзена аўтар CodeChimp, крыніца
Было б мэтазгодна размясціць невялікі LightSource (pointmarker) дзесьці ў сцэне, каб спрасціць выяўленне зруху?
дададзена аўтар fvu, крыніца
дададзена аўтар Oliver Charlesworth, крыніца
@SamuelWillems калі вы хочаце звязаць мне код, я быў бы шчаслівы, каб гусак на яго. Я зрабіў крыху працы з аналізам пікселяў ў C ++ на працягу многіх гадоў.
дададзена аўтар Mike, крыніца
@SamuelWillems калі вы хочаце звязаць мне код, я быў бы шчаслівы, каб гусак на яго. Я зрабіў крыху працы з аналізам пікселяў ў C ++ на працягу многіх гадоў.
дададзена аўтар Mike, крыніца
Ах, я і Kinect старыя ворагі.
дададзена аўтар Mike, крыніца
Ах, я і Kinect старыя ворагі.
дададзена аўтар Mike, крыніца
Ах, я і Kinect старыя ворагі.
дададзена аўтар Mike, крыніца
@SamuelWillems калі вы хочаце звязаць мне код, я быў бы шчаслівы, каб гусак на яго. Я зрабіў крыху працы з аналізам пікселяў ў C ++ на працягу многіх гадоў.
дададзена аўтар Mike, крыніца
@SamuelWillems вы не збіраецеся знайсці ідэальнае рашэнне з нізкім дазволам шумных малюнкаў. Я хацеў бы стварыць масіў каля 100 кропак, якія былі раскіданыя па ўсім малюнку. Я б запісваць піксельныя дадзеныя ў гэтых 100 пунктаў кожны кадр. Затым, калі вялікая частка з іх зменіцца (скажам, 75%), то можна меркаваць, што камера рухаецца. Адтуль вам трэба будзе выглядаць як налева, так і направа (але толькі зрушэнне каля 20 пікселяў), каб знайсці патрэбны шаблон зноў (зноў жа, з дакладнасцю прыкладна на 75%). Гэта адымае шмат часу, але, верагодна, ваш лепшы выбар.
дададзена аўтар Mike, крыніца
@CodeChimp праблема з тым, як вы ведаеце, калі камера перамяшчаецца налева або направа? Калі ён перамяшчаецца направа, левыя куты з'едуць, правільныя куты будуць новымі, і калі фон быў досыць мяккім, усё гэта было б неазначальнай адзін ад аднаго.
дададзена аўтар Mike, крыніца

8 адказы

Вы павінны выкарыстоўваць бібліятэку малюнкаў, гэта будзе прасцей, надзейней і больш эфектыўна, чым у вас ёсць рэалізацыі. Для вызначэння фону зруху, я б вылічыць градыент вашага малюнка і параўнаць яго з папярэднім. Гэта можа быць цікава для размыцця малюнка. Можна параўнаць з выкарыстаннем квадратычнай функцыі хібнасці паміж былым градыентам і бягучых.

1
дададзена
Я думаю, я атрымаў JavaCV працаваць, так што я буду выкарыстоўваць гэта ...
дададзена аўтар Samuel Willems, крыніца

Вы павінны выкарыстоўваць бібліятэку малюнкаў, гэта будзе прасцей, надзейней і больш эфектыўна, чым у вас ёсць рэалізацыі. Для вызначэння фону зруху, я б вылічыць градыент вашага малюнка і параўнаць яго з папярэднім. Гэта можа быць цікава для размыцця малюнка. Можна параўнаць з выкарыстаннем квадратычнай функцыі хібнасці паміж былым градыентам і бягучых.

1
дададзена
Я думаю, я атрымаў JavaCV працаваць, так што я буду выкарыстоўваць гэта ...
дададзена аўтар Samuel Willems, крыніца

Вы павінны выкарыстоўваць бібліятэку малюнкаў, гэта будзе прасцей, надзейней і больш эфектыўна, чым у вас ёсць рэалізацыі. Для вызначэння фону зруху, я б вылічыць градыент вашага малюнка і параўнаць яго з папярэднім. Гэта можа быць цікава для размыцця малюнка. Можна параўнаць з выкарыстаннем квадратычнай функцыі хібнасці паміж былым градыентам і бягучых.

1
дададзена
Я думаю, я атрымаў JavaCV працаваць, так што я буду выкарыстоўваць гэта ...
дададзена аўтар Samuel Willems, крыніца

Вы павінны выкарыстоўваць бібліятэку малюнкаў, гэта будзе прасцей, надзейней і больш эфектыўна, чым у вас ёсць рэалізацыі. Для вызначэння фону зруху, я б вылічыць градыент вашага малюнка і параўнаць яго з папярэднім. Гэта можа быць цікава для размыцця малюнка. Можна параўнаць з выкарыстаннем квадратычнай функцыі хібнасці паміж былым градыентам і бягучых.

1
дададзена
Я думаю, я атрымаў JavaCV працаваць, так што я буду выкарыстоўваць гэта ...
дададзена аўтар Samuel Willems, крыніца

Гэта, як я б вызначыць, калі камера перамяшчаецца. Вядома, некаторая абіўка і дысперсія будуць хацець быць дададзеныя да «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];
    }
}
1
дададзена
Дзякуй за намаганні, для чаго гэта каштуе, я +1 да калі я магу (калі калі-небудзь). У любым выпадку я вырашыў пайсці іншым шляхам на гэтым.
дададзена аўтар Samuel Willems, крыніца

Гэта, як я б вызначыць, калі камера перамяшчаецца. Вядома, некаторая абіўка і дысперсія будуць хацець быць дададзеныя да «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];
    }
}
1
дададзена
Дзякуй за намаганні, для чаго гэта каштуе, я +1 да калі я магу (калі калі-небудзь). У любым выпадку я вырашыў пайсці іншым шляхам на гэтым.
дададзена аўтар Samuel Willems, крыніца

Гэта, як я б вызначыць, калі камера перамяшчаецца. Вядома, некаторая абіўка і дысперсія будуць хацець быць дададзеныя да «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];
    }
}
1
дададзена
Дзякуй за намаганні, для чаго гэта каштуе, я +1 да калі я магу (калі калі-небудзь). У любым выпадку я вырашыў пайсці іншым шляхам на гэтым.
дададзена аўтар Samuel Willems, крыніца

Гэта, як я б вызначыць, калі камера перамяшчаецца. Вядома, некаторая абіўка і дысперсія будуць хацець быць дададзеныя да «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];
    }
}
1
дададзена
Дзякуй за намаганні, для чаго гэта каштуе, я +1 да калі я магу (калі калі-небудзь). У любым выпадку я вырашыў пайсці іншым шляхам на гэтым.
дададзена аўтар Samuel Willems, крыніца