2012-05-07 14 views
5

Say mam ten obraz:Rozpoznanie pozycji czerwonej kuli w obrazie za pomocą JavaScript?

enter image description here

Chciałabym rozpoznać położenie czerwoną kulę w obrazie, mogę zmierzyć rozmiar kuli (w pikselach) w przodzie.

Wiem, że mógłbym narysować obrazek na płótnie, wtedy mógłbym uzyskać dane koloru piksela z context.getImageData, ale co powinienem zrobić? który algorytm powinienem użyć? Jestem nowy w przetwarzaniu obrazów, wielkie dzięki.

+0

jesteśmy przypuszczać, kolor piłki jest unikalna (żaden inny obiekt tego koloru)? – snies

+0

@ snies nie, dlatego rozmiar piłki jest mierzony przed – wong2

+0

, ale znamy kolor lub tylko kształt (i rozmiar)? – snies

Odpowiedz

0

Cóż, poszedłbym i zgrupowałem piksele tego koloru. Na przykład, możesz mieć tabelę, w której przechowujesz czerwone (lub w zakresie progu) piksele (współrzędne są kluczem wyszukiwania) i wartość całkowitą będącą identyfikatorem klastra za każdym razem, gdy napotkasz piksel bez znanych czerwonych sąsiadów uruchamia nowy klaster, wszystkie pozostałe czerwone piksele otrzymują identyfikator klastra czerwonego piksela, z którego sąsiadują. W zależności od was algorytmy jądra:

A) XXX  B) X 
     XOX   XOX 
     XXX   X 

może trzeba zajmować (przypadek B) z pikselem łączącej dwie wcześniejsze niezwiązane klastry. Będziesz musiał zastąpić identyfikator klastra jednego z tych klastrów.

Po tym masz klastry pikseli. Te można analizować. W przypadku okrągłego kształtu powinienem szukać mediany wx i y dla każdego skupienia i sprawdzić, czy wszystkie piksele tego skupienia znajdują się w promieniu.

Nie powiedzie się, jeżeli czerwona kula (lub jej część) znajduje się przed innym czerwonym obiektem. Potrzebowalibyście bardziej skomplikowanych algorytmów.

1

Oto kod poświęcony zdobyciu pozycji kulki. Pozycja wyjściowa zostanie zapisana w konsoli, więc otwórz konsolę JS! Ten kod ma pewne wartości, które można odtwarzać. Wybrałem trochę pracy dla twojego obrazu, taką jak zgrubna średnica kulki wynosząca 14 pikseli i próg dla każdego składnika koloru.

I zapisany obraz jako „test.jpg”, ale można zmienić kod do właściwej ścieżki obrazu na linii 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> 
Powiązane problemy