Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marker detection problem after the first time #392

Open
MasoudShah opened this issue May 11, 2024 · 4 comments
Open

Marker detection problem after the first time #392

MasoudShah opened this issue May 11, 2024 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@MasoudShah
Copy link

There is a problem with marker detection. For the first time that a marker gets detected, everything is ok. But the second time and subsequent occurrence of detections, it seems that the position of the marker has an initial value and it gets corrected after some seconds. This amount of time is due to using filters for omitting noises, but the problem is that this filter shouldn't be active for initial frame of tracking (as the marker gets detected). It should behave like the first time of detection that probably no value of position is initialized. The video in this link shows the difference between the first and second detection. It seems that for the second detections, there is some animation for showing the threejs object, but I have verified, there is no animation at all. It's just about the position of the target marker at the beginning of detection. I should note that this problem doesn't exist in the threaded version.

@MasoudShah
Copy link
Author

I think I found the causing problem. It seems that the matrixGL_RH value (which the marker position depends on it), at the beginning of detection is not precise. Then the updating of position takes time due to one-euro-filter operation. The solution is to turn off the filter for the initial frames after the detection. For example, the first five frames, update without filter affection. I noticed the problem solves with this method.

@kalwalt
Copy link
Member

kalwalt commented May 22, 2024

Hi @MasoudShah thank you for this, I have also noticed this issue, have you a patch so i can test it?

@kalwalt kalwalt self-assigned this May 22, 2024
@kalwalt kalwalt added the bug Something isn't working label May 22, 2024
@MasoudShah
Copy link
Author

Something like this

...
class OneEuroFilter {
  constructor({ minCutOff, beta }) {
    this.minCutOff = minCutOff;
    this.beta = beta;
    this.dCutOff = 0.001; // period in milliseconds, so default to 0.001 = 1Hz
    this.framesToSkip = 10;

    this.xPrev = null;
    this.dxPrev = null;
    this.tPrev = null;
    this.warmup = 0;
  }

  reset() {
    this.warmup = 0;
  }

  filter(t, x) {
    if (this.warmup < this.framesToSkip) {
      this.warmup++;
      this.xPrev = x;
      this.dxPrev = x.map(() => 0);
      this.tPrev = t;
      return x;
    }
    const { xPrev, tPrev, dxPrev } = this;
...

This change only protects the first frames of detection from filter effect. But another problem shows up that for some milliseconds, the threejs object shows in very different position and attitude. To amend this problem, I used 100 milliseconds delay to show the object and playing video, that the user almost doesn't understand at all. Instead of

ARVideos[index].play();
planes[index].visible = true;

in the main script for showing objects, I used this:

setTimeout((idx) => {
      ARVideos[idx].play();
      planes[idx].visible = true;
}, 100, index);

I only noted the solution for you, to do it yourself with your own code structure. If there is still some vagueness, let me know.

@kalwalt
Copy link
Member

kalwalt commented May 25, 2024

Something like this

...
class OneEuroFilter {
  constructor({ minCutOff, beta }) {
    this.minCutOff = minCutOff;
    this.beta = beta;
    this.dCutOff = 0.001; // period in milliseconds, so default to 0.001 = 1Hz
    this.framesToSkip = 10;

    this.xPrev = null;
    this.dxPrev = null;
    this.tPrev = null;
    this.warmup = 0;
  }

  reset() {
    this.warmup = 0;
  }

  filter(t, x) {
    if (this.warmup < this.framesToSkip) {
      this.warmup++;
      this.xPrev = x;
      this.dxPrev = x.map(() => 0);
      this.tPrev = t;
      return x;
    }
    const { xPrev, tPrev, dxPrev } = this;
...

This change only protects the first frames of detection from filter effect. But another problem shows up that for some milliseconds, the threejs object shows in very different position and attitude. To amend this problem, I used 100 milliseconds delay to show the object and playing video, that the user almost doesn't understand at all. Instead of

ARVideos[index].play();
planes[index].visible = true;

in the main script for showing objects, I used this:

setTimeout((idx) => {
      ARVideos[idx].play();
      planes[idx].visible = true;
}, 100, index);

I only noted the solution for you, to do it yourself with your own code structure. If there is still some vagueness, let me know.

Thank you @MasoudShah i will try it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants