Advertisement

C# 影像特征点提取

阅读量:

版权所有 详情咨询qq 849495327

内容和要求如下:

 任务:提取一幅数字影像中的特征点
 内容:使用Moravec算子编写程序,从一幅数字影像中自动提取出50个以上的特征点
 要求:程序能读取数字图像、在窗口中显示整幅图像、在图像中显示所提取的特征点(+),并列表显示各特征点的像素坐标。

算法流程及计算原理
1.选取一个合理的邻域遍历图像,这里是5*5邻域的。在邻域中依次计算,垂直,水平,对角与反对角四个相邻像素灰度的差的平方和,作为该邻域特征值。
大致就是下面这个样子:
在这里插入图片描述
公式:
在这里插入图片描述

这里k是窗口的半径。
2.从四个特征值中选最小的值作为该像素初次候选特征值。
公式:
在这里插入图片描述
3.设定一个阈值,将大于该阈值初次候选特征值的选为二次候选特征值。
4.设定一个邻域,将该邻域最大的二次候选特征值作为最终要选择的特征值。
界面调试
在这里插入图片描述在这里插入图片描述在这里插入图片描述
主要界面的代码:

复制代码
    FORM1:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace shuzituxiangchuli
    {
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private string curFilename;
        private System.Drawing.Bitmap curbitmap;
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openglg = new OpenFileDialog();
            openglg.Filter = "所有图像文件|*.bmp;*.png;*.pcx;*.jpg;*.gif;*.tif;*.ico";
            openglg.Title = "打开图像文件";
            openglg.ShowHelp = true;
            if (openglg.ShowDialog() == DialogResult.OK)
            {
                curFilename = openglg.FileName;
                try
                {
                    curbitmap = (Bitmap)Image.FromFile(curFilename);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }
            Invalidate();
    
        }
    
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = this.panel1.CreateGraphics();
            if (curbitmap != null)
            {
                int x, y;
                x = curbitmap.Width;
                y = curbitmap.Height;
                while (x > this.Width - 160 && y > this.Height - 20)
                {
                    x = x / 2;
                    y = y / 2;
                }
                g.DrawImage(curbitmap, 160, 20, x, y);
                //g.DrawImage(curbitmap, 160, 20, curbitmap.Width, curbitmap.Height);
    
            }
            g.Dispose();
        }
    
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
    
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            //this.panel1.Left = 10;
            this.panel1.BackColor = Color.CadetBlue;
        }
    
        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            //curbitmap = new Bitmap(curbitmap, new Size(curbitmap.Width / 2, curbitmap.Height / 2));
            Graphics g = this.panel1.CreateGraphics();
            g.Clear(this.panel1.BackColor);
        }
    
        private void Form1_Scroll(object sender, ScrollEventArgs e)
        {
    
    
        }
    
        private void button4_Click(object sender, EventArgs e)
        {
            FrmhistR f = new FrmhistR(curbitmap);
            f.Show();
            FrmhistG G = new FrmhistG(curbitmap);
            G.Show();
            FrmhistB B = new FrmhistB(curbitmap);
            B.Show();
        }
    
        private void button5_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Frmliner finearfrom = new Frmliner();
                if (finearfrom.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        curbitmap.PixelFormat);
                    IntPtr ptr = bmpdata.Scan0;
                    int bytes = 3 * curbitmap.Width * curbitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
    
                    int temp = 0;
                    double a = Convert.ToDouble(finearfrom.Getscaling);
                    double b = Convert.ToDouble(finearfrom.Getoffset);
                    for (int i = 0; i < bytes; i++)
                    {
                        temp = (int)(a * grayValues[i] + b + 0.5);
                        if (temp > 255)
                        {
                            grayValues[i] = 255;
                        }
                        else
                            if (temp < 0)
                            grayValues[i] = 0;
                        else
                            grayValues[i] = (byte)temp;
    
    
                    }
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curbitmap.UnlockBits(bmpdata);
    
                }
                Invalidate();
            }
        }
    
        private void button6_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect,
                    System.Drawing.Imaging.ImageLockMode.ReadWrite, curbitmap.PixelFormat);
                IntPtr ptr = bmpdata.Scan0;
                int bytes = 2 * curbitmap.Width * curbitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                byte a = 255;
                byte b = 0;
                double p;
                for (int i = 0; i < bytes; i++)
                {
                    if (a > grayValues[i])
                    {
                        a = grayValues[i];
                    }
                    if (b < grayValues[i])
                    {
                        b = grayValues[i];
                    }
                }
                p = 255.0 / (b - a);
                for (int i = 0; i < bytes; i++)
                {
                    grayValues[i] = (byte)(p * (grayValues[i] - a) + 0.5);
                }
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curbitmap.UnlockBits(bmpdata);
                Invalidate();
    
            }
        }
    
        private void button7_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect,
                    System.Drawing.Imaging.ImageLockMode.ReadWrite, curbitmap.PixelFormat);
                IntPtr ptr = bmpdata.Scan0;
                int bytes = 3 * curbitmap.Width * curbitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
    
                for (int i = 0; i < bytes; i += 3)
                {
                    grayValues[i] = 0;
                    grayValues[i + 1] = 0;
                }
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curbitmap.UnlockBits(bmpdata);
                Invalidate();
    
            }
        }
    
        private void button8_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect,
                    System.Drawing.Imaging.ImageLockMode.ReadWrite, curbitmap.PixelFormat);
                IntPtr ptr = bmpdata.Scan0;
                int bytes = 3 * curbitmap.Width * curbitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
                double[] junzhi = new double[3];
                junzhi[0] = 0; junzhi[1] = 0; junzhi[2] = 0;
                //double j = 0;
                for (int i = 0; i < bytes; i += 3)
                {
                    junzhi[0] += grayValues[i];
                    junzhi[1] += grayValues[i + 1];
                    junzhi[2] += grayValues[i + 2];
                    // grayValues[i + 1] = 0;
                }
                junzhi[0] = junzhi[0] / bytes * 3;
                junzhi[1] = junzhi[1] / bytes * 3;
                junzhi[2] = junzhi[2] / bytes * 3;
                double[] var = new double[3];
                var[0] = 0; var[1] = 0; var[2] = 0;
                for (int i = 0; i < bytes; i += 3)
                {
                    var[0] += (grayValues[i] - junzhi[0]) * (grayValues[i] - junzhi[0]);
                    var[1] += (grayValues[i + 1] - junzhi[1]) * (grayValues[i + 1] - junzhi[1]);
                    var[2] += (grayValues[i + 2] - junzhi[2]) * (grayValues[i + 2] - junzhi[2]);
                    // grayValues[i + 1] = 0;
                }
                var[0] = var[0] / bytes * 3;
                var[1] = var[1] / bytes * 3;
                var[2] = var[2] / bytes * 3;
                for (int i = 0; i < bytes; i += 3)
                {
                    if (grayValues[i] > junzhi[0])
                    {
                        grayValues[i] = (byte)(150 + Math.Sqrt(2000 * (grayValues[i] - junzhi[0]) / var[0]));
                    }
                    else
                        grayValues[i] = (byte)(150 - Math.Sqrt(2000 * (junzhi[0] - grayValues[i]) / var[0]));
                    if (grayValues[i + 1] > junzhi[1])
                    {
                        grayValues[i + 1] = (byte)(150 + Math.Sqrt(2000 * (grayValues[i + 1] - junzhi[1]) / var[1]));
                    }
                    else
                        grayValues[i + 1] = (byte)(150 - Math.Sqrt(2000 * (junzhi[1] - grayValues[i + 1]) / var[1]));
                    if (grayValues[i + 2] > junzhi[2])
                    {
                        grayValues[i + 2] = (byte)(150 + Math.Sqrt(2000 * (grayValues[i + 2] - junzhi[2]) / var[2]));
                    }
                    else
                        grayValues[i + 2] = (byte)(150 - Math.Sqrt(2000 * (junzhi[2] - grayValues[i + 2]) / var[2]));
    
                }
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curbitmap.UnlockBits(bmpdata);
                Invalidate();
    
            }
        }
        Bitmap beijingmap;
        private void button9_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect,
                    System.Drawing.Imaging.ImageLockMode.ReadWrite, curbitmap.PixelFormat);
                IntPtr ptr = bmpdata.Scan0;
                int bytes = bmpdata.Stride * bmpdata.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
                //double colortemp = 0;
                int M = 3;
                int H = curbitmap.Height / 3;
                int L = curbitmap.Width / 3;
                double[,] av = new double[H, L];
                double[,] var = new double[H, L];
                double sav = 0;
                double svar = 0;
                //计算每一块的平均值
                for (int x = 1; x < H; x += 1)
                {
                    for (int y = 1; y < L; y += 1)
                    {
                        for (int i = 0; i < M; i++)
                        {
                            for (int j = 0; j < M; j++)
                            {
                                int X = i + (x - 1) * M;
                                int Y = j + (y - 1) * M;
                                sav += grayValues[X * bmpdata.Stride + Y * 3];
                            }
                        }
    
                        av[x, y] = sav / 9;
                        sav = 0;
                        for (int i = 0; i < M; i++)
                        {
                            for (int j = 0; j < M; j++)
                            {
                                int X = i + (x - 1) * M;
                                int Y = j + (y - 1) * M;
                                svar += (grayValues[X * bmpdata.Stride + Y * 3] - av[x, y]) * (grayValues[X * bmpdata.Stride + Y * 3] - av[x, y]);
                            }
                        }
                        var[x, y] = svar / 9;
                        svar = 0;
                    }
                }
                //所有块的平均值和方差
                double Gmean = 0;
                double Vmean = 0;
                for (int i = 0; i < H; i++)
                {
                    for (int j = 0; j < L; j++)
                    {
                        Gmean = Gmean + av[i, j];
                        Vmean += var[i, j];
                    }
                }
                double Gmean1 = Gmean / (H * L);
                double Vmean1 = Vmean / (H * L);
                double gtemp = 0;
                double gtotle = 0;
                double vtemp = 0;
                double vtotle = 0;
                for (int x = 0; x < H; x++)
                {
                    for (int y = 0; y < L; y++)
                    {
                        if (Gmean1 > av[x, y])
                        {
                            gtemp += 1;
                            gtotle += av[x, y];
                        }
                        if (Vmean1 < var[x, y])
                        {
                            vtemp += 1;
                            vtotle += var[x, y];
    
                        }
                    }
                }
                double G1 = gtotle / gtemp;
                double V1 = vtotle / vtemp;
    
    
                double gtemp1 = 0;
                double gtotle1 = 0;
                double vtemp1 = 0;
                double vtotle1 = 0;
                for (int x = 0; x < H; x++)
                {
                    for (int y = 0; y < L; y++)
                    {
                        if (G1 > av[x, y])
                        {
                            gtemp1 += 1;
                            gtotle1 += av[x, y];
                        }
                        if (0 < var[x, y] && var[x, y] < V1)
                        {
                            vtemp1 += 1;
                            vtotle1 += var[x, y];
    
                        }
                    }
                }
                double G2 = gtotle1 / gtemp1;
                double V2 = vtotle1 / vtemp1;
    
    
    
    
    
    
                //构建矩阵
                double[,] E = new double[H, L];
                for (int x = 0; x < H; x++)
                {
                    for (int y = 0; y < L; y++)
                    {
                        if (av[x, y] > G2 && var[x, y] < V2)
                        {
                            E[x, y] = 1;
                        }
                        if (av[x, y] < (G1 - 130) && var[x, y] < V2)
                        {
                            E[x, y] = 1;
                        }
                    }
                }
    
                for (int x = 1; x < H - 1; x++)
                {
                    for (int y = 1; y < L - 1; y++)
                    {
                        if (E[x, y] == 1)
                        {
                            if (E[x - 1, y] + E[x, y + 1] + E[x + 1, y + 1] + E[x - 1, y + 1] + E[x + 1, y] + E[x + 1, y - 1]
                                + E[x, y - 1] + E[x - 1, y - 1] <= 4)
                            {
                                E[x, y] = 0;
                            }
                        }
                    }
                }
                beijingmap = new Bitmap(curbitmap.Width, curbitmap.Height);
                for (int i = 0; i < beijingmap.Width; i++)
                {
                    for (int j = 0; j < beijingmap.Height; j++)
                    {
                        beijingmap.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                    }
                }
    
                for (int x = 1; x < H; x++)
                {
                    for (int y = 1; y < L; y++)
                    {
                        if (E[x, y] == 1)
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                for (int j = 0; j < 3; j++)
                                {
                                    int X = i + (x - 1) * M;
                                    int Y = j + (y - 1) * M;
                                    grayValues[X * bmpdata.Stride + Y * 3] = (byte)G1;
                                    grayValues[X * bmpdata.Stride + Y * 3 + 1] = (byte)G1;
                                    grayValues[X * bmpdata.Stride + Y * 3 + 2] = (byte)G1;
                                    beijingmap.SetPixel(Y, X, Color.FromArgb(1, 1, 1));
                                }
                            }
                        }
                    }
                }
    
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curbitmap.UnlockBits(bmpdata);
    
                Invalidate();
                beijingtu map = new beijingtu(beijingmap);
                map.Show();
    
            }
        }
    
        private void button2_Click(object sender, EventArgs e)
        {
            Graphics g = this.panel1.CreateGraphics();
            g.Clear(panel1.BackColor);
            curbitmap = null;
            g.Dispose();
        }
    
        private void button10_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect,
                    System.Drawing.Imaging.ImageLockMode.ReadWrite, curbitmap.PixelFormat);
                IntPtr ptr = bmpdata.Scan0;
                int bytes = bmpdata.Stride * bmpdata.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
                double colortemp = 0;
                for (int i = 0; i < bmpdata.Height; i += 1)
                {
                    for (int j = 0; j < bmpdata.Width; j += 1)
                    {
                        colortemp = grayValues[i * bmpdata.Stride + 3 * j + 2] * 0.299 + grayValues[i * bmpdata.Stride + 3 * j + 1] * 0.587 +
                            grayValues[i * bmpdata.Stride + 3 * j] * 0.114;
                        grayValues[i * bmpdata.Stride + 3 * j + 2] = grayValues[i * bmpdata.Stride + 3 * j + 1] = grayValues[i * bmpdata.Stride + 3 * j]
                            = (byte)colortemp;
                    }
                }
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curbitmap.UnlockBits(bmpdata);
                Invalidate();
    
            }
        }
    
        private void button11_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Convolution c = new Convolution();
                curbitmap = c.Smooth(curbitmap);
            }
        }
    
        private void button12_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curbitmap.Width, curbitmap.Height);
                System.Drawing.Imaging.BitmapData bmpdata = curbitmap.LockBits(rect,
                    System.Drawing.Imaging.ImageLockMode.ReadWrite, curbitmap.PixelFormat);
                IntPtr ptr = bmpdata.Scan0;
                int bytes = bmpdata.Stride * bmpdata.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                double[,] Gx = new double[bmpdata.Stride, curbitmap.Height];
                double[,] Gy = new double[bmpdata.Stride, curbitmap.Height];
                double[,] G = new double[bmpdata.Stride, curbitmap.Height];
                double colortemp = 0;
                for (int i = 1; i < bmpdata.Height - 1; i += 1)
                {
                    for (int j = 1; j < bmpdata.Width - 2; j += 1)
                    {
                        Gx[i, j] = (-1) * (grayValues[(i - 1) * bmpdata.Stride + 3 * (j - 1) + 2] + grayValues[(i - 1) * bmpdata.Stride + 3 * (j - 1) + 1] +
                            grayValues[(i - 1) * bmpdata.Stride + 3 * (j - 1)]) +
                            (1) * (grayValues[(i + 1) * bmpdata.Stride + 3 * (j - 1) + 2] + grayValues[(i + 1) * bmpdata.Stride + 3 * (j - 1) + 1] +
                            grayValues[(i + 1) * bmpdata.Stride + 3 * (j - 1)]) +
                        (-2) * (grayValues[(i - 1) * bmpdata.Stride + 3 * (j) + 2] + grayValues[(i - 1) * bmpdata.Stride + 3 * (j) + 1] +
                            grayValues[(i - 1) * bmpdata.Stride + 3 * (j)]) +
                             (2) * (grayValues[(i + 1) * bmpdata.Stride + 3 * (j) + 2] + grayValues[(i + 1) * bmpdata.Stride + 3 * (j) + 1] +
                            grayValues[(i + 1) * bmpdata.Stride + 3 * (j)]) +
                             (-1) * (grayValues[(i - 1) * bmpdata.Stride + 3 * (j + 1) + 2] + grayValues[(i - 1) * bmpdata.Stride + 3 * (j + 1) + 1] +
                            grayValues[(i - 1) * bmpdata.Stride + 3 * (j + 1)]) +
                             (1) * (grayValues[(i + 1) * bmpdata.Stride + 3 * (j + 1) + 2] + grayValues[(i + 1) * bmpdata.Stride + 3 * (j + 1) + 1] +
                            grayValues[(i + 1) * bmpdata.Stride + 3 * (j + 1)]);
    
                        Gy[i, j] = (1) * (grayValues[(i - 1) * bmpdata.Stride + 3 * (j - 1) + 2] + grayValues[(i - 1) * bmpdata.Stride + 3 * (j - 1) + 1] +
                            grayValues[(i - 1) * bmpdata.Stride + 3 * (j - 1)]) +
                            (2) * (grayValues[(i) * bmpdata.Stride + 3 * (j - 1) + 2] + grayValues[(i) * bmpdata.Stride + 3 * (j - 1) + 1] +
                            grayValues[(i) * bmpdata.Stride + 3 * (j - 1)]) +
                            (1) * (grayValues[(i + 1) * bmpdata.Stride + 3 * (j - 1) + 2] + grayValues[(i + 1) * bmpdata.Stride + 3 * (j - 1) + 1] +
                            grayValues[(i + 1) * bmpdata.Stride + 3 * (j - 1)]) +
                        0 * (grayValues[(i - 1) * bmpdata.Stride + 3 * (j) + 2] + grayValues[(i - 1) * bmpdata.Stride + 3 * (j) + 1] +
                            grayValues[(i - 1) * bmpdata.Stride + 3 * (j)]) +
                             0 * (grayValues[(i + 1) * bmpdata.Stride + 3 * (j) + 2] + grayValues[(i + 1) * bmpdata.Stride + 3 * (j) + 1] +
                            grayValues[(i + 1) * bmpdata.Stride + 3 * (j)]) +
                             (-1) * (grayValues[(i - 1) * bmpdata.Stride + 3 * (j + 1) + 2] + grayValues[(i - 1) * bmpdata.Stride + 3 * (j + 1) + 1] +
                            grayValues[(i - 1) * bmpdata.Stride + 3 * (j + 1)]) +
                             (-1) * (grayValues[(i + 1) * bmpdata.Stride + 3 * (j + 1) + 2] + grayValues[(i + 1) * bmpdata.Stride + 3 * (j + 1) + 1] +
                            grayValues[(i + 1) * bmpdata.Stride + 3 * (j + 1)]) +
                            (-2) * (grayValues[(i) * bmpdata.Stride + 3 * (j + 1) + 2] + grayValues[(i) * bmpdata.Stride + 3 * (j + 1) + 1] +
                            grayValues[(i) * bmpdata.Stride + 3 * (j + 1)]);
                         G[i,j] = Math.Atan2(Gy[i, j],Gx[i, j]);
                        grayValues[(i) * bmpdata.Stride + 3 * (j)  ] = (byte)G[i,j];
                        grayValues[(i) * bmpdata.Stride + 3 * (j) + 1] = (byte)G[i, j];
                        grayValues[(i) * bmpdata.Stride + 3 * (j) + 2] = (byte)G[i, j];
                        ;
                    }
                }
                double g = 0;double gy = 0;
                //for (int i = 1; i < bmpdata.Height - 1; i += 1)
                //{
                //    for (int j = 1; j < bmpdata.Width - 2; j += 1)
                //    {
                //        g += G[i, j];
                       
                //    }
                //}
                double jx = g / (bmpdata.Height - 1)/ (bmpdata.Width - 2);
                //double jy = gy / (bmpdata.Width - 2);
                for (int i = 1; i < bmpdata.Height - 1; i += 1)
                {
                    for (int j = 1; j < bmpdata.Width - 2; j += 1)
                    {
                        grayValues[(i) * bmpdata.Stride + 3 * (j)] = (byte)255;
                        grayValues[(i) * bmpdata.Stride + 3 * (j) + 1] = (byte)255;
                        grayValues[(i) * bmpdata.Stride + 3 * (j) + 2] = (byte)255;
                        if (G[i, j] <1)
                        {
                            grayValues[(i) * bmpdata.Stride + 3 * (j)] = (byte)0;
                            grayValues[(i) * bmpdata.Stride + 3 * (j) + 1] = (byte)0;
                            grayValues[(i) * bmpdata.Stride + 3 * (j) + 2] = (byte)0;
                        }
    
                    }
                }
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curbitmap.UnlockBits(bmpdata);
                Invalidate();
            }
        }
    
    
    
    
    
        private void Image_Test()
        {
            if (this.curbitmap != null)
            {
                
                int Height = curbitmap.Height;
                int Width = curbitmap.Width;
                Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
                Bitmap MyBitmap = curbitmap;
                BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); //原图
                BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);  //新图即边缘图
                unsafe
                {
                    //首先第一段代码是提取边缘,边缘置为黑色,其他部分置为白色
                    byte* pin_1 = (byte*)(oldData.Scan0.ToPointer());
                    byte* pin_2 = pin_1 + (oldData.Stride);
                    byte* pout = (byte*)(newData.Scan0.ToPointer());
                    double[,] R = new double[oldData.Height - 1, oldData.Width];
                    for (int y = 0; y < oldData.Height - 1; y++)
                    {
                        for (int x = 0; x < oldData.Width; x++)
                        {
                            //使用robert算子
                            double b = System.Math.Sqrt(((double)pin_1[0] - (double)(pin_2[0] + 3)) * ((double)pin_1[0] - (double)(pin_2[0] + 3)) + ((double)(pin_1[0] + 3) - (double)pin_2[0]) * ((double)(pin_1[0] + 3) - (double)pin_2[0]));
                            double g = System.Math.Sqrt(((double)pin_1[1] - (double)(pin_2[1] + 3)) * ((double)pin_1[1] - (double)(pin_2[1] + 3)) + ((double)(pin_1[1] + 3) - (double)pin_2[1]) * ((double)(pin_1[1] + 3) - (double)pin_2[1]));
                            double r = System.Math.Sqrt(((double)pin_1[2] - (double)(pin_2[2] + 3)) * ((double)pin_1[2] - (double)(pin_2[2] + 3)) + ((double)(pin_1[2] + 3) - (double)pin_2[2]) * ((double)(pin_1[2] + 3) - (double)pin_2[2]));
                            double bgr = b + g + r;//博主一直在纠结要不要除以3,感觉没差,选阈值的时候调整一下就好了- -
    
                            if (bgr > 80) //阈值,超过阈值判定为边缘(选取适当的阈值)
                            {
                                b = 0;
                                g = 0;
                                r = 0;
                            }
                            else
                            {
                                b = 255;
                                g = 255;
                                r = 255;
                            }
                            pout[0] = (byte)(b);
                            pout[1] = (byte)(g);
                            pout[2] = (byte)(r);
                            pin_1 = pin_1 + 3;
                            pin_2 = pin_2 + 3;
                            pout = pout + 3;
    
                        }
                        pin_1 += oldData.Stride - oldData.Width * 3;
                        pin_2 += oldData.Stride - oldData.Width * 3;
                        pout += newData.Stride - newData.Width * 3;
                    }
                    
                    bitmap.UnlockBits(newData);
                    MyBitmap.UnlockBits(oldData);
                    this.curbitmap = bitmap;
                }
    
            }
    
        }
    
        private void button13_Click(object sender, EventArgs e)
        {
            Image_Test();
        }
    
        private void button14_Click(object sender, EventArgs e)
        {
            curbitmap = ToThinner(curbitmap);
        }
        public unsafe Bitmap ToThinner(Bitmap srcImg)
        {
            int iw = srcImg.Width;
            int ih = srcImg.Height;
            bool bModified;     //二值图像修改标志            
            bool bCondition1;   //细化条件1标志            
            bool bCondition2;   //细化条件2标志            
            bool bCondition3;   //细化条件3标志            
            bool bCondition4;   //细化条件4标志
            int nCount;
            //5X5像素块            
            byte[,] neighbour = new byte[5, 5];
            //新建临时存储图像            
            Bitmap NImg = new Bitmap(iw, ih, srcImg.PixelFormat);
            bModified = true;
            //细化修改标志, 用作循环条件
            BitmapData dstData = srcImg.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, srcImg.PixelFormat);
            byte* data = (byte*)(dstData.Scan0);
            //将图像转换为0,1二值得图像; 
            int step = dstData.Stride;
            for (int i = 0; i < dstData.Height; i++)
            {
                for (int j = 0; j < dstData.Width * 3; j += 3)
                {
                    if (data[i * step + j] > 128)
                        //如果是白线条,只要将0改成1,将1改成0
                        data[i * step + j]
                            = data[i * step + j + 1]
                            = data[i * step + j + 2]
                            = 0;
                    else
                        data[i * step + j]
                            = data[i * step + j + 1]
                            = data[i * step + j + 2]
                            = 1;
                }
            }
    
            BitmapData dstData1 = NImg.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, NImg.PixelFormat);
            byte* data1 = (byte*)(dstData1.Scan0);
            int step1 = dstData1.Stride;
            //细化循环开始           
            while (bModified)
            {
                bModified = false;
                //初始化临时二值图像NImg                
                for (int i = 0; i < dstData1.Height; i++)
                {
                    for (int j = 0; j < dstData1.Width * 3; j++)
                    {
                        data1[i * step1 + j] = 0;
                    }
                }
                for (int i = 2; i < ih - 2; i++)
                {
                    for (int j = 6; j < iw * 3 - 6; j += 3)
                    {
                        bCondition1 = false;
                        bCondition2 = false;
                        bCondition3 = false;
                        bCondition4 = false;
                        if (data[i * step + j] == 0)
                            //若图像的当前点为白色,则跳过                           
                            continue;
                        for (int k = 0; k < 5; k++)
                        {
                            //取以当前点为中心的5X5块                           
                            for (int l = 0; l < 5; l++)
                            {
                                //1代表黑色, 0代表白色                             
                                //neighbour[k, l] = bw[i + k - 2, j + l - 2];         
                                //neighbour[k, l] = data[(i + k - 2) * step + (j + l - 2)];
                                neighbour[k, l] = data[(i + k - 2) * step + (j + l * 3 - 6)];
                            }
                        }
                        //(1)判断条件2<=n(p)<=6          
                        nCount = neighbour[1, 1] + neighbour[1, 2] + neighbour[1, 3] + neighbour[2, 1] + neighbour[2, 3] + neighbour[3, 1] + neighbour[3, 2] + neighbour[3, 3];
                        if (nCount >= 2 && nCount <= 6)
                            bCondition1 = true;
                        else
                        {
                            data1[i * step1 + j] = 1;
                            continue;
                            //跳过, 加快速度                       
                        }
                        //(2)判断s(p)=1                      
                        nCount = 0;
                        if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1)
                            nCount++;
                        if (neighbour[1, 3] == 0 && neighbour[1, 2] == 1)
                            nCount++;
                        if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1)
                            nCount++;
                        if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1)
                            nCount++;
                        if (neighbour[2, 1] == 0 && neighbour[3, 1] == 1)
                            nCount++;
                        if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1)
                            nCount++;
                        if (neighbour[3, 2] == 0 && neighbour[3, 3] == 1)
                            nCount++;
                        if (neighbour[3, 3] == 0 && neighbour[2, 3] == 1)
                            nCount++;
                        if (nCount == 1)
                            bCondition2 = true;
                        else
                        {
                            data1[i * step1 + j] = 1;
                            continue;
                        }
                        //(3)判断p0*p2*p4=0 or s(p2)!=1   
                        if (neighbour[2, 3] * neighbour[1, 2] * neighbour[2, 1] == 0)
                            bCondition3 = true;
                        else
                        {
                            nCount = 0;
                            if (neighbour[0, 2] == 0 && neighbour[0, 1] == 1)
                                nCount++;
                            if (neighbour[0, 1] == 0 && neighbour[1, 1] == 1)
                                nCount++;
                            if (neighbour[1, 1] == 0 && neighbour[2, 1] == 1)
                                nCount++;
                            if (neighbour[2, 1] == 0 && neighbour[2, 2] == 1)
                                nCount++;
                            if (neighbour[2, 2] == 0 && neighbour[2, 3] == 1)
                                nCount++;
                            if (neighbour[2, 3] == 0 && neighbour[1, 3] == 1)
                                nCount++;
                            if (neighbour[1, 3] == 0 && neighbour[0, 3] == 1)
                                nCount++;
                            if (neighbour[0, 3] == 0 && neighbour[0, 2] == 1)
                                nCount++;
                            if (nCount != 1)
                                //s(p2)!=1                              
                                bCondition3 = true;
                            else
                            {
                                data1[i * step1 + j] = 1;
                                continue;
                            }
                        }
                        //(4)判断p2*p4*p6=0 or s(p4)!=1    
                        if (neighbour[1, 2] * neighbour[2, 1] * neighbour[3, 2] == 0)
                            bCondition4 = true;
                        else
                        {
                            nCount = 0;
                            if (neighbour[1, 1] == 0 && neighbour[1, 0] == 1)
                                nCount++;
                            if (neighbour[1, 0] == 0 && neighbour[2, 0] == 1)
                                nCount++;
                            if (neighbour[2, 0] == 0 && neighbour[3, 0] == 1)
                                nCount++;
                            if (neighbour[3, 0] == 0 && neighbour[3, 1] == 1)
                                nCount++;
                            if (neighbour[3, 1] == 0 && neighbour[3, 2] == 1)
                                nCount++;
                            if (neighbour[3, 2] == 0 && neighbour[2, 2] == 1)
                                nCount++;
                            if (neighbour[2, 2] == 0 && neighbour[1, 2] == 1)
                                nCount++;
                            if (neighbour[1, 2] == 0 && neighbour[1, 1] == 1)
                                nCount++;
                            if (nCount != 1)//s(p4)!=1       
                                bCondition4 = true;
                        }
                        if (bCondition1 && bCondition2 && bCondition3 && bCondition4)
                        {
                            data1[i * step1 + j] = 0;
                            bModified = true;
                        }
                        else
                        {
                            data1[i * step1 + j] = 1;
                        }
                    }
                }
                // 将细化了的临时图像bw_tem[w,h]copy到bw[w,h],完成一次细化   
                for (int i = 2; i < ih - 2; i++)
                    for (int j = 2; j < iw * 3 - 2; j++)
                        data[i * step + j] = data1[i * step1 + j];
            }
            for (int i = 2; i < ih - 2; i++)
            {
                for (int j = 6; j < iw * 3 - 6; j += 3)
                {
                    if (data[i * step + j] == 1)
    
                        data[i * step + j]
                            = data[i * step + j + 1]
                            = data[i * step + j + 2]
                            = 0;
    
                    else
    
                        data[i * step + j]
                            = data[i * step + j + 1]
                            = data[i * step + j + 2]
                            = 255;
    
                }
            }
            srcImg.UnlockBits(dstData);
            NImg.UnlockBits(dstData1);
            return (srcImg);
        }
    
        private void button15_Click(object sender, EventArgs e)
        {
            Convolution c = new Convolution();
            this.curbitmap = c.kaiyunsuan(curbitmap);
        }
    
        private void button16_Click(object sender, EventArgs e)
        {
            Convolution c = new Convolution();
            this.curbitmap = c.expend(curbitmap);
        }
    
        private void button17_Click(object sender, EventArgs e)
        {
            Moravec m = new Moravec(curbitmap);
            m.Show();
    
        }
    }
    }
    moravec.cs:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace shuzituxiangchuli
    {
    public partial class Moravec : Form
    {
        public Bitmap curbitmap;
        public Moravec(Bitmap map)
        {
            this.curbitmap = map;
            InitializeComponent();
        }
    
        private void Moravec_Load(object sender, EventArgs e)
        {
    
           }
    
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            Graphics g = this.pictureBox1.CreateGraphics();
            int x, y;
            x = curbitmap.Width / 3;
            y = curbitmap.Height / 3;
            //while (x > this.pictureBox1.Width  && y > this.pictureBox1.Height )
            //{
            //    x = x / 2;
            //    y = y / 2;
            //}
            g.DrawImage(curbitmap, 0, 0, x, y);
    
        }
    
        public double[,]  gethuiduzhi(Bitmap map)
        {
            double[,] huiduzhi = new double[map.Width, map.Height];
            int w = map.Width;
            int h = map.Height;
            for (int i = 0; i < w; i++)
            {
                for (int j = 0; j < h; j++)
                {
                    Color c = map.GetPixel(i, j);
                    huiduzhi[i, j] = c.R * 0.299 + c.G * 0.587 + c.B * 0.114;
                }
            }
            return huiduzhi;
    
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            if (curbitmap != null)
            {
                progressBar1.Visible = true;
                progressBar1.Maximum = 7;
                progressBar1.Value = 0;
                progressBar1.Step = 1;
                double[,] huidu = new double[this.curbitmap.Width, this.curbitmap.Height];
                huidu = gethuiduzhi(curbitmap);
                progressBar1.Value += progressBar1.Step;
                int w = curbitmap.Width;
                int h = curbitmap.Height;
    
                double[,] xingquzhi = new double[w,h];
                for (int i = 2; i < w - 2; i++)
                {
                    for (int j = 2; j < h - 2; j++)
                    {
                        double V1 = 0;
                        for (int m = 0; m < 4; m++)
                        {
                            V1 += Math.Pow(huidu[i - 2 + m, j] - huidu[i - 1 + m, j], 2);
    
                        }
                        double V2 = 0;
                        for (int m = 0; m < 4; m++)
                        {
                            V2 += Math.Pow(huidu[i - 2 + m, j - 2 + m] - huidu[i - 1 + m, j - 1 + m], 2);
    
                        }
                        double V3 = 0;
                        for (int m = 0; m < 4; m++)
                        {
                            V3 += Math.Pow(huidu[i, j - 2 + m] - huidu[i, j - 1 + m], 2);
    
                        }
                        double V4 = 0;
                        for (int m = 0; m < 4; m++)
                        {
                            V4 += Math.Pow(huidu[i - 2 + m, j + 2 - m] - huidu[i - 1 + m, j + 1 - m], 2);
                        }
    
                        xingquzhi[i, j] = Math.Min(Math.Min(Math.Min(V1, V2), V3), V4);
                    }
                }
                progressBar1.Value += progressBar1.Step;
                double sum = 0;
                for (int i = 0; i < w ; i++)
                {
                    for (int j =0 ; j < h; j++)
                    {
                        sum += xingquzhi[i, j];
    
                    }
                }
                double pingjun = sum / ((w) * (h ));
                progressBar1.Value += progressBar1.Step;
                int houxuan = 0;
                int c = 10001;
                double zeng = 1;
    
                int[,] tezhengzhi = new int[houxuan, 2];
                while (c>10000)
                {
                    c = 0;
                    double yuzhi = pingjun * zeng;
                    double[,] jianding = new double[w, h];
                    for (int i=2;i<w-2;i++)
                    {
                        for (int j=2;j<h-2;j++)
                        {
                            if(xingquzhi[i,j]<=yuzhi)
                            {
                                jianding[i, j] = 0;
    
                            }
                            else
                            {
                                jianding[i, j] = 1;
                                houxuan++;
                            }
                        }
                    }
                    int [,]tezhengzhi1 = new int[houxuan, 2];
                    int yuzhimuban = 5;
                    int mubanbanchaung = 2;
                    for(int i=mubanbanchaung;i<w-mubanbanchaung;i=i+1)
                    {
                        for(int j=mubanbanchaung;j<h-mubanbanchaung;j++)
                        {
                            double MAX = 0;
                            int a = 0;
                            int b = 0;
                            for(int m=0;m<yuzhimuban;m++)
                            {
                                for (int n=0;n<yuzhimuban;n++)
                                {
                                    if(jianding[i-mubanbanchaung+m,j-mubanbanchaung+n]==1)
                                    {
                                        if(MAX<xingquzhi[i-mubanbanchaung+m,j-mubanbanchaung+n])
                                        {
                                            MAX = xingquzhi[i - mubanbanchaung + m, j - mubanbanchaung + n];
                                            a = i - mubanbanchaung + m;
                                            b = j - mubanbanchaung + n;
    
                                        }
                                    }
                                    else
                                    {
                                        a = 0;b = 0;
                                    }
                                }
                            }
                            if((a!=0)&&(b!=0)&&jianding[i,j]==1)
                            {
                                tezhengzhi1[c, 0] = a;
                                tezhengzhi1[c, 1] = b;
                                c++;
    
                            }
    
                        }
                    }
                    tezhengzhi = tezhengzhi1;
                    zeng=zeng+1;
    
                }
                progressBar1.Value += progressBar1.Step;
                progressBar1.Value += progressBar1.Step;
                int[,] tezhengzhi2 = new int[c,2];
                tezhengzhi2 = tezhengzhi;
               
    
                Graphics g = this.pictureBox2.CreateGraphics();
                int x, y;
                x = curbitmap.Width/3;
                y = curbitmap.Height/3;
                //while (x > this.pictureBox1.Width && y > this.pictureBox1.Height)
                //{
                //    x = x / 2;
                //    y = y / 2;
                //}
                g.DrawImage(curbitmap, 0, 0, x, y);
                progressBar1.Value += progressBar1.Step;
                Pen p = new Pen(Color.Red);
                for(int i=0;i<c;i++)
                {
                    
                    
                   x = tezhengzhi2[i, 0]/3;
                    y = tezhengzhi2[i, 1]/3;
                    g.DrawLine(p, x - 5, y, x + 5, y);
                    g.DrawLine(p, x , y-5, x , y+5);
                }
                progressBar1.Value += progressBar1.Step;
               // progressBar1.Visible = false;
                g.Dispose();
            }
        }
    
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
    
        }
    }
    }

全部评论 (0)

还没有任何评论哟~