日期:2014-05-17  浏览次数:20744 次

我想查找一个“十”字白色图形的中心,应该怎么算呢?
我有一个摄像头,以及能够截图了,图像是一个黑底上有两个十字光标(较大个,多数时间是没有倾斜的)的图形,亮度一浅一深

我想图像识别,找出两个十字的中心,之后计算其中心的差距。请问应该怎么编程呢?


如果太复杂可以先告诉我一个十字应该怎么识别? 二值化之后我就没想到更好的处理方法了

------解决方案--------------------
问下,十字是不是规则的,要是的话就好弄,遍历像素,取该点的上下左右一段距离的四个点,判断是不是和它一样是白色,要是的话要就存入数组,然后对数组进行排序,求一下相差的平均值就可以了,应该不难。
------解决方案--------------------
你都二值化了还有什么不能做的。。可以用X和Y两个方向的直方图投影,然后找到能量最高的两个点坐标,X1、X2和Y1、Y2,那么(X1,Y1)、(X2,Y2)就是你要的两个十字中心。。。N个十字也是这么做。。。只要十字在投影方向上不重叠。。

------解决方案--------------------
其实重叠影响不大,因为中心和四肢的能量差距太大。。主要问题是解决倾斜(45度的时候直方图全平)。。。
------解决方案--------------------
以一个倾斜十字为例试着找了一下中心点,没优化,不知道行不行。

C# code

        int centerx = -1;
        int centery = -1;
        Bitmap bp;
        public Form1()
        {
            InitializeComponent();
        }

        unsafe private void button1_Click_1(object sender, EventArgs e)
        {
            bp = (Bitmap)Bitmap.FromFile("e:\\test.bmp");
            BitmapData data = bp.LockBits(new Rectangle(0, 0, bp.Width, bp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            Dictionary<uint, List<Point>> colorpoints = new Dictionary<uint, List<Point>>();
            uint* p = (uint*)data.Scan0;
            for (int i = 0; i < bp.Width; i++)
            {
                for (int j = 0; j < bp.Height; j++)
                {
                    uint color = p[j * bp.Width + i];
                    if (!colorpoints.Keys.Contains(color))
                        colorpoints.Add(color, new List<Point>());
                    else
                        colorpoints[color].Add(new Point(i, j));
                }
            }
            var cross = colorpoints.OrderByDescending(x => x.Value.Count).Select(y => y.Key).ToArray()[1];
            List<Point> list = colorpoints[cross];
            int leftx = list.Min(x => x.X);
            int rightx = list.Max(x => x.X);
            int topy = list.Min(x => x.Y);
            int bottomy = list.Max(x => x.Y);
            centerx = (leftx + rightx) / 2;
            centery = (topy + bottomy) / 2;
            for (int i = centerx - 10; i < centerx + 11; i++)
            {
                for (int j = centery - 10; j < centery + 11; j++)
                {
                    p[j * bp.Width + i] = 0xffffffff;
                }
            }
            bp.UnlockBits(data);
            Invalidate();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            if(centerx == -1)
                return;
            e.Graphics.DrawImage(bp, new Point(0, 0));
        }

------解决方案--------------------
结合10、11楼的方法,基本可以排除杂斑。。
------解决方案--------------------
探讨

引用:

你这个太简单了,直接用连通域判断,黑色框内白色区域的连通域,直接可以拿到十字中间的白色区域,然后计算形心就OK了,本人上学的时候就做过了。


有没有连通域判断的代码示例啊,速度怎么样啊? 型心的意思是正方形的中心吗?

------解决方案--------------------
探讨
引用:

以一个倾斜十字为例试着找了一下中心点,没优化,不知道行不行。

C# code

int centerx = -1;
int centery = -1;
Bitmap bp;
public Form1()
{
InitializeComponent();
}

……


var cross = colorpoints.OrderByDe……