您需要执行一些步骤。首先,像您一样识别箭头的边界框。其次,获取箭头像素的坐标,在这里我发现它们的红色、绿色和蓝色值都超过了 80,您可能需要为您的图像检查这一点。第三,获取箭头区域的中心。最后得到箭头Ix、Iy、Ixy的面积属性,可以得到箭头的旋转角度。
你需要对这个角度做简单的修改,如果它是一个负值,加上 Pi,你还需要从它的中心得到最远的箭头点,如果它正好从质心,角度应该是大于 Pi,否则应该小于它。
int i, x, y, t;
double xc, yc, Ix, Iy, Ixy, xf, yf, d, ang;
Bitmap img = new Bitmap(path); // load only the area that contains the arrow
List<int> px, py;
px = new List<int>();
py = new List<int>();
xc = yc = Ix = Iy = Ixy = xf = yf = d = t = 0;
for (x = 0; x < img.Width; x++)
for (y = 0; y < img.Height; y++)
if (img.GetPixel(x, y).R > 80 && img.GetPixel(x, y).G > 80 && img.GetPixel(x, y).B > 80) // you will have to check this condition for your images
{
t++; // get the number of pixels of arrow
xc += x;
yc += y;
px.Add(x); // store x-coordinates of all arrow pixels
py.Add(y); // store y-coordinates of all arrow pixels
}
// get the center of area of the arrow
xc /= t;
yc /= t;
// calculate the properties of area
for (i = 0; i < t; i++)
{
if (Math.Pow(px[i] - xc, 2) + Math.Pow(py[i] - yc, 2) > d)
{
xf = px[i] - xc;
yf = py[i] - yc;
d = Math.Pow(xf, 2) + Math.Pow(yf, 2);
}
Ix += Math.Pow(py[i] - yc, 2);
Iy += Math.Pow(px[i] - xc, 2);
Ixy += (px[i] - xc) * (py[i] - yc);
}
// calculate the angel
ang = Math.Atan2(-2 * Ixy, Ix - Iy) / 2;
// correct the angle
if (ang < 0)
ang += Math.PI;
if (xf > 0 && ang < Math.PI)
ang += Math.PI;
if (xf < 0 && ang > Math.PI)
ang -= Math.PI;
我在你的图片上试过这个,第一张是 1.769 Pi,第二张是 0.578 Pi,第三张是 0.832 Pi。