6

私がこの画像を持っているとしましょう:

ここに画像の説明を入力してください

画像内の赤いボールの位置を認識したいのですが、前方のボールのサイズ(ピクセル単位)を測定できました。

画像をキャンバスに描画して、でピクセルカラーデータを取得できることcontext.getImageDataはわかっていますが、どうすればよいですか?どのアルゴリズムを使用すればよいですか?私は画像処理に不慣れです、どうもありがとう。

4

2 に答える 2

1

そのボールの位置を取得する専用のコードを次に示します。出力位置はコンソールに記録されるため、JS コンソールを開いてください。このコードには、操作できるいくつかの値が含まれています。ボールのおおよその直径が 14 ピクセルで、各色コンポーネントのしきい値など、画像に適したものを選択しました。

画像を「test.jpg」として保存しましたが、コードを 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>
于 2012-11-27T19:13:08.697 に答える
0

そうですね、その色のピクセルをクラスター化します。たとえば、赤 (またはしきい値の範囲内) のピクセル (ルックアップ キーである座標) を格納するルックアップ テーブルと、既知の赤の隣接ピクセルがないピクセルに遭遇したときのクラスター ID である整数値を使用できます。新しいクラスターを開始し、他のすべての赤のピクセルは、隣接する赤のピクセルのクラスター ID を取得します。あなたのアルゴリズムカーネルに応じて:

   A) XXX      B)  X
      XOX         XOX
      XXX          X 

以前の接続されていない 2 つのクラスターを接続するピクセルを処理する必要がある場合があります (ケース B)。そのクラスターの 1 つのクラスター ID を置き換える必要があります。

その後、ピクセルのクラスターがあります。これらを分析できます。丸い形の場合、各クラスターの x と y の中央値を探し、そのクラスターのすべてのピクセルが半径内にあるかどうかを確認します。

赤いボール (またはその一部) が別の赤いオブジェクトの前にある場合、これは失敗します。より複雑なアルゴリズムが必要になります。

于 2012-05-07T13:23:45.003 に答える