-
Notifications
You must be signed in to change notification settings - Fork 928
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
[bug report] Stretched camera feed #498
Comments
@marcusx2 this is a known problem, I will try to get to it when I have a moment. |
@marcusx2 thanks for the tip re. MindAR. |
In the On this file https://github.com/hiukim/mind-ar-js/blob/master/src/image-target/aframe.js this code snippet seems to be the solution
|
@nickw1 If I use The scale of the cube is |
Thanks for that. I think what I'll probably do is incorporate fixes for all your issues into a new version 3.5, with the agreement of @kalwalt, as the world-origin-as-original-GPS-position will be a breaking change. I'll also try and add the multiple cameras feature. |
It doesn't have to be breaking if it's optional! It can default to false to keep the functionality as it is.
Multiple cameras? Don't know anything about that. Must be some other feature request. |
I just thought that, as you have made quite a few requests, it would be best to collate them and include them in a new release. And if the initial position as world origin is the preferred behaviour anyway, maybe it's best to make that the default by switching to that with a 3.5 release. It won't affect most use cases anyhow. (This will also fit in with some other work I'm doing to try and combine AR.js with the SLAM library AlvaAR). Sorry, I lost track of who requested the multiple cameras feature! |
It is better for other frameworks(PlayCanvas and Unity at least, probably more) that want to use arjs like I explained because of the floating point issue. I also think it semantically makes sense as well that the experience starts at world origin.
AlvaAR integration would be amazing for sure! AlvaAR alone without geolocation would already be awesome: world tracking on the web! Just to summarize this issue includes 2 bug reports: 1- Camera feed stretching when |
@marcusx2 I have implemented your suggested fix for stretching for the Do you want to try testing it? You need to check out the
|
I simply got the files ar-threex-location-only and aframe-ar from the branch and added to the same folder as the index.html. Like this
Should be correct right? The fix didn't work here though, unless I missed something.
Please don't deprecate/remove it. videoTexture: false is better for projects that use AR.js as an API to get the information about positioning and apply it elsewhere. For example, for PlayCanvas I don't need the videoTexture to be true because I just get the information of the camera and entities, and use it to place the objects in PlayCanvas, which draws the scene in its own Canvas which overlays the video element. The threejs canvas is completely useless for cases like this, just consuming unnecessary resources, because I don't need aframe/threejs to actually draw anything. |
If it helps anything, you can take a look at this issue from another repo. I tried the fix provided there but it didn't work here. Maybe the JeelizResizer and/or the JeelizThreeHelper can give some clues. |
I tried checking out the new branch as well, just in case. Still didn't work =/. The problem happens on my Android Chrome and on iOS Safari, and also on Chrome for desktop (stretched horizontally). |
Does the bug not happen with you? Hopefully it's something that you can debug. |
I know, but it might be something that requires some research to fix. This is very much dependent on my time availability, which is a bit restricted right now - whereas the other two problems are already fixed. Hence, as soon as #507 and #508 have been reviewed, I can make a bugfix release for those two issues, at least. |
Can this bug be worked around in current version of AR.js? |
bump |
Hey @nickw1 , I recently had this stretching issue with another app, and I fixed it with something like this
don't know if this applies to arjs or not, but the problem I was having on said app is that depending if the it started on landscape mode or portrait mode, I had to swap the video width with the video height and vice versa so that the aspect ratio was always correct and it didn't show up stretched. I had to check for the first resize event and detect if the app started in portrait or landscape...anyways. Don't know if this helps at all, but just throwing it here just in case, who knows. I really need this |
@kbs1 I've found a workaround:
I'm full-screening because I want to but the only important bit is the button removal then setting the style attribute. I found the style doesn't work if set directly, probably something to do with setting the style after AR.js is done setting up the scene. So I imagine you can get this to work without the 'start' button by just getting the start function to run after the first gps camera position is updated, although I haven't tried it:
|
Never-mind actually, just noticed that for some reason changing the video's CSS seems to destroy all entities as does setting a-scene to embedded |
@marcusx2 @Platform-Group apologies for the late reply, I've had very little time to look at AR.js lately. @marcusx2 could you submit your fix as a PR? Please provide a sample which works with the fix and doesn't work without the fix. This will ease the integration into the main repo. |
@nickw1 I didn't apply anything to ARJS. It's just that I had a similar problem with something else and posted my solution here, which maybe can be used by ARJS with the same idea or something similar. |
I've found out that the issue arises when camera aspect ratio is not the same as device (mobile phone) aspect ratio, or more specifically, usable viewport aspect ratio. I've found out that AR.js creates a PlaneBufferGeometry of width 1 and height 1, if you tweak these values to have the same aspect ratio as the viewport, you can then unstretch the video feed (video texture) on that particular device. |
@kbs1 is this tweaking done by modifying ar.js's source code? |
@Platform-Group yes, you can search the source for PlaneBufferGeometry, there will be 2 instances. You can find the active one based on your use case and tweak the values there. For my use case, I added reading from window (global) so the correct values can be calculated before initialising AR.js itself |
@kbs1 thanks for that. Do you want to submit a PR to fix the issue? |
@nickw1 the fix I used was not proper, and it required reading from magic I'm not familiar with AR.js / aframe / three.js codebases enough to develop a proper fix, but for the fix itself, further research is also needed. The way I understand it AR.js creates a plane that is filled with video texture (the camera feed). This plane is 1x1 in dimensions. Somehow, this plane is stretched to "fit" the scene, and this creates the distortion (might be due to The code in question is here: https://github.com/AR-js-org/AR.js/blob/3.4.5/aframe/src/location-based/arjs-webcam-texture.js#L6-L20 The proper fix would be to emulate a behavior like CSS's |
@kbs1 I think you can still contribute your modifications as a PR, we will review it, and if your code is not compatible stylistically or otherwise with AR.js, we will modify it. Even if it's not a full fix, if it partly solves some problems, it's still worth incorporating. |
@nickw1 here, I had a crack at it, works for me:
It still has problems though:
|
@Platform-Group thank you, that is esentially exactly the same workaround I have used. Outstanding issues are well written |
Bad news, I found an issue with the fix @kbs1 |
This also made me realise that it's using the 0.5x zoom camera for everything which is weird |
@Platform-Group I am using this code before initialising AR.js: if (window.navigator.mediaDevices && window.navigator.mediaDevices.getUserMedia)
window.navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode: {exact: 'environment'}}}).then(async stream => {
stream.getTracks().forEach(track => {
let trackSettings = track.getSettings();
let ios = () => {
if (typeof window === 'undefined' || typeof navigator === 'undefined') return false;
return /iPhone|iPad|iPod/i.test(navigator.userAgent || navigator.vendor || (window.opera && opera.toString() === '[object Opera]'));
};
if (ios()) {
this.deviceCameraInitialised = true;
} else if (trackSettings.width && trackSettings.height) {
console.log('webcam width ' + trackSettings.width);
console.log('webcam height ' + trackSettings.height);
console.log('webcam aspect ratio ' + (trackSettings.width / trackSettings.height));
window.ARJS_WEBCAM_ASPECT_RATIO = (trackSettings.width / trackSettings.height);
this.deviceCameraInitialised = true;
}
track.stop();
});
}).catch(e => console.log(e)); Then at AR.js side, I have the following code: var w = 1;
var h = 1;
if (window.ARJS_WEBCAM_ASPECT_RATIO) {
if (window.ARJS_WEBCAM_ASPECT_RATIO < 1) {
// portrait (width < height) => stretch width
w = 1 / window.ARJS_WEBCAM_ASPECT_RATIO * 1.1;
} else {
// landscape (width >= height) => stretch height
h = 1 * window.ARJS_WEBCAM_ASPECT_RATIO * 1.3;
}
}
this.geom=new I.PlaneBufferGeometry(w, h); This involves some magic constants, so the video feed is "as unstretched as possible". My primary goal was to make this work on a particular android device. I have also added window I am using Vue 3 in the project, so all aframe elements such as |
@kbs1 How did you get around this issue? I've changed over to vue 3 too but this particular bug is rather annoying. I'm thinking it doesn't really matter as I'll add a high z-level border around the video anyway but still. |
@Platform-Group I've just hidden all |
Working workaround I fixed the camera stretching by putting the whole arjs scene inside a separate html file and then using an iframe to embed that within another page. From there I can set the iframe width and height to match the camera's aspect ratio. Here's the function I used to calculate the needed iFrame width and height, it however doesn't take into account rotating devices or window size adjustments:
|
Bump! |
Is this getting fixed anytime soon? T_T |
@nickw1 I'm going to pay @DuncanPodmore to fix this properly and he is going to make a pull request. I need to know if you will be available to review it as soon as he makes the pull request, to know if the solution is proper. The pull request should be there sometime next month. |
Hello, |
Hello, I got stuck with this problem, because apart from the fact that the video image did not look as it should, the resolution is also horrible. I was looking for solutions everywhere, I even tried each of the solutions proposed here, but absolutely nothing worked. After trial and error, I arrived at the following solution. When using arjs, you must import some libraries, including 'aframe.min.js' and 'aframe-ar.js', as you can see in the screenshots I am attaching. Within the aframe-ar.js file, there is a fragment within all the obfuscated code where the video settings, "constraints", are established. There, there is only the following constraints "{ video: { facingMode: 'environment' } }", you must modify it in such a way that it is "{ video: { facingMode: 'environment', width: { ideal: 4096 }, height: { ideal: 2190 } }", which apart from increasing the horrible resolution that the camera has with the library, solves the error. As the code is obfuscated, you must find this fragment in VSCode using CTRL + F (search: "mediadevices.getusermedia"). Perhaps, in a future version of arjs it would be useful to add a little more customization (perhaps it already does and I'm talking about ignorant). Well, I have already had to modify the code directly from the library to solve other types of things that are not customizable. I will attach screenshots to clarify the situation: I hope my answer can help resolve the error, greetings! |
try to add aspect-ration in css, for make the height and width same to the resolution of the screen. |
@marcusx2 apologies for late reply on this. To be honest I don't really have much available time to spend on AR.js these days (other than quick checks of PRs) and haven't looked on here for a while; hope this is fixed though. Apologies for this but do please bear in mind the nature of open source projects is that contributors and maintainers are often doing it on a voluntary basis. |
The video camera feed is stretched on my android chrome (ARJS Geolocation). I took a photo with ARJS, and then with the camera app of my phone so you can see the difference
ARJS:
Camera app
The text was updated successfully, but these errors were encountered: