<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Experimentos &#8211; Visão Computacional</title>
	<atom:link href="https://visaocomputacional.com.br/category/experimentos/feed/" rel="self" type="application/rss+xml" />
	<link>https://visaocomputacional.com.br</link>
	<description>Tecnologias, teorias e testes.</description>
	<lastBuildDate>Thu, 28 Aug 2025 18:27:06 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.8.1</generator>

<image>
	<url>https://visaocomputacional.com.br/wp-content/uploads/2021/12/cropped-logo-150x150-1-32x32.png</url>
	<title>Experimentos &#8211; Visão Computacional</title>
	<link>https://visaocomputacional.com.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Programando Esqueletização e Extração de Fronteiras Morfológica com Javascript</title>
		<link>https://visaocomputacional.com.br/programando-esqueletizacao-e-extracao-de-fronteiras-morfologica-com-javascript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=programando-esqueletizacao-e-extracao-de-fronteiras-morfologica-com-javascript</link>
		
		<dc:creator><![CDATA[Piemontez]]></dc:creator>
		<pubDate>Mon, 19 Jun 2023 17:50:53 +0000</pubDate>
				<category><![CDATA[Experimentos]]></category>
		<category><![CDATA[Esqueletização]]></category>
		<category><![CDATA[Fronteiras]]></category>
		<category><![CDATA[Morfologia]]></category>
		<guid isPermaLink="false">https://visaocomputacional.com.br/?p=4669</guid>

					<description><![CDATA[<p>Este artigo demonstra como programar a extração de fronteiras internas e externas, e esqueletização de imagens binárias apresentadas em Morfologia Matemática – Esqueletização de imagem e Morfologia Matemática – Extração de Fronteiras / Detecção de Bordas. A programação foi realizada na linguagem javascript, utilizando a biblioteca opencv.js e as imagens produzidas com a IDE OpenCV-Flow.</p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/programando-esqueletizacao-e-extracao-de-fronteiras-morfologica-com-javascript/">Programando Esqueletização e Extração de Fronteiras Morfológica com Javascript</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="ratio ratio-16x9"><iframe loading="lazy" title="Programando Extração de Fronteiras Morfológica com Javascript." width="800" height="450" src="https://www.youtube.com/embed/FLfueaozdHo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></div>
</div></figure>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="ratio ratio-16x9"><iframe loading="lazy" title="Programando Esqueletização Morfológica com Javascript." width="800" height="450" src="https://www.youtube.com/embed/tMaCqGAM8uI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></div>
</div></figure>



<p>Este artigo demonstra como programar a extração de fronteiras internas e externas, e esqueletização de imagens binárias apresentadas em <a href="https://visaocomputacional.com.br/morfologia-matematica-esqueletizacao-de-imagem/">Morfologia Matemática – Esqueletização de imagem</a> e <a href="https://visaocomputacional.com.br/morfologia-matematica-extracao-de-fronteiras-deteccao-de-bordas/">Morfologia Matemática – Extração de Fronteiras / Detecção de Bordas</a>. A programação foi realizada na linguagem javascript, utilizando a biblioteca&nbsp;<a href="https://docs.opencv.org/4.x/d5/d10/tutorial_js_root.html">opencv.js</a>&nbsp;e as imagens produzidas com a IDE&nbsp;<a href="https://opencvflow.org/pt">OpenCV-Flow</a>.</p>



<h3>OpenCV</h3>



<p>A biblioteca opencv.js disponibiliza diversas funcionalidade prontas para o processamento de imagens e visão computacional. Para utilizá-la, basta incluí-la no script da página&nbsp;conforme descrito em&nbsp;<a href="https://docs.opencv.org/4.x/d0/d84/tutorial_js_usage.html">Using OpenCV.js</a>.</p>



<h2>Extração de Fronteira Interna</h2>



<p>A fronteira interna, como apresentado no outro post citado,&nbsp;é o contorno da imagem binarizada. O cálculo consiste em subtrair da imagem o resultado da erosão da própria imagem, por um elemento estruturante.</p>



<p>A primeira etapa que iremos realizar é criar o núcleo de operação com o formato de quadrado. O elemento estruturante deve ser uma imagem binarizada (preto e branco). Como não temos imagens binárias no OpenCV, criaremos uma imagem em tons de cinza.</p>



<p>Na função nucleoFormatoCruz abaixo, é criada uma matriz de tamanho 3×3, com um canal de cor do tipo uint8, com valores entre 0 e 255:</p>



<pre class="wp-block-preformatted">function nucleoFormatoCruz() {
  return new cv.matFromArray(3, 3, cv.CV_8UC1, [
    0, 1, 0,
    1, 1, 1,
    0, 1, 0
  ]);
}</pre>



<p>Com o núcleo criado, basta realiza a erosão da imagem binarizada e depois subtrair a imagem original pelo resultado desta operação. A função abaixo realiza este processo com a biblioteca OpenCV.js:</p>



<pre class="wp-block-preformatted">function extrairFronteiraInterna(imagem, imagemSaida, nucleo) {
  let imgTemporaria = new cv.Mat(imagem.rows, imagem.cols, imagem.type(), new cv.Scalar(0));

  // Realiza a erosão com biblioteca opencv.
  cv.erode(imagem, imgTemporaria, nucleo);
  
  // Realiza a subtração da imagem pela mesma erodida
  cv.subtract(imagem, imgTemporaria, imagemSaida);
}</pre>



<p>A primeira operação realizada com a função cv.erode, recebe uma imagem de entrada, uma imagem que receberá o resultado da operação de erosão e o núcleo para a operação. </p>



<p>A segunda e última operação realizada é a subtração com a função cv.subtract, que recebe uma imagem de entrada, uma segunda imagem com os valores das subtrações a serem realizadas, e por fim uma imagem de saída que receberá o resultado desta operação.</p>



<p>É possível simplificar esta função conforme abaixo:</p>



<pre class="wp-block-preformatted">function extrairFronteiraInterna(imagem, imagemSaida, nucleo) {
  // Realiza a erosão com biblioteca opencv.
  cv.erode(imagem, imagemSaida, nucleo);
  
  // Realiza a subtração da imagem pela mesma erodida
  cv.subtract(imagem, imagemSaida, imagemSaida);
}</pre>



<p>Note que, foi informada a variável imagemSaida como segundo e terceiro parâmetro, da segunda operação. Foi realizado isto, pois a variável imagemSaida contém o resultado da erosão, que é preciso para subtrair os valores e para não precisarmos criar uma terceira variável, simplificando a função. Não há problemas em utilizar a mesma variável na operação cv.subtract, pois ela é uma operação não convolucional, que realiza apenas operações que utilizam um único pixel de cada vez.</p>



<h2>Extração de Fronteiras Externas</h2>



<p>A fronteira externa, na imagem binarizada, cria uma camada como uma vestimenta que cobre toda a imagem. O cálculo consiste em dilatar a imagem por um elemento estruturante e subtrair pela imagem original. De certa forma, o inverso da operação para extração da fronteira interna.</p>



<p>A primeira etapa para realizar esta operação, também consiste em criar um núcleo para a operação de dilatação. Utilizaremos o mesmo da seção anterior. Com o núcleo criado basta realizar as operações conforme a função abaixo:</p>



<pre class="wp-block-preformatted">function extrairFronteiraExterna(imagem, imagemSaida, nucleo) {
  let imgTemporaria = new cv.Mat(imagem.rows, imagem.cols, imagem.type(), new cv.Scalar(0));

  // Realiza a erosão com biblioteca opencv.
  cv.dilate(imagem, imgTemporaria, nucleo);
  
  // Realiza a subtração da imagem pela mesma erodida
  cv.subtract(imgTemporaria, imagem, imagemSaida);
}</pre>



<p>Observe que para extração da fronteira externa, foi trocada a operação de erosão pela dilatação com a função cv.dilate, e alterada a ordem dos parâmetros durante a subtração com a função cv.subtract.</p>



<h2>Esqueletização de Imagem Binarizada </h2>



<p>Pare realizar a esqueletização com morfologia, conforme apresentado em <a href="https://visaocomputacional.com.br/morfologia-matematica-esqueletizacao-de-imagem/">Morfologia Matemática – Esqueletização de imagem</a>, basta realizar quatro operações, dentro de um laço de repetição, e realizar a inicialização de algumas variáveis para este processamento.</p>



<p>Observe na função abaixo, que nas primeiras linhas, antes do laço while, foram inicializados variáveis para o processamento da esqueletização, criando uma imagem temporária chamada clone, com as mesmas informações da imagem original e um núcleo que é utilizado para reduzir a estrutura da imagem original.</p>



<pre class="wp-block-preformatted">function extrairEsqueleto(imagem, imagemSaida) {
  // Inicializa as matrizes
  const erosao = new cv.Mat(imagem.rows, imagem.cols, src.type());
  const abertura = new cv.Mat(imagem.rows, imagem.cols, src.type());
  const subtracao = new cv.Mat(imagem.rows, imagem.cols, src.type());

  // Clona a imagem original
  let clone = imagem.clone();
  // Cria o núcleo(3x3) em formato de cruz
  const nucleo = cv.getStructuringElement(cv.MORPH_CROSS, new cv.Size(3, 3), new cv.Point(-1, -1));

<strong><strong>  while (cv.countNonZero(clone) !== 0) {
    cv.erode(clone, erosao, nucleo); 
    cv.dilate(erosao, abertura, nucleo);

    cv.subtract(clone, abertura, subtracao);

    cv.bitwise_or(imagemSaida, subtracao, imagemSaida);

    clone = </strong>erosao<strong>.clone();</strong>
    GCStore.add(<strong>clone</strong>);<strong>
  }
</strong></strong>
  // Deleta as variáveis temporárias
  delete erosao;
  delete abertura;
  delete subtracao;
  delete clone;
}</pre>



<p>Após a inicialização das variáveis, é realizado um laço que verifica se a imagem clone está vazia (só com valores zero), caso não esteja, o laço fica realizando as seguintes operações:</p>



<ul id="block-7706de29-1bfa-4502-a250-c1d85e071358"><li>As duas primeiras operações realizadas, dentro do laço, consistem em realizar uma erosão, seguida de uma dilatação.<ul><li>Como resultado é criado uma abertura da imagem, pelo elemento estruturante em formato cruz;</li><li>Esta abertura remove os pontos das extremidades da imagem clone.</li></ul></li><li>A terceiraça operação, realiza a subtração da imagem clone pela imagem de abertura.<ul><li>Como resultado, na matriz subtração, estão apenas os pontos com as extremidades da imagem clone.</li></ul></li><li>Por fim, os pontos da extremidades, são salvos na imagem de saída.</li></ul>



<p>O processo é repetido até que a imagem clone seja zerada, durante o processo de erosão.</p>



<p>Note que, em cada laço realizado, é coletado os pontos da extremidades da imagem clone e salvo na imagem de saída, e em cada laço a imagem é diminuída de tamanho. Este processo resulta na criação do esqueleto da imagem.</p>



<h2>Cuidados</h2>



<p>Caso você vá utilizar a biblioteca opencv, saiba que as funções morfológicas dela também realizam morfologia matemática em imagens em tons de cinza e coloridas, que possuem resultados muito diferentes das operações morfológicas em imagens binarizadas. Lembre-se de converter a imagem em preto e branco, para realizar os experimentos aqui apresentados.</p>



<h2>Considerações</h2>



<p>As funções programadas neste post possuem caráter de estudo, afim de entender as etapas e os processos morfológicos, pois não foram pensadas em questões como desempenho nestes exemplos. Caso você precise utilizar este tipo de operação, é recomendado que utilize uma biblioteca preparada para isso, como o OpenCV ou similar.</p>



<p>O código aqui apresentado esta disponível no link abaixo:</p>



<p>Source code:&nbsp;<a href="https://github.com/visaocomputacionalexemplos/morfologia/blob/main/javascript/base/morfologia.html">https://github.com/visaocomputacionalexemplos/morfologia/blob/main/javascript/base/esqueletizacao.html</a></p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/programando-esqueletizacao-e-extracao-de-fronteiras-morfologica-com-javascript/">Programando Esqueletização e Extração de Fronteiras Morfológica com Javascript</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Programando Erosão, Dilatação, Abertura e Fechamento Morfológica com Javascript.</title>
		<link>https://visaocomputacional.com.br/programando-erosao-dilatacao-abertura-e-fechamento-morfologica-com-javascript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=programando-erosao-dilatacao-abertura-e-fechamento-morfologica-com-javascript</link>
		
		<dc:creator><![CDATA[Piemontez]]></dc:creator>
		<pubDate>Thu, 09 Feb 2023 23:03:49 +0000</pubDate>
				<category><![CDATA[Experimentos]]></category>
		<category><![CDATA[Abertura]]></category>
		<category><![CDATA[Dilatação]]></category>
		<category><![CDATA[Dilate]]></category>
		<category><![CDATA[Erode]]></category>
		<category><![CDATA[Erosão]]></category>
		<category><![CDATA[Fechamento]]></category>
		<category><![CDATA[Morfologia]]></category>
		<guid isPermaLink="false">https://visaocomputacional.com.br/?p=3846</guid>

					<description><![CDATA[<p>Este artigo trata de como programar as operações morfológicas binárias apresentadas no post Morfologia Matemática para Processamento de Imagens. A programação foi realizada na linguagem javascript, utilizando a biblioteca opencv.js e as imagens produzidas com a IDE OpenCV-Flow. OpenCV A biblioteca opencv.js disponibiliza diversas funcionalidade prontas para o processamento de imagens e visão computacional. Para [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/programando-erosao-dilatacao-abertura-e-fechamento-morfologica-com-javascript/">Programando Erosão, Dilatação, Abertura e Fechamento Morfológica com Javascript.</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="ratio ratio-16x9"><iframe loading="lazy" title="Programando Erosão e Dilatação Morfológica com Javascript." width="800" height="450" src="https://www.youtube.com/embed/FTHAoLFlWuI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></div>
</div></figure>



<p>Este artigo trata de como programar as operações morfológicas binárias apresentadas no post <a href="https://visaocomputacional.com.br/morfologia-matematica-para-processamento-de-imagens/">Morfologia Matemática para Processamento de Imagens</a>. A programação foi realizada na linguagem javascript, utilizando a biblioteca <a href="https://docs.opencv.org/4.x/d5/d10/tutorial_js_root.html">opencv.js</a> e as imagens produzidas com a IDE <a href="https://opencvflow.org/pt">OpenCV-Flow</a>.</p>



<h3>OpenCV</h3>



<p>A biblioteca opencv.js disponibiliza diversas funcionalidade prontas para o processamento de imagens e visão computacional. Para utilizá-la, basta incluí-la no script da página <span class="has-inline-color has-black-color">conforme descrito em <a href="https://docs.opencv.org/4.x/d0/d84/tutorial_js_usage.html">Using OpenCV.js</a></span>.</p>



<p>Utilizaremos a classe <a href="https://docs.opencv.org/4.x/de/d06/tutorial_js_basic_ops.html">Mat do OpenCV</a> para realizar a manipulação da imagem, com esta classe conseguimos construir de forma fácil imagens (coloridas e binárias) e manipular seus pixels. </p>



<h2>Erosão</h2>



<p>A erosão como apresentado no outro post citado, consiste em testar se o elemento estruturante (núcleo) se encaixa na imagem de origem, gerando uma nova imagem de destino, onde cada teste realizado com sucesso, é identificado na imagem de destino com o valor 1 e identificado com o valor 0 caso a estrutura não tenha sido localizada.&nbsp;</p>



<p>A primeira etapa que iremos realizar é criar o núcleo de operação com o formato de quadrado. O elemento estruturante deve ser uma imagem binárizada (preto e branco), como não temos imagens binárias no OpenCV, criaremos uma imagem em tons de cinza.</p>



<p>Na função nucleoFormatoCruz, abaixo, é criada uma matriz de tamanho 3&#215;3, com um canal de cor do tipo uint8, com valores entre 0 e 255: </p>



<pre class="wp-block-preformatted">function nucleoFormatoCruz() {
  return new cv.matFromArray(3, 3, cv.CV_8UC1, [
    1, 1, 1,
    1, 1, 1,
    1, 1, 1
  ]);
}</pre>



<p>Além do núcleo das operações, vamos precisar da posição central das operações, sendo que no OpenCV é utilizada a classe cv.Point para indicar posições específicas, com o objetivo de seguir o padrão, nosso código também ira utilizá-la. Para inicializar a classe, é preciso apenas informar as posições das coordenadas x e y, conforme abaixo:</p>



<pre class="wp-block-preformatted">const centro = new cv.Point(1, 1);</pre>



<p>Agora que temos nosso núcleo e sua posição, nossa função de erosão foi programada com as seguintes etapas:</p>



<ul><li>Percorre todas as posições dos pixels da imagem;</li><li>Para cara pixel da imagem, percorre todos os elementos do elemento estruturante e testa a estrutura na imagem conforme as etapas:<ul><li>Verifica-se se o elemento do núcleo possui valor e:<ul><li>Se o elemento possuir valor, verifica a posição correspondente na imagem também possui valor e:<ul><li>Se o pixel possuir valor, verifica o próximo elemento;</li><li>Se o pixel não possuir, marca o teste como negado;</li></ul></li></ul></li></ul><ul><li>Se o elemento não possui valor, verifica o próximo elemento;</li><li>Ao finalizar todos os testes dos elementos, do núcleo na região do pixel, e caso nenhum for negado, marca na imagem de destino o valor 255, do contrário marca como 0;</li></ul></li></ul>



<pre class="wp-block-preformatted">function erosao(nucleo, centro, imagem, imagemSaida) {
  //Percorre a imagem
  for (let x = centro.x; x &lt; imagem.cols; x++) {
    for (let y = centro.y; y &lt; imagem.rows; y++) {

      let hasNucleo = true;
      //Percorre o elemento estruturante (núcleo)
      for (let j = 0; j &lt; nucleo.cols; j++) {
        for (let k = 0; k &lt; nucleo.rows; k++) {
          
          //Verifica-se se o elemento do núcleo deve ser checado
          const nucleoTemValor = nucleo.ucharPtr(k, j)[0] &gt; 0;
          if (nucleoTemValor) {
            const col = x + j - centro.x;
            const row = y + k - centro.y;

            //Verifica-se se a imagem tem valor na mesma posição do núcleo
            const imagemTemValor = imagem.ucharPtr(row, col)[0] &gt; 0;
            if (!imagemTemValor) {
              hasNucleo = false;
              break;
            }
          }
        }
      }

      imagemSaida.ucharPtr(y, x)[0] = hasNucleo ? 255 : 0;
    }
  }
}</pre>



<h2>Dilatação</h2>



<p>A dilatação consiste em testar cada elemento da imagem de origem e verificar se possui valor 1, caso exista na imagem de destino, então é adicionado os valores do elemento estruturante a partir da posição central do elemento estruturante.</p>



<p>A programação da dilatação é menos complexa que a da erosão, nossa função realiza apenas as seguintes etapas:</p>



<ul><li>Percorre todas as posições dos pixeis da imagem;</li><li>Para cara pixel da imagem:<ul><li>Verifica-se se o pixel possui valor e:<ul><li>Caso possuir, percorre os elementos do núcleo e os projeta na imagem de destino;</li><li>Caso não possuir, não realiza nenhuma operação;</li></ul></li></ul></li></ul>



<pre class="wp-block-preformatted">function dilatacao(nucleo, centro, imagem, imagemSaida) {
  //Percorre a imagem
  for (let x = centro.x; x &lt; imagem.cols; x++) {
    for (let y = centro.y; y &lt; imagem.rows; y++) {

      //Verifica-se se o pixel da imagem possui valor positivo
      const pixelComValor = imagem.ucharPtr(y, x)[0] &gt; 0;
      if (pixelComValor) {

        //Percorre o elemento estruturante (núcleo)
        for (let j = 0; j &lt; nucleo.cols; j++) {
          for (let k = 0; k &lt; nucleo.rows; k++) {
            
            //Verifica-se se o elemento do núcleo tem valor positivo
            const nucleoTemValor = nucleo.ucharPtr(k, j)[0] &gt; 0;
            if (nucleoTemValor) {
              const col = x + j - centro.x;
              const row = y + k - centro.y;

              imagemSaida.ucharPtr(row, col)[0] = 255;
            }
          }
        }
      }
    }
  }
}</pre>



<h2>Abertura</h2>



<p>A abertura de uma imagem A, por um elemento estruturante B, é simplesmente a operação de erosão de A por B, seguida da dilatação de A por B. Como a abertura é apenas o encadeamento de duas operações, nosso código de exemplo faz apenas isto.</p>



<pre class="wp-block-preformatted">function abertura(nucleo, centro, imagem, imagemSaida) {
  let imgTemporaria = new cv.Mat( imagem.rows, imagem.cols, imagem.type(), new cv.Scalar(0));
  
  erosao(nucleo, centro, imagem, imgTemporaria);
  dilatacao(nucleo, centro, imgTemporaria, imagemSaida);

  imgTemporaria.delete();
}</pre>



<h2>Fechamento</h2>



<p>O fechamento de uma imagem A, por um elemento estruturante B, é simplesmente a operação de dilatação de A por B, seguida da erosão de A por B. Como o fechamento também é apenas o encadeamento de duas operações, nosso código de exemplo faz apenas isto também.</p>



<pre class="wp-block-preformatted">function fechamento(nucleo, centro, imagem, imagemSaida) {
  let imgTemporaria = new cv.Mat( imagem.rows, imagem.cols, imagem.type(), new cv.Scalar(0));

  dilatacao(nucleo, centro, imagem, imgTemporaria);
  erosao(nucleo, centro, imgTemporaria, imagemSaida);

  imgTemporaria.delete();
}</pre>



<h2>Considerações</h2>



<p>As funções programadas neste post possuem caráter de estudo, afim de entender as etapas e os processos morfológicos, pois não foram pensadas em questões como desempenho nestes exemplos. Caso você precise utilizar este tipo de operação, é recomendado que utilize uma biblioteca preparada para isso, como o OpenCV ou similar.</p>



<p>O código aqui apresentado esta disponível no link abaixo:</p>



<p>Source code: <a href="https://github.com/visaocomputacionalexemplos/morfologia/blob/main/javascript/base/morfologia.html">https://github.com/visaocomputacionalexemplos/morfologia/blob/main/javascript/base/morfologia.html</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/programando-erosao-dilatacao-abertura-e-fechamento-morfologica-com-javascript/">Programando Erosão, Dilatação, Abertura e Fechamento Morfológica com Javascript.</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Experimento &#8211; NDVI e NDWI com o Google Earth Engine</title>
		<link>https://visaocomputacional.com.br/experimento-ndvi-e-ndwi-com-o-google-earth-engine/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=experimento-ndvi-e-ndwi-com-o-google-earth-engine</link>
		
		<dc:creator><![CDATA[Piemontez]]></dc:creator>
		<pubDate>Fri, 18 Mar 2022 00:22:54 +0000</pubDate>
				<category><![CDATA[Experimentos]]></category>
		<category><![CDATA[Google Earth Engine]]></category>
		<category><![CDATA[NDVI]]></category>
		<category><![CDATA[NDWI]]></category>
		<guid isPermaLink="false">https://visaocomputacional.com.br/?p=3041</guid>

					<description><![CDATA[<p>Detectando água e vegetação na superfícies terrestres a partir de imagens multiespectrais de satélites.</p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/experimento-ndvi-e-ndwi-com-o-google-earth-engine/">Experimento &#8211; NDVI e NDWI com o Google Earth Engine</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="ratio ratio-16x9"><iframe loading="lazy" title="VC - Experimento - NDVI e NDWI com o Google Earth Engine" width="800" height="450" src="https://www.youtube.com/embed/6FVhfF13q9E?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



<p>Neste experimento, vamos demostrar a aplicação das técnicas NDWI e NDVI, capazes de identificar água e a saúde da vegetação, por meio de imagens públicas de satélites com o Google Earth Engine. Essas técnicas foram apresentadas no post <a href="https://visaocomputacional.com.br/ndvi-e-ndwi-indice-de-vegetacao-e-indice-de-agua/">&#8220;Índice de Vegetação e Índice de Água&#8221;</a>.</p>



<p>A técnica NDVI &#8211; Índice de vegetação por diferença normalizada, identifica a saúde da planta, calculando a diferença de refletância entre o infravermelho-próximo e o vermelho, com a fórmula:</p>



<pre class="wp-block-preformatted"><strong>Fórmula:</strong> NDVI = (Infravermelho Próximo - Vermelho) / (Infravermelho Próximo + Vermelho).</pre>



<p>A técnica NDWI &#8211;  Índice de vegetação por diferença normalizada identifica água, inundações, mar, etc. Calculando a diferença de refletância entre o infravermelho-próximo e o verde, com a fórmula:</p>



<pre class="wp-block-preformatted"><strong>Fórmula:</strong> NDWI = (Verde – Infravermelho Próximo) / (Verde + Infravermelho Próximo).</pre>



<p>Estas duas técnicas diferentes, podem ser aplicadas em imagens de satélite ou através de câmeras infravermelho de forma muito simples. Neste post, iremos demonstrar como aplicá-las com a ferramenta Google Earth Engine utilizando uma base de dados geoespaciais pública, para pesquisa. </p>



<h2>Google Earth Engine</h2>



<p>É uma ferramenta desenvolvida pela Google que combina um catálogo de várias de imagens de satélite e conjuntos de dados geoespaciais com recursos de análise em escala planetária. Com o objetivo, de que cientistas, pesquisadores e desenvolvedores usam o Earth Engine para detectar mudanças, mapear tendências e quantificar diferenças na superfície da Terra. </p>



<p>A ferramenta está disponível para uso comercial e é gratuito para uso acadêmico e de pesquisa. Para utilizar o Code Editor, basta acessar o link <a href="https://code.earthengine.google.com/">&#8220;code&#8221;</a>, realizar o login com sua conta do Google e de um navegador web desktop. A ferramenta contém os seguintes 4 painéis:</p>



<ul><li>O Editor, de código onde serão adicionados todos os procedimentos e script;</li><li>O Painel de status, que exibem as saídas dos procedimentos executados, como exibição de logs e erros;</li><li>O Painel de navegação, semelhante ao Explorer do Windows;</li><li>O Mapa, onde serão exibidos todos os resultados e análises feitas pelos scripts criado.</li></ul>



<figure class="wp-block-image"><img src="https://mapasabertos.files.wordpress.com/2021/03/fig-1.jpg?w=1024" alt=""/><figcaption>Editor de código do Google Earth Engine<br>Autor: Iporã Brito Possantti (Mapasabertos)</figcaption></figure>



<h2>Catálogos de Dados do Google Earth </h2>



<p>Pare aplicar as técnicas de análise de dados geoespaciais, com o Earth Engine, primeiro é preciso selecionar qual ou quais coleções de dados/imagens deseja-se utilizar. Existe uma grande variedade de base de dados e para diversas finalidades, porém, para nosso agrado, o Google disponibiliza um buscador (<a href="https://developers.google.com/earth-engine/datasets/catalog">Clique aqui para acessar</a>) que nos facilita a encontrá-la.</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="296" src="https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-1-1024x296.png" alt="" class="wp-image-3080" srcset="https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-1-1024x296.png 1024w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-1-300x87.png 300w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-1-768x222.png 768w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-1-1536x444.png 1536w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-1.png 1626w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Buscador de base de dados do Earth Engine.</figcaption></figure>



<p>Neste experimento, iremos utilizar a base <a href="https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C01_T1_TOA">USGS Landsat 8 Collection 1 Tier 1 TOA Reflectance</a>. Base de dados com informações de refletância do espectro de luz magnético, que possui imagens com as cores e o infravermelho,  necessário para aplicar as fórmulas NDVI e NDWI.</p>



<p>Esta base de dados, possui imagens coletadas entre o período de 2013 à 2022. As informações da base de dados são divididas em bandas, cada banda representa uma faixa do espectro eletromagnético. No experimento iremos utilizar as bandas B3, B4 e B5, que representam respectivamente o verde, vermelho e infravermelho próximo.</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="458" src="https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-2-1024x458.png" alt="" class="wp-image-3083" srcset="https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-2-1024x458.png 1024w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-2-300x134.png 300w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-2-768x344.png 768w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/image-2.png 1486w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Bandas da coleção de dados Landsat8 Tier 1 Reflectance</figcaption></figure>



<h2>Experimento</h2>



<p>Coletar NDVI e NDWI com o Earth Engine é muito fácil, para testes rápidos precisamos apenas realizar 4 etapas: selecionar a coleção de dados; selecionar as bandas; aplicar as fórmulas e exibir o resultado no mapa.</p>



<h4>Selecionar Coleção de dados</h4>



<p>Na primeira etapa, é preciso selecionar a região de interesse no mapa, o local que se deseja extrair as imagens, no experimento foi selecionado a região de Florianópolis &#8211; SC.  Esta região foi selecionada por meio da função  <strong>ee.Geometry.Point </strong>que criar uma variável com as informações da coordenada desejada.</p>



<p>Também é necessário coletar a base de imagens ou coleção de dados, por meio da função <strong>ee.ImageCollection</strong>. Com a coleção de dados indicada, agora precisamos indicar 2 filtros, o filtro da região de interesse e o filtro de período de busca de imagens. Estes filtros são aplicados por meio das funções <strong>filterBounds</strong> e <strong>filterDate</strong>.</p>



<pre class="wp-block-preformatted">//Coleta as posições do mapa na região de Florianópolis - SC
var imagePoint = ee.Geometry.Point([-49, -27.6935391]);
var viewPoint = ee.Geometry.Point([-48.5449963, -27.5930994]);

//Base de imagens geoespaciais utilizada
var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR');
//Informa o período de busca das imagens
var l8Query =  l8
    .filterBounds(imagePoint)
    .filterDate('2021-01-01', '2021-12-31')
    .sort('CLOUD_COVER');

//Coleta a primeira imagem identificada para o período informado
var image = ee.Image(l8Query.first());

//Centraliza o mapa
Map.centerObject(viewPoint, 13);</pre>



<p>Com os filtros e a região de interesse informada, basta solicitar os registros com a função <strong>l8Query.first</strong>. Com os registros coletados, devemos convertê-los em dados de imagens que podemos trabalhar com a função <strong>ee.Image</strong> que retorna uma classe com diversas funcionalidade.</p>



<p>Observe que, além dos filtros foi informada para ordenar a coleção de dados por meio da função <strong>sort</strong>, com base na ordem de dados do atributo <strong>CLOUD_COVER</strong> da coleção de dados. Este atributo indica o quanto da região esta coberta por nuvens, e como não queremos realizar a analise dos dados com nuvens, então indicamos para trazer a primeira imagem com o menor número de nuvens identificadas. Também é possível realizar filtros por este atributo, porém isso pode fazer com que não venha nenhuma imagem da região devido o filtro aplicado.</p>



<h4>Selecionar Bandas</h4>



<p>Na segunda etapa, basta extrairmos da imagem as bandas B3, B4 e B5 da coleção de dados que correspondem ao verde, vermelho e infravermelho-próximo do espectro eletromagnético, conforme código abaixo: </p>



<pre class="wp-block-preformatted">//Coleta as bandas de cores NIR, Vermelho e Verde 
var green = image.select('B3');
var red = image.select('B4');
var nir = image.select('B5');</pre>



<h4>Aplicar e visualizar Fórmulas</h4>



<p>Por fim, basta realizar os cálculos e adicionar a camada (Layer) com a imagem do NDVi gerada pelo Earth Engine ao mapa. Para adicionar ao mapa basta chamar a função <strong>Map.addLayer</strong>. Note que ao adicionar a camada NDVI, foram adicionados 2 parâmetros adicionais, o primeiro parâmetro (ndviParams), indica quais cores representarão cada extremo do cálculo NDVI, utilizamos a cores vermelha pra representar o valor -1, verde +1 e branco valores próximo ao zero. O segundo parâmetro &#8220;NDVI imagem&#8221; indica o nome do botão que ativa e inativa a visualização da camada no visualizador do mapa.</p>



<pre class="wp-block-preformatted">// Computa o Índice de Vegetação de Diferença Normalizada (NDVI).
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');
var ndviParams = {min: -1, max: 1, palette: ['red', 'white', 'green']};
Map.addLayer(ndvi, ndviParams, 'NDVI image');</pre>



<p>Para calcular o NDWI basta realizar as mesmas operações do NDVI, porém ajustando o cálculo para utilizar o infravermelho e o verde.</p>



<pre class="wp-block-preformatted">// Computa o Índice de Água de Diferença Normalizada (NDWI).
var ndwi = green.subtract(nir).divide(green.add(nir)).rename('NDVI');
var ndwiParams = {min: -1, max: 1, palette: ['red', 'white', 'blue']};
Map.addLayer(ndwi, ndwiParams, 'NDWI image');</pre>



<p>Também é possível realizar todo o cálculo do NDVI e NDWI de uma forma bem mais simples. Como essas duas formulas são cálculos de normalização, basta utilizar os seguintes códigos abaixo que o próprio Earth Engine converte para as fórmulas descritas acima.</p>



<pre class="wp-block-preformatted">//Formas resumidas de coletar a informação
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
var ndwi = image.normalizedDifference(['B3', 'B5']).rename('NDVI');
Map.addLayer(ndvi);
Map.addLayer(ndwi);</pre>



<p>Com este experimento e o código acima foram geradas as seguintes imagens: </p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="394" src="https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndvi-1024x394.jpg" alt="" class="wp-image-3048" srcset="https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndvi-1024x394.jpg 1024w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndvi-300x115.jpg 300w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndvi-768x295.jpg 768w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndvi.jpg 1358w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption><br>Resultado NDVI do Goggle Earth Engine</figcaption></figure>



<p>Na primeira imagem, na parte esquerda, visualizamos em verde a refletância de áreas cobertas por vegetação e em vermelho áreas com nenhuma refletância de vegetação segundo a fórmula do NDVI. Quanto mais escuro o verde é indicativo de maior concentração de vegetação ou vegetações mais saudáveis. </p>



<p>Observar que nem toda vegetação saudável possui um alto nível de NDVI, cada vegetação possui uma característica especifica de saúde, que requerem estudos específicos para saber identificar sua saúde através do NDVI. Porém para identificar regiões de mata, floresta ou de cultivo, o NDVI é ideal ideal.</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="394" src="https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndwi-1-1024x394.jpg" alt="" class="wp-image-3050" srcset="https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndwi-1-1024x394.jpg 1024w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndwi-1-300x115.jpg 300w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndwi-1-768x295.jpg 768w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/google_earth_ndwi-1.jpg 1358w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Resultado NDWI do Goggle Earth Engine</figcaption></figure>



<p>Na segunda imagem, na parte esquerde, visualizamos em azul todas as regiões com superfície coberta por água, inundações e em vermelho a ausência d&#8217;água. O interessante nesta segunda imagem é que ela consegue identificar a Lagoa da Conceição, uma lagoa situada no meio de Florianópolis e se olharmos a mesma imagem, na parte direita, não é possível identificar a lagoa pela imagem de satélite.</p>



<p>Para visualizar esta aplicação, basta acessar o link <a href="https://rafaelpiemontez.users.earthengine.app/view/ndvindwi">Teste NDVI NDWI</a>. Todo este experimento foi criado, com base no tutorial criado pelo próprio Google (<a href="https://developers.google.com/earth-engine/tutorials/tutorial_api_06">clique aqui para acessar o tutorial</a>).</p>



<h2>Plataforma MapBiomas</h2>



<p>Uma ferramenta muito mais elabora, que esta criada neste post, é a plataforma <a href="https://mapbiomas.org/ferramentas">MapBiomas</a> que disponibilizam diversas análises sensoriais do Brasil com <a href="https://mapbiomas.org/ferramentas">scripts</a> criados por meio do Google Earth Engine.</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1024" height="486" src="https://visaocomputacional.com.br/wp-content/uploads/2022/03/mapbiomas-1024x486.jpg" alt="" class="wp-image-3063" srcset="https://visaocomputacional.com.br/wp-content/uploads/2022/03/mapbiomas-1024x486.jpg 1024w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/mapbiomas-300x142.jpg 300w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/mapbiomas-768x364.jpg 768w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/mapbiomas-1536x729.jpg 1536w, https://visaocomputacional.com.br/wp-content/uploads/2022/03/mapbiomas.jpg 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Ilustração da Plataforma MapBiomas</figcaption></figure>



<p><a href="https://plataforma.brasil.mapbiomas.org/?activeBaseMap=8&amp;layersOpacity=70&amp;activeModule=coverage&amp;activeModuleContent=coverage%3Acoverage_main&amp;activeYear=2020&amp;mapPosition=-14.392118%2C-56.250000%2C4&amp;timelineLimitsRange=1985%2C2020">Clique aqui</a> para acessar a ferramenta ou <a href="https://plataforma.brasil.mapbiomas.org/agua">clique</a> <a href="https://plataforma.brasil.mapbiomas.org/agua">aqui</a> para visualizar uma análise sensorial e temporal da superfície d&#8217;água no Brasil.</p>



<p>Todo o código fonte do projeto, está disponível para replicação do experimento no link abaixo. Caso tenha dúvidas ou sugestões de melhorias no post, deixe seu comentário abaixo.</p>



<p>Source:</p>



<p><a href="https://github.com/visaocomputacionalexemplos/espectroeletromagnetico/tree/main/google_earth_ndvi_ndwi">https://github.com/visaocomputacionalexemplos/espectroeletromagnetico/tree/main/google_earth_ndvi_ndwi</a></p>



<p>Referências:</p>



<p>Iporã Brito Possantti via MasAbertos, O Google Earth&nbsp;Engine. <a href="https://mapasabertos.com/2021/03/30/o-google-earth-engine/">Acessado em 04 mar 2022</a>.</p>



<p>Google, NDVI, Mapping a Function over a Collection, Quality Mosaicking . <a href="https://developers.google.com/earth-engine/tutorials/tutorial_api_06">Acessado em 04 mar 2022.</a></p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/experimento-ndvi-e-ndwi-com-o-google-earth-engine/">Experimento &#8211; NDVI e NDWI com o Google Earth Engine</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Experimento &#8211; Detecção de piscadas e contador de piscadas com OpenCV e Dlib</title>
		<link>https://visaocomputacional.com.br/deteccao-e-contagem-de-piscadas-com-opencv-e-dlib/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=deteccao-e-contagem-de-piscadas-com-opencv-e-dlib</link>
		
		<dc:creator><![CDATA[Piemontez]]></dc:creator>
		<pubDate>Thu, 21 Oct 2021 11:53:02 +0000</pubDate>
				<category><![CDATA[Experimentos]]></category>
		<category><![CDATA[Contador Piscadas]]></category>
		<category><![CDATA[Detecção Piscadas]]></category>
		<category><![CDATA[Dlib]]></category>
		<category><![CDATA[facemark]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Pontos Faciais]]></category>
		<guid isPermaLink="false">http://visaocomputacional.com.br/?p=2297</guid>

					<description><![CDATA[<p>Apresentação dos resultados dos experimentos na detecção de piscadas com as bibliotecas OpenCV e Dlib.</p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/deteccao-e-contagem-de-piscadas-com-opencv-e-dlib/">Experimento &#8211; Detecção de piscadas e contador de piscadas com OpenCV e Dlib</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="ratio ratio-16x9"><iframe loading="lazy" title="VC - Experimento - Detecção de piscadas e contador de piscadas com OpenCV e Dlib" width="800" height="450" src="https://www.youtube.com/embed/6Fi8jTeIG8s?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div></figure>



<p>Neste vídeo, apresento os resultados obtidos no experimento de detecção e contagem de piscadas com a webcam.</p>



<p>Para realizar este experimento, foi necessário coletar o contorno dos olhos através da detecção de pontos faciais do rosto e criar um pequeno controlador que verifica a proporção do olho aberto e fechado.&nbsp; Este controlador verifica se o olho foi fechado e depois verifica se o olho voltou a estar aberto, ao realizar finalizar este processo contabiliza uma piscada.</p>



<p>A coleta dos pontos faciais foi realizada com a biblioteca OpenCV e Dlib, que por padrão informa 6 referências para cada olho. Os posts &#8220;Detecção de pontos faciais com <a href="http://visaocomputacional.com.br/deteccao-de-pontos-faciais-facemark-com-opencv/">OpenCV&#8221;</a> e &#8220;Detecção de pontos faciais com <a href="http://visaocomputacional.com.br/deteccao-de-pontos-faciais-facemark-com-dlib/">Dlib</a>&#8220;, detalham melhor esta coleta.</p>



<p>A proporção de olho aberto é calculada apenas dividindo a altura do olho pela largura do olho, conforme ilustrado na Fig 1. abaixo.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="http://visaocomputacional.com.br/wp-content/uploads/2021/10/calculo_proporcao_olho.png"><img loading="lazy" width="493" height="191" src="http://visaocomputacional.com.br/wp-content/uploads/2021/10/calculo_proporcao_olho.png" alt="" class="wp-image-2312" srcset="https://visaocomputacional.com.br/wp-content/uploads/2021/10/calculo_proporcao_olho.png 493w, https://visaocomputacional.com.br/wp-content/uploads/2021/10/calculo_proporcao_olho-300x116.png 300w" sizes="(max-width: 493px) 100vw, 493px" /></a><figcaption>Fig 1. Informações utilizadas para calcular a proporção de olho aberto.</figcaption></figure></div>



<p>Caso você esteja se perguntando, &#8220;mas por que ele não utiliza apenas a informação da altura olho?&#8221;. Na imagem abaixo (Fig 2.) espero responder esta pergunta. Note, nesta imagem, que existem diversos tamanhos de olhos, se for considerado apenas a altura do olho aberto, para saber se o olho está fechando ou não, o controlador irá identificar piscadas apenas com um único tamanho de imagem de olho, e não para qualquer tamanho de olho encontrado.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="http://visaocomputacional.com.br/wp-content/uploads/2021/10/olho_diferente_tamanhos.png"><img loading="lazy" width="491" height="121" src="http://visaocomputacional.com.br/wp-content/uploads/2021/10/olho_diferente_tamanhos.png" alt="" class="wp-image-2319" srcset="https://visaocomputacional.com.br/wp-content/uploads/2021/10/olho_diferente_tamanhos.png 491w, https://visaocomputacional.com.br/wp-content/uploads/2021/10/olho_diferente_tamanhos-300x74.png 300w" sizes="(max-width: 491px) 100vw, 491px" /></a><figcaption>Fig 2. Olhos com diferentes tamanhos na imagem.</figcaption></figure></div>



<p>Para calcular a largura do olho, basta calcular a distância euclidiana entre os pontos da lateral esquerda e lateral direita do olho. A Fig 3. ilustra o cálculo da distância euclidiana.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="http://visaocomputacional.com.br/wp-content/uploads/2021/10/distancia_euclidiana-1.png"><img loading="lazy" width="454" height="269" src="http://visaocomputacional.com.br/wp-content/uploads/2021/10/distancia_euclidiana-1.png" alt="" class="wp-image-2324" srcset="https://visaocomputacional.com.br/wp-content/uploads/2021/10/distancia_euclidiana-1.png 454w, https://visaocomputacional.com.br/wp-content/uploads/2021/10/distancia_euclidiana-1-300x178.png 300w" sizes="(max-width: 454px) 100vw, 454px" /></a><figcaption>Fig 3. Fórmula distância euclidia.</figcaption></figure></div>



<p>E para calcular a altura dos olhos é preciso coletar o centro da parte superior e o centro da parte inferior do olho. O centro da parte superior é obtido somando os X e Y das posições 38 e 39 do olho e dividindo por 2, conforme Fig 1. E o centro da parte inferior é obtido da mesma forma, porém utilizando as posições 42 e 41. A Fig 4. ilustra todo o cálculo realizado para calcular a proporção do olho e a condicional para verificar se o olho está aberto e fechado.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="http://visaocomputacional.com.br/wp-content/uploads/2021/10/proporcao_olho_aberto.png"><img loading="lazy" width="591" height="338" src="http://visaocomputacional.com.br/wp-content/uploads/2021/10/proporcao_olho_aberto.png" alt="" class="wp-image-2328" srcset="https://visaocomputacional.com.br/wp-content/uploads/2021/10/proporcao_olho_aberto.png 591w, https://visaocomputacional.com.br/wp-content/uploads/2021/10/proporcao_olho_aberto-300x172.png 300w, https://visaocomputacional.com.br/wp-content/uploads/2021/10/proporcao_olho_aberto-150x85.png 150w" sizes="(max-width: 591px) 100vw, 591px" /></a><figcaption>Fig 4. Cálculo de proporção de olho aberto.</figcaption></figure></div>



<p>Todo o código fonte do projeto está disponível para replicação do experimento no link abaixo. Caso tenham dúvidas e sugestões de melhorias no post, deixe seu comentário abaixo.</p>



<p>Source:<br><a href="https://github.com/visaocomputacionalexemplos/experimentos_faciais/tree/main/identificar_piscada">https://github.com/visaocomputacionalexemplos/experimentos_faciais/tree/main/identificar_piscada</a></p>
<p>The post <a rel="nofollow" href="https://visaocomputacional.com.br/deteccao-e-contagem-de-piscadas-com-opencv-e-dlib/">Experimento &#8211; Detecção de piscadas e contador de piscadas com OpenCV e Dlib</a> appeared first on <a rel="nofollow" href="https://visaocomputacional.com.br">Visão Computacional</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
