2012-05-07 11 views
5

Dire che ho questa immagine:Riconoscere la posizione di una palla rossa in un'immagine con JavaScript?

enter image description here

vorrei riconoscere la posizione della palla rossa nell'immagine, ho potuto misurare la dimensione della palla (in pixel) in avanti.

So che è possibile disegnare l'immagine su una tela, quindi è possibile ottenere i dati del colore dei pixel con context.getImageData, ma cosa devo fare? quale algoritmo dovrei usare? Sono nuovo nell'elaborazione delle immagini, grazie mille.

+0

siamo noi ad assumere, il colore della palla è unica (nessun altro oggetto di quel colore)? – snies

+0

@snies no, ecco perché la dimensione della palla viene misurata in anticipo – wong2

+0

ma conosciamo il colore o solo la forma (e la dimensione)? – snies

risposta

0

Beh, andrei a raggruppare i pixel di quel colore. Ad esempio, è possibile avere una tabella di ricerca in cui si memorizzano i pixel rossi (o nell'intervallo di una limitazione) (le coordinate sono la chiave di ricerca) e un valore intero che rappresenta l'id del cluster ogni volta che si incontra un pixel senza alcun vicino rosso noto inizia un nuovo cluster, tutti gli altri pixel rossi ottengono l'id del cluster di un pixel rosso di cui sono il vicino. A seconda di voi algoritmi kernel:

A) XXX  B) X 
     XOX   XOX 
     XXX   X 

potrebbe essere necessario affrontare (caso B) con un pixel che collega due precedenti gruppi non collegati. Dovresti sostituire l'id del cluster di uno di quei cluster.

Dopodiché ci sono gruppi di pixel. Questi puoi analizzare. In caso di una forma rotonda cercherei la mediana in xey per ciascun cluster e verificare se tutti i pixel di quel cluster sono nel raggio.

Questo fallirà se la palla rossa (o parte di essa) si trova di fronte a un altro oggetto rosso. Avresti bisogno di algoritmi più complessi.

1

Ecco il codice dedicato per ottenere quella posizione della palla. La posizione di uscita verrà registrata nella console in modo da avere la console JS aperta! Questo codice contiene alcuni valori con cui puoi giocare. Ho scelto alcuni che funzionano per la tua immagine, come il diametro approssimativo della palla di 14 pixel e la soglia per ogni componente di colore.

ho salvato l'immagine come "test.jpg", ma è possibile modificare il codice per il percorso dell'immagine corretta sulla linea 11.

<!DOCTYPE html> 
<html> 
    <body> 
     <canvas width="800" height="600" id="testCanvas"></canvas> 
     <script type="text/javascript"> 
      var img = document.createElement('img'); 
      img.onload = function() { 
       console.log(getBallPosition(this)); 
      }; 
      img.src = 'test.jpg'; 

      function getBallPosition(img) { 
       var canvas = document.getElementById('testCanvas'), 
        ctx = canvas.getContext('2d'), 
        imageData, 
        width = img.width, 
        height = img.height, 
        pixelData, 
        pixelRedValue, 
        pixelGreenValue, 
        pixelBlueValue, 
        pixelAlphaValue, 
        pixelIndex, 
        redThreshold = 128, 
        greenThreshold = 40, 
        blueThreshold = 40, 
        alphaThreshold = 180, 
        circleDiameter = 14, 
        x, y, 
        count, 
        ballPosition, 
        closestBallCount = 0, 
        closestBallPosition; 

       // Draw the image to the canvas 
       canvas.width = width; 
       canvas.height = height; 
       ctx.drawImage(img, 0, 0); 

       // Get the image data 
       imageData = ctx.getImageData(0, 0, width, height); 
       pixelData = imageData.data; 

       // Find the ball! 
       for (y = 0; y < height; y++) { 
        // Reset the pixel count 
        count = 0; 

        // Loop through the pixels on this line 
        for (x = 0; x < width; x++) { 
         // Set the pixel data starting point 
         pixelIndex = (y * width * 4) + (x * 4); 

         // Grab the red pixel value 
         pixelRedValue = pixelData[pixelIndex]; 
         pixelGreenValue = pixelData[pixelIndex + 1]; 
         pixelBlueValue = pixelData[pixelIndex + 2]; 
         pixelAlphaValue = pixelData[pixelIndex + 3]; 

         // Check if the value is within out red colour threshold 
         if (pixelRedValue >= redThreshold && pixelGreenValue <= greenThreshold && pixelBlueValue <= blueThreshold && pixelAlphaValue >= alphaThreshold) { 
          count++; 
         } else { 
          // We've found a pixel that isn't part of the red ball 
          // so now check if we found any red data 
          if (count === circleDiameter) { 
           // We've found our ball 
           return { 
            x: x - Math.floor(circleDiameter/2), 
            y: y 
           }; 
          } else { 
           // Any data we found was not our ball 
           if (count < circleDiameter && count > closestBallCount) { 
            closestBallCount = count; 
            closestBallPosition = { 
             x: x - Math.floor(circleDiameter/2), 
             y: y 
            }; 
           } 
           count = 0; 
          } 
         } 
        } 
       } 

       return closestBallPosition; 
      } 
     </script> 
    </body> 
</html> 
Problemi correlati