基于C#的眼部瞳孔追踪 与 双图片融合成像

版权声明:欢迎转载与留言提问 https://blog.csdn.net/qq_25439417/article/details/82700801

前期我们先用画饼充饥的方法来做研发与测试

手动画人眼

测试算法

蓝线中心点为瞳孔中心,可以看到比较准。

具体代码如下:

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;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        Point p = new Point();
        static Bitmap b;
        int h;
        int w;
        Bitmap b1;
        BitmapData bd;
        BitmapData bd1;
        public Form1()
        {
            InitializeComponent();
            this.Show();
            String s = "";
            b = null;
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                s = ofd.FileName;
                b = (Bitmap)Bitmap.FromFile(s, false);

                int[] point = getdivimg(b);
                try
                {
                    //Bitmap bmp = new Bitmap(b.Width, b.Height, PixelFormat.Format32bppArgb);
                    MessageBox.Show(point[0] + "---" + point[1]);
                    p.X = point[1];
                    p.Y = point[0];
                    this.pictureBox1.Load(s);
                    //g = Graphics.FromImage(bmp);
                    //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    //g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    //Image img = Image.FromFile(s);
                    //g.DrawImage(img, 0, 0);
                    pictureBox1.Refresh();
                    //g.FillEllipse(Brushes.Red, 0, 0, 100, 100);
                    ////this.pictureBox1.Image = img;
                    //g.Dispose();
                }
                catch (Exception e1)
                {
                    MessageBox.Show(e1.Message);
                }
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Show();
           
        }

        public void setgray(Bitmap b)
        {
            ColorPalette cp = b.Palette;
            for (int i = 0; i < 256; i++)
            {
                cp.Entries[i] = Color.FromArgb(i, i, i);
            }
            b.Palette = cp;
        }

        public int[] getdivimg(Bitmap b)
        {
            h = b.Height;
            w = b.Width;
            Rectangle rect = new Rectangle(0, 0, w, h);
            bd = b.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
            
            b1 = new Bitmap(b.Width, b.Height, PixelFormat.Format8bppIndexed);
            bd1 = b1.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            int len = bd.Stride * h;
            byte[] imgbyte = new byte[len];
            Marshal.Copy(bd.Scan0, imgbyte, 0, len);
            int i = 0;
            int j = 0;
            int[] hist = new int[256];
            int maxgray = 0;
            int maxpos = 0;
            int bogugray = 0;
            int bogupos = 0;
            try
            {
                for (i = 0; i < h; i++)
                {
                    for (j = 0; j < w; j++)
                    {
                        int t = imgbyte[i * bd.Stride + j];
                        hist[t]++;
                        if (hist[t] > maxgray)
                        {
                            maxgray = hist[t];
                            maxpos = t;
                        }
                    }
                }

                bogugray = maxgray;
                for (int k = 9; k < maxpos; k++)
                {
                    if (hist[k] < bogugray)
                    {
                        bogugray = hist[k];
                        bogupos = k;
                    }
                }

                int[] apoint = getcenterpoint(imgbyte, 0, h, 0, w, bogupos);
                MessageBox.Show(apoint[0] + "---" + apoint[1]);
                int[] point = getcenterpoint(imgbyte, apoint[0] - 100, apoint[0] + 100, apoint[1] - 100, apoint[1] + 100, bogupos);
                MessageBox.Show(point[0] + "---" + point[1]);

                return point;

            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
                return null;
            }
        }
        double r;
        public int[] getcenterpoint(byte[] imgbyte, int xstart = 0, int xend = 378, int ystart = 0, int yend = 681, int thresh=0)
        {
            
            if(xstart < 0)
                xstart=0;
            if (xend > h)
                xend = h;
            if (ystart < 0)
                ystart = 0;
            if (yend > w)
                yend = w;
            bool firstpoint = false;
            int firstx = 0;
            int firsty = 0;
            int xpossum = 0, ypossum = 0, count = 0;
            for (int i = xstart; i < xend; i++)
            {
                for (int j = ystart; j < yend; j++)
                {
                    //Console.WriteLine(i * bd.Stride + j);
                    int t = imgbyte[i * bd.Stride + j];
                    if (t <= thresh)
                    {
                        if (!firstpoint) {
                            firstx = i;
                            firsty = j;
                            firstpoint = true;
                        }
                        imgbyte[i * bd.Stride + j] = (byte)0;
                        xpossum += i;
                        ypossum += j;
                        count++;
                    }
                    else
                    {
                        imgbyte[i * bd.Stride + j] = (byte)255;
                    }
                }
            }
            //b.UnlockBits(bd);
            int[] point = new int[2];
            point[0] = xpossum / count;
            point[1] = ypossum / count;
            r = Math.Sqrt(Math.Abs(firstx - point[0]) * Math.Abs(firstx - point[0]) + Math.Abs(firsty - point[1]) * Math.Abs(firsty - point[1]));
            Console.WriteLine(r);
            return point;
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
        {
          Pen pen=new Pen (Color .Blue,50);
          Point q = new Point(p.X + 1, p.Y + 1);
          e.Graphics.DrawLine(pen, p, q);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}

那么对真实人眼准不准呢


接下来是读入两副眼睛图片并做拼接融合

上面是先用picturebox做的伪融合,真正的融合需要在内存地址中融合,用到Marshal

伪融合代码:

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;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        Point p = new Point();
        Point p2 = new Point();
        static Bitmap b;
        static Bitmap b2;
        int h;
        int w;
        Bitmap b1;
        BitmapData bd;
        BitmapData bd1;
        public Form1()
        {
            InitializeComponent();
            this.Show();
            String s = "";
            b = null;
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                s = ofd.FileName;
                b = (Bitmap)Bitmap.FromFile(s, false);

                int[] point = getdivimg(b);
                try
                {
                    //Bitmap bmp = new Bitmap(b.Width, b.Height, PixelFormat.Format32bppArgb);
                    MessageBox.Show(point[0] + "---" + point[1]);
                    p.X = point[1];
                    p.Y = point[0];
                    this.pictureBox1.Load(s);
                    //g = Graphics.FromImage(bmp);
                    //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    //g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    //Image img = Image.FromFile(s);
                    //g.DrawImage(img, 0, 0);
                    pictureBox1.Refresh();
                    //g.FillEllipse(Brushes.Red, 0, 0, 100, 100);
                    ////this.pictureBox1.Image = img;
                    //g.Dispose();
                }
                catch (Exception e1)
                {
                    MessageBox.Show(e1.Message);
                }
            }
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                s = ofd.FileName;
                b2 = (Bitmap)Bitmap.FromFile(s, false);

                int[] point = getdivimg(b2);
                try
                {
                    //Bitmap bmp = new Bitmap(b.Width, b.Height, PixelFormat.Format32bppArgb);
                    MessageBox.Show(point[0] + "---" + point[1]);
                    p2.X = point[1];
                    p2.Y = point[0];
                    this.pictureBox2.Load(s);
                    //g = Graphics.FromImage(bmp);
                    //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    //g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    //Image img = Image.FromFile(s);
                    //g.DrawImage(img, 0, 0);
                    pictureBox2.Refresh();
                    //g.FillEllipse(Brushes.Red, 0, 0, 100, 100);
                    ////this.pictureBox1.Image = img;
                    //g.Dispose();
                }
                catch (Exception e1)
                {
                    MessageBox.Show(e1.Message);
                }
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Show();
           
        }

        public void setgray(Bitmap b)
        {
            ColorPalette cp = b.Palette;
            for (int i = 0; i < 256; i++)
            {
                cp.Entries[i] = Color.FromArgb(i, i, i);
            }
            b.Palette = cp;
        }

        public int[] getdivimg(Bitmap b)
        {
            h = b.Height;
            w = b.Width;
            Rectangle rect = new Rectangle(0, 0, w, h);
            bd = b.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
            
            b1 = new Bitmap(b.Width, b.Height, PixelFormat.Format8bppIndexed);
            bd1 = b1.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            int len = bd.Stride * h;
            byte[] imgbyte = new byte[len];
            Marshal.Copy(bd.Scan0, imgbyte, 0, len);
            int i = 0;
            int j = 0;
            int[] hist = new int[256];
            int maxgray = 0;
            int maxpos = 0;
            int bogugray = 0;
            int bogupos = 0;
            try
            {
                for (i = 0; i < h; i++)
                {
                    for (j = 0; j < w; j++)
                    {
                        int t = imgbyte[i * bd.Stride + j];
                        hist[t]++;
                        if (hist[t] > maxgray)
                        {
                            maxgray = hist[t];
                            maxpos = t;
                        }
                    }
                }

                bogugray = maxgray;
                for (int k = 9; k < maxpos; k++)
                {
                    if (hist[k] < bogugray)
                    {
                        bogugray = hist[k];
                        bogupos = k;
                    }
                }

                int[] apoint = getcenterpoint(imgbyte, 0, h, 0, w, bogupos);
                MessageBox.Show(apoint[0] + "---" + apoint[1]);
                int[] point = getcenterpoint(imgbyte, apoint[0] - 100, apoint[0] + 100, apoint[1] - 100, apoint[1] + 100, bogupos);
                MessageBox.Show(point[0] + "---" + point[1]);

                return point;

            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
                return null;
            }
        }
        double r;
        public int[] getcenterpoint(byte[] imgbyte, int xstart = 0, int xend = 378, int ystart = 0, int yend = 681, int thresh=0)
        {
            
            if(xstart < 0)
                xstart=0;
            if (xend > h)
                xend = h;
            if (ystart < 0)
                ystart = 0;
            if (yend > w)
                yend = w;
            bool firstpoint = false;
            int firstx = 0;
            int firsty = 0;
            int xpossum = 0, ypossum = 0, count = 0;
            for (int i = xstart; i < xend; i++)
            {
                for (int j = ystart; j < yend; j++)
                {
                    //Console.WriteLine(i * bd.Stride + j);
                    int t = imgbyte[i * bd.Stride + j];
                    if (t <= thresh)
                    {
                        if (!firstpoint) {
                            firstx = i;
                            firsty = j;
                            firstpoint = true;
                        }
                        imgbyte[i * bd.Stride + j] = (byte)0;
                        xpossum += i;
                        ypossum += j;
                        count++;
                    }
                    else
                    {
                        imgbyte[i * bd.Stride + j] = (byte)255;
                    }
                }
            }
            //b.UnlockBits(bd);
            int[] point = new int[2];
            point[0] = xpossum / count;
            point[1] = ypossum / count;
            r = Math.Sqrt(Math.Abs(firstx - point[0]) * Math.Abs(firstx - point[0]) + Math.Abs(firsty - point[1]) * Math.Abs(firsty - point[1]));
            Console.WriteLine(r);
            return point;
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Blue, 50);
            Point q = new Point(p.X, p.Y + 1);
            e.Graphics.DrawLine(pen, p, q);
            Point q2 = new Point(p.X, p.Y - 1);
            e.Graphics.DrawLine(pen, p, q2);
            Point q3 = new Point(p.X+1, p.Y );
            e.Graphics.DrawLine(pen, p, q3);
            Point q4 = new Point(p.X-1, p.Y);
            e.Graphics.DrawLine(pen, p, q4);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox2_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Blue, 50);
            Point q = new Point(p2.X, p2.Y + 1);
            e.Graphics.DrawLine(pen, p2, q);
            Point q2 = new Point(p2.X, p2.Y - 1);
            e.Graphics.DrawLine(pen, p2, q2);
            Point q3 = new Point(p2.X + 1, p2.Y);
            e.Graphics.DrawLine(pen, p2, q3);
            Point q4 = new Point(p2.X - 1, p2.Y);
            e.Graphics.DrawLine(pen, p2, q4);
        }
    }
}

真正融合代码:

在自己开发的程序中,初次尝试byte上的融合

出现了这种情况

右边为融合之后的,出现了间隔栅格+噪声


做了一些调试以后,感觉问题应该是在于 变量没上锁,变量还没进入 就被读出,所以会产生噪声和黑色蒙版

尝试在变量上加锁

猜你喜欢

转载自blog.csdn.net/qq_25439417/article/details/82700801