Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

PNP_Backend

Introduction

Ce projet contient un solveur pour le problème "Perspective-n-Points" (PnP). Il s'agit, étant donnée une photo, d'estimer les caractéristiques et la position de l'appareil de prise de vue.

Cette estimation se fait à partir de n points dont on connaît à la fois les coordonnées réelles (en 3 dimensions) et les coordonnées dans la photo (en 2 dimensions). L'estimation repose sur une modélisation du comportement des appareils photo basée sur la projection perspective. D'où le nom de "Perspective-n-Points".

Cette page indique comment installer, démarrer, et utiliser le solveur.

Pour visualiser un exemple d'utilisation ou en savoir plus sur les bases théoriques de ce projet, consultez notre wiki.

Implémentation

Le solveur en lui-même est implémenté en C++, avec l'aide de la librarie openCV.

Un serveur web vient compléter l'implémentation : il permet de rendre le solveur accessible depuis une machine distante, et facilite la communication avec le solveur grâce à l'utilisation du format JSON. Ce serveur est codé en nodeJS.

Enfin, l'application (solveur + serveur) est encapsulée dans un conteneurdocker. Cela permet de l'installer sur n'importe quelle type de machine (windows, mac, linux), avec pour seule dépendance docker lui-même.

Installation

  • Assurez-vous d'avoir docker installé sur votre machine. Sinon, consultez la page de téléchargement et installez la version adaptée à votre machine.
  • Téléchargez ce repo.
  • Optionnel : téléchargez l'application Postman pour effectuerp lus facilement des requêtes vers le serveur.

Usage

Démarrage du serveur

Pour démarrer le serveur, lancez la commande : docker-compose up.

Le premier démarrage peut être long (quelques minutes), car les dépendances sont téléchargées et compilées dans le conteneur. Cette étape ne sera pas exécutée aux démarrages suivants, les rendant bien plus rapides (de l'ordre de quelques secondes). Le serveur est prêt à recevoir des requêtes dès qu'il affiche le message "PnP solver running on port 3000. Waiting for requests...".

Pour vérifier votre configuration, entrez l'adresse "localhost:3000" dans un navigateur. Il devrait afficher la phrase "Hello from PnP solver".

Effectuer un calcul

Pour lancer un calcul, on envoie une requête POST sur la route localhost:3000/solve. Le corps de la requête doit être au format JSON, et respecter le format suivant :

{// tableau contenant les correspondances 2D-3D.// Doit contenir au minimum 6 correspondancesbindings: [{// coordonnées d'un point réelpoint3D: {x: Number,y: Number,z: Number},// coordonnées du point correspondant sur la photopoint2D: {x: Number,y: Number}}//...],// dimensions de la photo en pixelsimageDimensions: {width: Number,// largeur de l'image en pixelsheight: Number// hauteur de l'image en pixels}}

Attention, les coordonnées 2D doivent être comprises entre $- \frac{1}{2}$ et $\frac{1}{2}$ (le coin inférieur gauche de la photo ayant pour coordonnées $[- \frac{1}{2}, - \frac{1}{2}]$).

Interpréter le résultat

La réponse du serveur contient une estimation des paramètres de l'appareil ayant pris la photo. Elle contient également une estimation de l'erreur globale, et de l'erreur par point :

{camera: {// la matrice de la caméra, // indiquant le positionnement de l'appareil en 3dmatrix: [Number(16)],// angle de vue vertical (en degrés)vFOV: Number,// déviation horizontale du centre optique de l'appareilcx: Number,// déviation verticale du centre optique de l'appareilcy: Number,// largeur de la photo en pixelswidth: Number,// hauteur de la photo en pixelsheight: Number,},errorEstimation: {// tableau contenant les erreurs par pointbindingsError: [Number(n)],// estimation de l'erreur globaleglobalError: Number}}

Attention : le champ matrix correspond aux éléments de la matrice selon le format adopté par THREEjs (cf https://threejs.org/docs/#api/en/math/Matrix4)

L'appareil peut ainsi être simulé en THREEjs de la façon suivante :

functionsimulateCamera(camera){const{ matrix, cx, cy, vFOV, width, height }=camera;constfakeCamera3D=newTHREE.PerspectiveCamera(vFOV,width/height,1,1000);constm=newTHREE.Matrix4().set(...matrix).transpose();constposition=newTHREE.Vector3();constquaternion=newTHREE.Quaternion();constscale=newTHREE.Vector3();m.decompose(position,quaternion,scale);fakeCamera3D.position.copy(position);fakeCamera3D.quaternion.copy(quaternion);fakeCamera3D.setViewOffset(width,height,width*cx,height*cy,width,height);fakeCamera3D.updateMatrix();fakeCamera3D.updateMatrixWorld();fakeCamera3D.updateProjectionMatrix();}

Développement

Solveur

Le code du solveur se trouve dans le fichier src/solver/camCalibNode.cpp. En cas de mise à jour, il doit être recompilé. Pour cela, stoppez le conteneur docker (Ctrl-C) et relancez-en un nouveau avec l'option --build, pour forcer la compilation : docker-compose up --build

Serveur

Le code du serveur se trouve dans le dossier src/server. Il n'est pas nécessaire de relancer le conteneur docker lorsque vous mettez à jour ce code : la mise à jour est faite automatiquement.

About

Perspective recalage, PnP solver based on OpenCV cpp backend

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages