Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2023-05-11T16:25:04+02:00Les derniers messages parus sur le forum de Zeste de Savoir.Filtre de détection des contours sur une vidéo, message #2503932023-05-11T16:25:04+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16957/filtre-de-detection-des-contours-sur-une-video/?page=1#p250393<p>Double post // Un edit est pas pertinent cette fois.</p>
<p>Je me plongé dans la doc de openCV.js (chose que je voulais éviter car je la trouvait peu pratique) ce qui m’a mené à écrire une fonction très courte qui fonctionne sur une image :</p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span></div><pre><code class="hljs language-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">detectContour</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-comment">//Conversion d'une image en détection des contours</span>
<span class="hljs-comment">//Obtention de la matrice à partir de <img></span>
<span class="hljs-keyword">let</span> matriceCouleur= cv.imread(<span class="hljs-string">"imageSource"</span>); <span class="hljs-comment">// id d'une <img> dans html</span>
<span class="hljs-keyword">let</span> matriceGris = <span class="hljs-keyword">new</span> cv.Mat();
<span class="hljs-keyword">let</span> matriceEdge = <span class="hljs-keyword">new</span> cv.Mat();
cv.cvtColor(matriceCouleur, matriceGris, cv.COLOR_RGBA2GRAY);
cv.imshow(<span class="hljs-string">"canvasGris"</span>, matriceGris);
cv.Canny(matriceGris, matriceEdge, <span class="hljs-number">50</span>, <span class="hljs-number">100</span>, <span class="hljs-number">3</span>, <span class="hljs-literal">false</span>);
cv.imshow(<span class="hljs-string">"canvasEdge"</span>, matriceEdge);
}
</code></pre></div>
<p>Je n’ai pas gardé la page dans la doc qui m’a permis d’arriver ici. <img src="/static/smileys/svg/triste.svg" alt=":(" class="smiley"> Mais ça répond à mes 2 problèmes : C’est beaucoup plus lisible, et ça fonctionne.</p>
<p>Maintenant, il ne me reste plus qu’à adapter à la vidéo. <a href="https://docs.opencv.org/3.4/dd/d00/tutorial_js_video_display.html">La doc me donne encore ce qu’il faut :</a> </p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span></div><pre><code class="hljs language-js"><span class="hljs-keyword">let</span> video = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'videoInput'</span>);
<span class="hljs-keyword">let</span> src = <span class="hljs-keyword">new</span> cv.Mat(video.height, video.width, cv.CV_8UC4);
<span class="hljs-keyword">let</span> dst = <span class="hljs-keyword">new</span> cv.Mat(video.height, video.width, cv.CV_8UC4);
<span class="hljs-keyword">let</span> cap = <span class="hljs-keyword">new</span> cv.VideoCapture(video);
<span class="hljs-keyword">const</span> FPS = <span class="hljs-number">60</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processVideo</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">if</span> (!streaming) {
<span class="hljs-comment">// clean and stop.</span>
src.delete();
dst.delete();
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">let</span> begin = <span class="hljs-built_in">Date</span>.now();
<span class="hljs-comment">// start processing.</span>
cap.read(src);
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
cv.Canny(dst, dst, <span class="hljs-number">50</span>, <span class="hljs-number">100</span>, <span class="hljs-number">3</span>, <span class="hljs-literal">false</span>);
cv.imshow(<span class="hljs-string">'canvasOutput'</span>, dst);
<span class="hljs-comment">// schedule the next one.</span>
<span class="hljs-keyword">let</span> delay = <span class="hljs-number">1000</span>/FPS - (<span class="hljs-built_in">Date</span>.now() - begin);
<span class="hljs-built_in">setTimeout</span>(processVideo, delay);
} <span class="hljs-keyword">catch</span> (err) {
utils.printError(err);
}
};
<span class="hljs-comment">// schedule the first one.</span>
<span class="hljs-built_in">setTimeout</span>(processVideo, <span class="hljs-number">0</span>);
</code></pre></div>
<p>Ce qui fonctionne très bien dans le bac à sable de ladite page. Seulement, ça fonctionne avec le live de la caméra, et je veux travailler avec une vidéo qui est déjà enregistrée par la caméra et finie, donc j’ai essayé d’adapter un peu la chose :</p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span><span data-count="31"></span><span data-count="32"></span><span data-count="33"></span><span data-count="34"></span><span data-count="35"></span><span data-count="36"></span><span data-count="37"></span><span data-count="38"></span><span data-count="39"></span><span data-count="40"></span></div><pre><code class="hljs language-js"><span class="hljs-comment">/* Variables globales */</span>
<span class="hljs-comment">//...</span>
<span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, demarrerApp); <span class="hljs-comment">//On attend que tout soit chargé</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">demarrerApp</span>(<span class="hljs-params"></span>)</span>{ <span class="hljs-comment">// Fonction qui fait fonctionner la page, après avoir chargé tout html</span>
initialise_variables(); <span class="hljs-comment">// Initialisation des variables globales</span>
cameraShow(); <span class="hljs-comment">// Lancement de la webcam</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initialise_variables</span>(<span class="hljs-params"></span>)</span>{
<span class="hljs-comment">//...</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cameraShow</span>(<span class="hljs-params"></span>)
</span>{
<span class="hljs-comment">//...</span>
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">startRecording</span>(<span class="hljs-params"></span>) // <span class="hljs-title">Bouton</span> "<span class="hljs-title">d</span>é<span class="hljs-title">marrer</span> <span class="hljs-title">l</span>'<span class="hljs-title">enregistrement</span>"
</span>{
<span class="hljs-comment">//...</span>
}
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stopRecording</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// Bouton "arrêter l'enregistrement"</span>
<span class="hljs-comment">//...</span>
matSrc = <span class="hljs-keyword">new</span> cv.Mat(traitement.videoHeight, traitement.videoWidth, cv.CV_8UC4);
matDst = <span class="hljs-keyword">new</span> cv.Mat(traitement.videoHeight, traitement.videoWidth, cv.CV_8UC1);
captur = cv.VideoCapture(traitement); <span class="hljs-comment">//On capture la vidéo à traiter avec cette fonction, on passe en paramètre la vidéo voulue</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> captur); <span class="hljs-comment">// réponse : undefined</span>
detectContourVideo();
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">detectContourVideo</span>(<span class="hljs-params"></span>)</span>{
captur.read(matSrc); <span class="hljs-comment">// Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'read')</span>
<span class="hljs-comment">//...</span>
}
</code></pre></div>
<p>Je ne met pas l’intégralité du code : je sais que le reste fonctionne, donc pas la peine d’encombrer le topic.
J’ai ce problème très embêtant avec la première ligne de <code>detectContourVideo</code>, l’erreur est en commentaire. Effectivement, <code>capature</code> est de type <code>undefined</code>, ce qui ne doit apparemment être le cas. Si j’ai bien compris la doc, c’est censé être type <code>object</code> n’est-ce pas ? Qu’est-ce qui peut faire défaut ?</p>
<p>Mettre un await dans la ligne <code>captur = await cv.VideoCapture(traitement); </code> ne produit aucun changement de comportement. Mais j’ai pas l’impression que <code>VideoCapture</code> retourne une promesse, donc prévisible.</p>
<p>Faire une boucle avec une promesse justement pour attendre que <code>typeof captur == object</code> mène à une boucle infinie. Donc j’en déduit que le type de <code>captur</code> ne changera pas avec le temps.</p>
<p>Essayer avec une vidéo qui ne vient pas de la caméra mais qui est directement chargée dans la page en même temps que le reste ne change pas le problème.</p>
<p>Quant à l’initialisation de <code>captur</code> avec la variable <code>traitement</code>, c’est dans tout ce que je n’ai pas mis : traitement désigne une <code><video></code> html, qui est correctement identifiée par son ID, et qui a bien la vidéo enregistrée chargée, puisqu’elle se joue sans problème.</p>Filtre de détection des contours sur une vidéo, message #2503892023-05-11T10:41:43+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16957/filtre-de-detection-des-contours-sur-une-video/?page=1#p250389<p>Je viens d’essayé, avec <code>type = cv.CV_64FC4</code> (j’ai supposé que le 4 final faisait référence aux 4 canaux de couleur), mais je reste sur la même erreur.
Je suis en train de me demander si le problème ne vient pas de <code>cv.Canny</code> ? Est-ce que cette fonction ne renvoie pas justement une matrice remplie de 1 et de 0 (blanc et noir) au lieu d’une image ? Dans ce cas ça serait à moi de faire un traitement derrière…</p>Filtre de détection des contours sur une vidéo, message #2503862023-05-10T16:05:57+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/16957/filtre-de-detection-des-contours-sur-une-video/?page=1#p250386<p>L’erreur se situe plutôt dans la constitution de <code>cvOutput.data</code>, qui n’a pas la bonne taille. Tu es sûr qu’il ne manque pas des données ?</p>
<p>Tu as essayé de passer <code>rows</code>, <code>cols</code> et <code>type</code> en paramètres lorsque tu fais <code>const cvOutput = new cv.Mat();</code> (cf. <a href="https://docs.opencv.org/3.4/d3/d63/classcv_1_1Mat.html#a2ec3402f7d165ca34c7fd6e8498a62ca">doc OpenCV</a>) pour t’assurer que tes deux calques sont au même format ?</p>Filtre de détection des contours sur une vidéo, message #2503822023-05-10T10:10:37+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16957/filtre-de-detection-des-contours-sur-une-video/?page=1#p250382<p>Hii !</p>
<p>On est bien d’accord, une division par 4 à l’endroit où il attend la dimension de l’image, c’est bizarre. C’est pour ça que je dis que ma fonction est douteuse, car comme tu dis sois j’affiche une ligne sur 4, soit j’affiche seulement le premier quart, soit… pas moyen de le savoir. de plus j’avais jamais entendu parler d’un format d’image à une seule couche uniquement pour les trucs en noirs et blanc, mais c’est ce qui m’a corrigé l’erreur. <img src="/static/smileys/svg/triste.svg" alt=":(" class="smiley"></p>
<p>Donc c’est au niveau de ces lignes que j’avais l’erreur précisément (57 - 63) précisément :</p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span></div><pre><code class="hljs language-js"> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"canvas de sortie : %o * %o"</span>, cvOutput.rows, cvOutput.cols);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"%o bytes"</span>, cvOutput.data.length);
<span class="hljs-keyword">const</span> outputImageData = <span class="hljs-keyword">new</span> ImageData(
<span class="hljs-keyword">new</span> <span class="hljs-built_in">Uint8ClampedArray</span>(cvOutput.data),
cvOutput.cols,
cvOutput.rows
);
</code></pre></div>
<p>J’ai retiré le <code>/4</code>, l’erreur est "Uncaught (in promise) DOMException: Failed to construct 'ImageData’: The input data length is not equal to (4 <em> width </em> height)."
C’est pour ça qu’il y a les 2 <code>console.log</code> pour comparer les dimensions de <code>cvOutput</code> (hauteur et largeur) et le nombre de bytes : Il se trouve que j’ai <code>cvOutput.data.length = vOutput.rows*cvOutput.cols</code> sans le *4, d’où ma division sur <code>cvOutput.rows / 4</code>, comme ça la multiplication et la division se neutralisent.</p>Filtre de détection des contours sur une vidéo, message #2503722023-05-09T17:38:41+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/16957/filtre-de-detection-des-contours-sur-une-video/?page=1#p250372<p>Hello, </p>
<p>Je suis pas expert mais diviser par 4 me paraît dangereux quand l’API <a href="https://developer.mozilla.org/fr/docs/Web/API/ImageData"><code>ImageData</code></a> attend les dimensions de l’image à traiter et non un nombre de couleurs. De plus ta division est faite sur la hauteur : tu n’afficherais donc qu’une ligne sur 4 ?</p>
<p>Tu exposes peut-être uniquement du noir et blanc, mais l’affichage se fait bien en RGB, de même que le traitement : blanc étant du <code>RGB</code> (255, 255, 255), noir aussi (0, 0, 0). Le <code>A</code> de <code>RGBA</code> étant la couche alpha (transparence).</p>
<p>Quelle était l’erreur avant l’ajout de cette division ?</p>Filtre de détection des contours sur une vidéo, message #2503682023-05-09T15:01:31+02:00tsuruba/@tsurubahttps://zestedesavoir.com/forums/sujet/16957/filtre-de-detection-des-contours-sur-une-video/?page=1#p250368<p>bonjour !
J’essaie d’enregistrer une vidéo depuis ma webcam et de lui appliquer un filtre de détection des contours avec openCV.js. L’enregistrement fonctionne bien, il est fait avec WebRTC, il me donne une vidéo stockée dans un blob, et je peux l’afficher sans problème.
Voici le code de ma fonction de filtrage :</p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span><span data-count="31"></span><span data-count="32"></span><span data-count="33"></span><span data-count="34"></span><span data-count="35"></span><span data-count="36"></span><span data-count="37"></span><span data-count="38"></span><span data-count="39"></span><span data-count="40"></span><span data-count="41"></span><span data-count="42"></span><span data-count="43"></span><span data-count="44"></span><span data-count="45"></span><span data-count="46"></span><span data-count="47"></span><span data-count="48"></span><span data-count="49"></span><span data-count="50"></span><span data-count="51"></span><span data-count="52"></span><span data-count="53"></span><span data-count="54"></span><span data-count="55"></span><span data-count="56"></span><span data-count="57"></span><span data-count="58"></span><span data-count="59"></span><span data-count="60"></span><span data-count="61"></span><span data-count="62"></span><span data-count="63"></span><span data-count="64"></span><span data-count="65"></span><span data-count="66"></span><span data-count="67"></span><span data-count="68"></span><span data-count="69"></span><span data-count="70"></span><span data-count="71"></span><span data-count="72"></span><span data-count="73"></span><span data-count="74"></span><span data-count="75"></span><span data-count="76"></span><span data-count="77"></span><span data-count="78"></span><span data-count="79"></span><span data-count="80"></span><span data-count="81"></span><span data-count="82"></span></div><pre><code class="hljs language-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">detectContours</span>(<span class="hljs-params">inputBlob</span>) </span>{
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"a"</span>);
<span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(URL.createObjectURL(inputBlob));
<span class="hljs-keyword">const</span> blob = <span class="hljs-keyword">await</span> response.blob();
<span class="hljs-keyword">const</span> inputVideo = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"video"</span>);
inputVideo.src = URL.createObjectURL(blob);
<span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =></span> {
inputVideo.addEventListener(<span class="hljs-string">"loadedmetadata"</span>, <span class="hljs-function">() =></span> {
resolve();
});
inputVideo.load();
});
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"type de inputVideo : %o"</span>, <span class="hljs-keyword">typeof</span> inputVideo);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"vidéo d'entrée : %o * %o"</span>, inputVideo.height, inputVideo.width);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"b"</span>);
<span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =></span> {
inputVideo.addEventListener(<span class="hljs-string">"canplaythrough"</span>, <span class="hljs-function">() =></span> {
resolve();
});
inputVideo.load();
});
<span class="hljs-keyword">await</span> inputVideo.play();
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"c"</span>);
<span class="hljs-keyword">const</span> outputCanvas = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"canvas"</span>);
outputCanvas.width = inputVideo.videoWidth;
outputCanvas.height = inputVideo.videoHeight;
<span class="hljs-keyword">const</span> outputCtx = outputCanvas.getContext(<span class="hljs-string">"2d"</span>);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"d"</span>);
outputCtx.drawImage(
inputVideo,
<span class="hljs-number">0</span>,
<span class="hljs-number">0</span>,
outputCanvas.width,
outputCanvas.height
);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"e"</span>);
<span class="hljs-keyword">const</span> cvInput = cv.imread(outputCanvas);
<span class="hljs-keyword">const</span> cvOutput = <span class="hljs-keyword">new</span> cv.Mat();
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"f"</span>);
cv.Canny(cvInput, cvOutput, <span class="hljs-number">100</span>, <span class="hljs-number">200</span>);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"g"</span>);
<span class="hljs-built_in">console</span>.log(
<span class="hljs-string">"vidéo d'entrée : %o * %o"</span>,
inputVideo.videoHeight,
inputVideo.videoWidth
);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"canvas de sortie : %o * %o"</span>, cvOutput.rows, cvOutput.cols);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"%o bytes"</span>, cvOutput.data.length);
<span class="hljs-keyword">const</span> outputImageData = <span class="hljs-keyword">new</span> ImageData(
<span class="hljs-keyword">new</span> <span class="hljs-built_in">Uint8ClampedArray</span>(cvOutput.data),
cvOutput.cols,
cvOutput.rows / <span class="hljs-number">4</span>
);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"h"</span>);
<span class="hljs-keyword">const</span> outputCanvas2 = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"canvas"</span>);
outputCanvas2.width = outputImageData.width;
outputCanvas2.height = outputImageData.height;
<span class="hljs-keyword">const</span> outputCtx2 = outputCanvas2.getContext(<span class="hljs-string">"2d"</span>);
outputCtx2.putImageData(outputImageData, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"i"</span>);
<span class="hljs-keyword">const</span> outputBlob = <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =></span>
outputCanvas2.toBlob(resolve, <span class="hljs-string">"image/png"</span>)
);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"j"</span>);
URLvideoEdge = URL.createObjectURL(outputBlob);
blobVideoEdge = outputBlob;
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"k"</span>);
}
</code></pre></div>
<p>Voici le code de ma fonction appelée quand j’appuie sur mon bouton pour arrêter d’enregistrer : </p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span></div><pre><code class="hljs language-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stopRecording</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"1"</span>);
<span class="hljs-comment">//Recording the video</span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> track <span class="hljs-keyword">of</span> stream.getTracks()) {
track.stop(); <span class="hljs-comment">//when this event is triggered, function called display the video without any issue </span>
}
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"2"</span>);
<span class="hljs-comment">// verifying blobVideoCouleur actually is an object</span>
<span class="hljs-keyword">while</span> (<span class="hljs-keyword">typeof</span> blobVideoCouleur !== <span class="hljs-string">"object"</span>) {
<span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =></span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">100</span>)); <span class="hljs-comment">// Pause 100ms</span>
}
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"3"</span>);
<span class="hljs-comment">//Applying edge detection filter</span>
<span class="hljs-keyword">await</span> detectContours(blobVideoCouleur);
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"4"</span>);
<span class="hljs-comment">//Displaying filtered video </span>
playBack.src = URLvideoEdge;
playBack.autoplay = <span class="hljs-literal">true</span>;
<span class="hljs-built_in">console</span>.trace(<span class="hljs-string">"5"</span>);
}
</code></pre></div>
<p><code>playBack</code> est une variable globale définie comme l’élément html <code><vidéo></code> où je joue la vidéo enregistrée. Ca fonctionne très bien pour la vidéo "normale". Voici le code qui la définie, cette fonction est appelée quand j’appuie sur mon bouton d’arrêt d’enregistrement :</p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span></div><pre><code class="hljs language-js"> recorder.onstop = <span class="hljs-function">() =></span> { <span class="hljs-comment">// Event triggered when I stop the recorder </span>
<span class="hljs-keyword">const</span> blob = <span class="hljs-keyword">new</span> Blob(chunks, { <span class="hljs-comment">//</span>
<span class="hljs-attr">type</span>: <span class="hljs-string">'video/webm'</span> <span class="hljs-comment">// Et il le fait en webm</span>
})
chunks = [];
URLvideoCouleur = URL.createObjectURL(blob);
playBack = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"playBack"</span>);
playBack.src = URLvideoCouleur;
playBack.controls = <span class="hljs-literal">true</span>;
blobVideoCouleur = blob;
}
</code></pre></div>
<p>J’ai eu pas mal de soucis avec cette fonction, c’est pourquoi il y a plein de <code>console.trace</code> un peu partout, pour suivre l’exécution étape par étape. Ca m’a mené à corriger un dernier bug. La "solution" que j’ai trouvée était une division par 4 dans cette section de la fonction <code>detectContours</code> : </p>
<div class="hljs-code-div hljs-code-js"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span></div><pre><code class="hljs language-js"> <span class="hljs-keyword">const</span> outputImageData = <span class="hljs-keyword">new</span> ImageData(
<span class="hljs-keyword">new</span> <span class="hljs-built_in">Uint8ClampedArray</span>(cvOutput.data),
cvOutput.cols,
cvOutput.rows / <span class="hljs-number">4</span>
);
</code></pre></div>
<p>J’ai fait ça car apparemment ImageData a besoin que la taille totale des données soit largeur_frame*hauteur_frame*4, à cause des 4 couleurs (RGBA), mais moi j’ai une seule couche, en noir et blanc, après la détection des contours, donc je divise par 4 pour qu’il arrête de râler…
A partir de là, j’ai plus aucune erreur dans la console, ou interruption ou autre, pour me guider, mais malheureusement le comportement n’est pas celui attendu. <code>playBack</code> ne joue pas ma vidéo filtrée à la place de la vidéo "normale". Il me donne juste un carré noir avec les contrôles du player, mais inutiles car la vidéo a une durée de 0s.
<img src="/media/galleries/17687/3c6b8d46-f8d0-48de-a2aa-ac2b25e64bb0.png" alt="Screenshot_7.png"><img alt="ce qui s'affiche au lieu de ma vidéo filtrée"></p>
<p>J’ai plus la console pour avance je disais, et j’ai plus d’idée farfelue comme la division par 4. Avez-vous une suggestion de ce qui peut clocher ? Aussi, pour moi cette division par 4 est un signe que ma fonction detectContours est plus que douteuse, et en la regardant ça m’a l’air d’une grosse usine à gaz. Il n’y a pas une méthode plus simple pour appliquer un filtre de détection des contours en js ? Merci par avance !</p>Reconnaissance de chiffres manuscrits, message #2293002020-12-16T00:17:05+01:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p229300<p>Bonjour,</p>
<p>La bêta du contenu « Reconnaissance de chiffres manuscrits » a été désactivée.</p>Reconnaissance de chiffres manuscrits, message #2252982020-08-26T23:34:26+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p225298<p>Bonjour les agrumes !</p>
<p>La bêta a été mise à jour et décante sa pulpe
à l’adresse suivante :</p>
<div class="align-center"><p> <a href="https://zestedesavoir.com/contenus/beta/3655/reconnaissance-de-chiffres-manuscrits/">Reconnaissance de chiffres manuscrits</a> </p></div>
<p>Merci d’avance pour vos commentaires.</p>Reconnaissance de chiffres manuscrits, message #2250982020-08-19T07:22:27+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p225098<p>Bonjour les agrumes !</p>
<p>La bêta a été mise à jour et décante sa pulpe
à l’adresse suivante :</p>
<div class="align-center"><p> <a href="https://zestedesavoir.com/contenus/beta/3655/reconnaissance-de-chiffres-manuscrits/">Reconnaissance de chiffres manuscrits</a> </p></div>
<p>Merci d’avance pour vos commentaires.</p>Reconnaissance de chiffres manuscrits, message #2250942020-08-19T00:33:51+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p225094<p>Bonjour les agrumes !</p>
<p>La bêta a été mise à jour et décante sa pulpe
à l’adresse suivante :</p>
<div class="align-center"><p> <a href="https://zestedesavoir.com/contenus/beta/3655/reconnaissance-de-chiffres-manuscrits/">Reconnaissance de chiffres manuscrits</a> </p></div>
<p>Merci d’avance pour vos commentaires.</p>Reconnaissance de chiffres manuscrits, message #2250662020-08-17T23:06:40+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p225066<p>Bonjour les agrumes !</p>
<p>La bêta a été mise à jour et décante sa pulpe
à l’adresse suivante :</p>
<div class="align-center"><p> <a href="https://zestedesavoir.com/contenus/beta/3655/reconnaissance-de-chiffres-manuscrits/">Reconnaissance de chiffres manuscrits</a> </p></div>
<p>Merci d’avance pour vos commentaires.</p>Reconnaissance de chiffres manuscrits, message #2250012020-08-16T02:09:38+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p225001<p>Salut, merci pour ton retour,</p>
<figure><blockquote>
<ul>
<li>le titre de la section <em>Préparation post traitement</em>, ce ne serait pas plutôt <em>Préparation <strong>pré</strong>-traitement</em> ? Puisque que c’est quelque chose qui est fait avant le traitement…</li>
<li>sur l’image qui sert à illustrer <em>l’algorithme dans la boucle</em>, pourquoi est-ce que pour deux chiffres, c’est rouge et pas vert ?</li>
<li>dernier petit détail qui me chiffonne (mais là ça n’est que mon avis personnel), tu utilises l’expression <em>computer vision</em>, mais puisque tout l’article est en français, autant dire <em>vision par ordinateur</em></li>
</ul>
<p>À part ces détails, l’article me semble bien. Beau boulot ! <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"></p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p224997">philippemilink</a></figcaption></figure>
<p>Pour la première remarque, effectivement je ne sais pas où j’avais la tête, c’est bien pré traitement que je voulais dire <img src="/static/smileys/svg/heureux.svg" alt=":D" class="smiley"> </p>
<p>Pour la deuxième, j’ai mis en rouge parce que la détection est mauvaise, c’est pour montrer les bonnes et mauvaises détections.</p>
<p>Pour la troisième, j’y réfléchis encore <img src="/static/smileys/svg/clin.svg" alt=";)" class="smiley"> </p>Reconnaissance de chiffres manuscrits, message #2249972020-08-15T23:16:28+02:00philippemilink/@philippemilinkhttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p224997<p>Salut !</p>
<p>Tout d’abord, merci de prendre le temps d’écrire un article.</p>
<p>J’ai parcouru rapidement, et j’ai quelques remarques / questions:</p>
<ul>
<li>le titre de la section <em>Préparation post traitement</em>, ce ne serait pas plutôt <em>Préparation <strong>pré</strong>-traitement</em> ? Puisque que c’est quelque chose qui est fait avant le traitement…</li>
<li>sur l’image qui sert à illustrer <em>l’algorithme dans la boucle</em>, pourquoi est-ce que pour deux chiffres, c’est rouge et pas vert ?</li>
<li>dernier petit détail qui me chiffonne (mais là ça n’est que mon avis personnel), tu utilises l’expression <em>computer vision</em>, mais puisque tout l’article est en français, autant dire <em>vision par ordinateur</em></li>
</ul>
<p>À part ces détails, l’article me semble bien. Beau boulot ! <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"></p>Reconnaissance de chiffres manuscrits, message #2249962020-08-15T20:49:55+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p224996<p>Bonjour les agrumes !</p>
<p>La bêta a été mise à jour et décante sa pulpe
à l’adresse suivante :</p>
<div class="align-center"><p> <a href="https://zestedesavoir.com/contenus/beta/3655/reconnaissance-de-chiffres-manuscrits/">Reconnaissance de chiffres manuscrits</a> </p></div>
<p>Merci d’avance pour vos commentaires.</p>Reconnaissance de chiffres manuscrits, message #2249952020-08-15T19:39:04+02:00thibsc/@thibschttps://zestedesavoir.com/forums/sujet/14447/reconnaissance-de-chiffres-manuscrits/?page=1#p224995<p>Tout le monde se secoue ! <img src="/static/smileys/svg/heureux.svg" alt=":D" class="smiley"></p>
<p>J’ai commencé (mercredi 12 août 2020 à 08h23) la rédaction d’un article au doux nom
de « Reconnaissance manuscrite de chiffre » et j’ai pour objectif de proposer en validation
un texte aux petits oignons. Je fais donc appel à votre bonté sans
limites pour dénicher le moindre pépin, que ce soit à propos
du fond ou de la forme. Vous pourrez consulter la bêta à votre guise à
l’adresse suivante :</p>
<div class="align-center"><p> <a href="https://zestedesavoir.com/contenus/beta/3655/reconnaissance-manuscrite-de-chiffre-1/">À présent, c’est à vous !</a> </p></div>
<p>Merci !</p>[opencv][raspicam] Détection de trou , message #2044582019-06-13T08:55:47+02:00Golden Panda/@Golden%20Pandahttps://zestedesavoir.com/forums/sujet/12597/opencvraspicam-detection-de-trou/?page=1#p204458<p>Merci pour ta réponse Jacen, je vais étudier et essayer tout ça <img src="/static/smileys/smile.png" alt=":)" class="smiley"></p>[opencv][raspicam] Détection de trou , message #2044442019-06-12T18:16:01+02:00Jacen/@Jacenhttps://zestedesavoir.com/forums/sujet/12597/opencvraspicam-detection-de-trou/?page=1#p204444<p>Bonjour,</p>
<p>Oui c’est possible, à ma connaissance la raspicam est un device V4L2 tout à fait standard, il y a une classe <a href="https://docs.opencv.org/3.1.0/d8/dfe/classcv_1_1VideoCapture.html">VideoCapture</a> dans OpenCV, des choses simples comme <a href="https://stackoverflow.com/questions/39836565/read-from-linux-web-camera-using-opencv">cet exemple sur SO</a> devraient marcher.</p>[opencv][raspicam] Détection de trou , message #2043942019-06-11T15:43:41+02:00Golden Panda/@Golden%20Pandahttps://zestedesavoir.com/forums/sujet/12597/opencvraspicam-detection-de-trou/?page=1#p204394<p>Bonjour à tous et à toutes,</p>
<p>Je voulais savoir s’il était possible de faire du traitement d’image en utilisant open cv et la camera de la raspbery pi ? </p>
<p>L’objectif serait d’effectuer un traitement en temps réel sur le flux vidéo venant de la caméra.
Je parviens à faire mon traitement sur une simple image ou une vidéo (.avi) mais je ne trouve pas le moyen d’effectuer ce traitement sur le flux directement, est ce possible ? Si ouii, comment ca marche ?</p>
<p>Merci d’avance pour vos conseils <img src="/static/smileys/smile.png" alt=":)" class="smiley"> </p>Détection de cercle sur une droite avec OpenCV et Python, message #1435042017-03-06T18:17:58+01:00dewey/@deweyhttps://zestedesavoir.com/forums/sujet/8151/detection-de-cercle-sur-une-droite-avec-opencv-et-python/?page=1#p143504<p>Oui j’ai bien compris l’explication.</p>
<p>"La stratégie, ici, ce serait donc d’essayer de créer des droites à partir de deux point parmis l’entièreté, puis de trouver parmis les autres points ceux qui correspondent. Évidement, il y a un tout petit peut d’optimisation à faire, parce que dans l’absolu, il ne faut pas tester TOUTES les droites formées par chaque paire de deux points, mais je te laisse réfléchir "</p>
<p>Apres pour la partie du dessus, faut que je relise mieux</p>Détection de cercle sur une droite avec OpenCV et Python, message #1435012017-03-06T17:12:59+01:00pierre_24/@pierre_24https://zestedesavoir.com/forums/sujet/8151/detection-de-cercle-sur-une-droite-avec-opencv-et-python/?page=1#p143501<figure>
<blockquote>
<p>Vue l’image qu’il a donnée en exemple, je doute que ce soit suffisant : il y a plein de cercles parasites qui forment des alignements. Je ne pense pas qu’une méthode qui consiste à dire « on n’a qu’à regarder la régularité des distances » soit très robuste non plus.</p>
</blockquote>
<figcaption><a href="https://zestedesavoir.com/forums/sujet/8151/detection-de-cercle-sur-une-droite-avec-opencv-et-python/?page=1#p143489">Eusèbe</a></figcaption>
</figure>
<p>Toutafé d’accord, et OpenCV n’est absolument pas mon rayon. Après, peut de chances qu’il détecte 6 cercles alignés au hasard <img alt=";)" src="/static/smileys/clin.png"> (même si ça ne tue jamais d’améliorer la fonction pour éviter les faux-positifs).</p>
<blockquote>
<p>@pierre_24 A chaque fois que je regarde sur internet, je tombe sur des sujets avec pas mal de maths, j’ai regardé tracé une droite à partir d’un nuage de points <img alt=":o" src="/static/smileys/huh.png"> j’ai pris peur.</p>
</blockquote>
<p>… Tu peux bien <img alt="^^" src="/static/smileys/hihi.png"> … Ce qui ne me dit pas si tu as compris mon explication ou pas, note !</p>Détection de cercle sur une droite avec OpenCV et Python, message #1434952017-03-06T16:28:14+01:00dewey/@deweyhttps://zestedesavoir.com/forums/sujet/8151/detection-de-cercle-sur-une-droite-avec-opencv-et-python/?page=1#p143495<p>J’ai pensé à tracer des traits à partir de tout les points que je trouve, après je regarde si ma droite coupe bien 6 points. Mais ca me semble compliqué, doit avoir plus simple je pense, j’ai regardé rapidement faire des droits mais je n’arrive pas totalement à ce que je veux.</p>
<p>@pierre_24 A chaque fois que je regarde sur internet, je tombe sur des sujets avec pas mal de maths, j’ai regardé tracé une droite à partir d’un nuage de points <img alt=":o" src="/static/smileys/huh.png"> j’ai pris peur.</p>
<p>@Eusèbe Je vais regarder si je peut améliorer mes params, je m’amuse à faire un cercle avec ma main, il le détecte bien, je vais regarder plus en détail la function HoughCircles.</p>
<p>Quand je vois qu’il détecte le cable… il vois trois points du coup pour lui c’est un cercle…</p>