假设我有这张图片:
我想识别图像中红球的位置,我可以测量前面球的大小(以像素为单位)。
我知道我可以将图像绘制到画布上,然后我可以使用 获取像素颜色数据context.getImageData
,但是我该怎么办?我应该使用哪种算法?我是图像处理的新手,非常感谢。
假设我有这张图片:
我想识别图像中红球的位置,我可以测量前面球的大小(以像素为单位)。
我知道我可以将图像绘制到画布上,然后我可以使用 获取像素颜色数据context.getImageData
,但是我该怎么办?我应该使用哪种算法?我是图像处理的新手,非常感谢。
这是专用于获取该球位置的代码。输出位置将记录到控制台,因此请打开您的 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>
好吧,我会去聚集那种颜色的像素。例如,您可以有一个查找表,其中存储红色(或在阈值范围内)像素(坐标是查找键),并且每当遇到没有任何已知红色邻居的像素时,一个整数值作为集群 ID它启动了一个新的集群,所有其他红色像素都获得了与它们相邻的红色像素的集群 ID。取决于你的算法内核:
A) XXX B) X
XOX XOX
XXX X
您可能需要处理(案例 B)连接两个先前未连接的集群的像素。您必须替换其中一个集群的集群 ID。
之后你有像素簇。这些你可以分析。如果是圆形,我会在每个簇的 x 和 y 中查找中值,并检查该簇的所有像素是否都在半径内。
如果红球(或它的一部分)在另一个红色物体的前面,这将失败。您将需要更复杂的算法。