国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#開發的人臉左右相似度計算軟件源碼分析

2020-01-24 01:57:00
字體:
來源:轉載
供稿:網友

本文實例講述了C#開發的人臉左右相似度計算軟件。分享給大家供大家參考。具體分析如下:

模仿湖南衛視快樂大本營中所使用的一款人臉左右對稱相似度計算軟件,自己寫的一個小軟件,使用語言是C#,希望跟喜歡這個軟件的同志們共享!

1. FaceClass類程序

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;using System.Drawing.Drawing2D;namespace FaceSmile{ class FaceClass {  /// <summary>  /// 左臉對稱函數  /// </summary>  /// <param name="a"></param>  /// <returns></returns>  public static Bitmap FaceFlipLeft(Bitmap a)  {   Rectangle rect = new Rectangle(0, 0, a.Width, a.Height);   System.Drawing.Imaging.BitmapData srcData = a.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, a.PixelFormat);   IntPtr ptr = srcData.Scan0;   int bytes = 0;   bytes = srcData.Stride * a.Height;   byte[] grayValues = new byte[bytes];   System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);   byte[] temp = new byte[bytes];   temp = (byte[])grayValues.Clone();   for (int j = 0; j < a.Height; j++)   {    for (int i = 0; i < (int)(a.Width/2); i++)    {     temp[(a.Width - 2 - i) * 3 + j * srcData.Stride] = temp[i * 3 + j * srcData.Stride];     temp[(a.Width - 2 - i) * 3 + 1 + j * srcData.Stride] = temp[i * 3 + 1 + j * srcData.Stride];     temp[(a.Width - 2 - i) * 3 + 2 + j * srcData.Stride] = temp[i * 3 + 2 + j * srcData.Stride];    }   }   grayValues = (byte[])temp.Clone();    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);   a.UnlockBits(srcData);   return a;  }  /// <summary>  /// 右臉對稱函數  /// </summary>  /// <param name="a"></param>  /// <returns></returns>  public static Bitmap FaceFlipRight(Bitmap a)  {   Rectangle rect = new Rectangle(0, 0, a.Width, a.Height);   System.Drawing.Imaging.BitmapData srcData = a.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, a.PixelFormat);   IntPtr ptr = srcData.Scan0;   int bytes = 0;   bytes = srcData.Stride * a.Height;   byte[] grayValues = new byte[bytes];   System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);   byte[] temp = new byte[bytes];   temp = (byte[])grayValues.Clone();   for (int j = 0; j < a.Height; j++)   {    for (int i = 0; i < (int)(a.Width / 2); i++)    {     temp[i * 3 + j * srcData.Stride] = temp[(a.Width - 2 - i) * 3 + j * srcData.Stride];     temp[i * 3 + 1 + j * srcData.Stride] = temp[(a.Width - 2 - i) * 3 + 1 + j * srcData.Stride];     temp[i * 3 + 2 + j * srcData.Stride] = temp[(a.Width - 2 - i) * 3 + 2 + j * srcData.Stride];    }   }   grayValues = (byte[])temp.Clone();   System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);   a.UnlockBits(srcData);   return a;  }  /// <summary>  /// 定義膚色檢測函數  /// </summary>  /// <param name="a"></param>  /// <returns></returns>  public static Bitmap SkinDetect(Bitmap a)  {   Rectangle rect = new Rectangle(0, 0, a.Width, a.Height);   System.Drawing.Imaging.BitmapData bmpData = a.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);   int stride = bmpData.Stride;   unsafe   {    byte* pIn = (byte*)bmpData.Scan0.ToPointer();    byte* P;    int R, G, B;    double r, g, Fupr, Flor, Wrg;    for (int y = 0; y < a.Height; y++)    {     for (int x = 0; x < a.Width; x++)     {      P = pIn;      B = P[0];      G = P[1];      R = P[2];      if (R + G + B == 0)      {       r = 0;       g = 0;      }      else      {       r = (R / (R + G + B));       g = (G / (R + G + B));      }      Fupr = (1.0743 * r + 0.1452 - 1.3767 * r * r);      Flor = (0.5601 * r + 0.1766 - 0.776 * r * r);      Wrg = (r - 0.33) * (r - 0.33) + (g - 0.33) * (g - 0.33);      if ((R - G >= 45) && ((R > G) && (G > B)) && (Fupr > g) && (Wrg >= 0.0004))      {       P[0] = (byte)B;       P[1] = (byte)G;       P[2] = (byte)R;      }      else      {       P[0] = 0;       P[1] = 0;       P[2] = 0;      }      pIn += 3;     }     pIn += stride - a.Width * 3;    }   }   a.UnlockBits(bmpData);   return a;  }  /// <summary>  /// 定義圖像灰度化函數  /// </summary>  /// <param name="src"></param>  /// <returns></returns>  public static Bitmap ImageGray(Bitmap src)  {   int w = src.Width;   int h = src.Height;   //構建與原圖像大小一樣的模版圖像   Bitmap dstBitmap = new Bitmap(src.Width, src.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);   //將原圖像存入內存   System.Drawing.Imaging.BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);   System.Drawing.Imaging.BitmapData dstData = dstBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);   unsafe   {    byte* pIn = (byte*)srcData.Scan0.ToPointer();    byte* pOut = (byte*)dstData.Scan0.ToPointer();    byte* p;    int stride = srcData.Stride;    int r, g, b;    for (int y = 0; y < h; y++)    {     for (int x = 0; x < w; x++)     {      p = pIn;      r = p[2];      g = p[1];      b = p[0];      //調用圖像灰度化公式      pOut[0] = pOut[1] = pOut[2] = (byte)(b * 0.114 + g * 0.587 + r * 0.299);      pIn += 3;      pOut += 3;     }     pIn += srcData.Stride - w * 3;     pOut += srcData.Stride - w * 3;    }    src.UnlockBits(srcData);    dstBitmap.UnlockBits(dstData);    return dstBitmap;   }  } }}

2. SameRatioClass類程序

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;using System.Drawing.Drawing2D;namespace FaceSmile{ class SameRatioClass {  /// <summary>  /// 左右臉相似度函數  /// </summary>  /// <param name="src"></param>  /// <param name="dst"></param>  /// <returns></returns>  public static double SameRatio(Bitmap src, Bitmap dst)  {   byte[] srcData = GetBytes(src);   byte[] dstData = GetBytes(dst);   double ratio = 0;   int sum = 0;   int std=0;   for (int i = 0; i < srcData.Length; i++)   {    sum += Math.Abs(srcData[i] - dstData[i]);    std += srcData[i];   }   ratio = 100-(double)(100*sum / std);   return ratio;  }  /// <summary>  /// 得到圖像信息函數  /// </summary>  /// <param name="src"></param>  /// <returns></returns>  private static byte[] GetBytes(Bitmap src)  {   int w = src.Width;   int h = src.Height;   byte[] dataImage = new byte[w * h];   System.Drawing.Imaging.BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);      unsafe   {    byte* pIn = (byte*)srcData.Scan0.ToPointer();        byte* p;    int stride = srcData.Stride;    int r, g, b;    for (int y = 0; y < h; y++)    {     for (int x = 0; x < w; x++)     {      p = pIn;      r = p[2];      g = p[1];      b = p[0];      dataImage[x + y * x] = (byte)((r + g + b) / 3);      pIn += 3;           }     pIn += srcData.Stride - w * 3;         }    src.UnlockBits(srcData);    return dataImage;   }  } }}

3. 主窗體程序

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace FaceSmile{ public partial class Form1 : Form {  public Form1()  {   InitializeComponent();   groupBox1.Visible = true;   groupBox2.Visible = false;  }  #region 全局變量定義  //定義原始圖像變量  private Bitmap src ;  //定義圖像相似度變量  private double ratio = 0;  //定義圖像路徑變量  private string curFileName;  //定義人臉位置圖像調整變量  private int numAdjust = 0;  #endregion  #region 軟件操作  //左臉對稱  private void button1_Click(object sender, EventArgs e)  {   if (src != null)   {    Bitmap temp = (Bitmap)src.Clone();    Bitmap a = FaceClass.FaceFlipLeft(temp);    pictureBox1.Image = (Image)a;    ratio = SameRatioClass.SameRatio(a, src);    label1.Text = ratio.ToString();   }   else   {    MessageBox.Show("Please open one image!");   }  }  //右臉對稱  private void button2_Click(object sender, EventArgs e)  {   if (src != null)   {    Bitmap temp = (Bitmap)src.Clone();    Bitmap a = FaceClass.FaceFlipRight(temp);    pictureBox1.Image = (Image)a;    ratio = SameRatioClass.SameRatio(a, src);    label1.Text = ratio.ToString();   }   else   {    MessageBox.Show("Please open one image!");   }  }  //打開圖像  private void button3_Click(object sender, EventArgs e)  {   OpenImage();   if (src != null)   {    pictureBox1.Image = (Image)src;    pictureBox1.Width = src.Width;    pictureBox1.Height = src.Height;   }   else   {    MessageBox.Show("Please open one image!");   }  }  //保存圖像  private void button4_Click(object sender, EventArgs e)  {   SaveImage();  }  //圖像打開函數  private void OpenImage()  {   try   {    ofd.Filter = "All files (*.*)|*.*|bmp files (*.bmp)|*.bmp|jpeg files (*.jpg)|*.jpg|png files (*.png)|*.png";    ofd.Title = "打開";    ofd.ShowHelp = true;    if (ofd.ShowDialog() == DialogResult.OK)    {     curFileName = ofd.FileName;     src = new Bitmap(curFileName);    }   }   catch (Exception ex)   {    MessageBox.Show(ex.Message);   }  }  //圖像保存函數  private void SaveImage()  {   try   {    sfd.Filter = "保存(*.bmp)|*.bmp";    sfd.Title = "保存";    sfd.ShowHelp = true;    if (sfd.ShowDialog() == DialogResult.OK)    {     Bitmap temp = (Bitmap)pictureBox1.Image;     temp.Save(sfd.FileName, System.Drawing.Imaging.ImageFormat.Bmp);    }   }   catch (Exception ex)   {    MessageBox.Show(ex.Message);   }  }  //其他操作  private void button5_Click(object sender, EventArgs e)  {   groupBox2.Location = new Point(groupBox1.Location.X, groupBox1.Location.Y);   groupBox2.Visible = true;   groupBox1.Visible = false;  }  //膚色檢測  private void button6_Click(object sender, EventArgs e)  {   if (pictureBox1.Image != null)   {    pictureBox1.Image = (Image)FaceClass.SkinDetect((Bitmap)pictureBox1.Image);   }   else   {    MessageBox.Show("Please open one image!");   }  }  //返回操作  private void button7_Click(object sender, EventArgs e)  {   groupBox1.Visible = true;   groupBox2.Visible = false;  }  //灰度化  private void button8_Click(object sender, EventArgs e)  {   if (pictureBox1.Image != null)   {    pictureBox1.Image = (Image)FaceClass.ImageGray((Bitmap)pictureBox1.Image);   }   else   {    MessageBox.Show("Please open one image!");   }  }  //博客連接  private void label2_Click(object sender, EventArgs e)  {   System.Diagnostics.Process.Start("IEXPLORE.EXE", "http://dongtingyueh.blog.163.com/");  }  //修正人臉位置  private void button9_Click(object sender, EventArgs e)  {   if (numAdjust != 0)   {    int a = numAdjust;    int b = src.Width - a;    int result = a < b ? a : b;    if (result == b)    {     src = src.Clone(new Rectangle(src.Width - 2 * result, 0, 2 * result, src.Height), src.PixelFormat);    }    else    {     src = src.Clone(new Rectangle(0, 0, 2 * result, src.Height), src.PixelFormat);    }    pictureBox1.Image = (Image)src;    pictureBox1.Width = src.Width;    pictureBox1.Height = src.Height;   }   trackBar1.Value = 0;   label4.Text = "0";  }  #endregion  #region 人臉位置修正  private void trackBar1_Scroll(object sender, EventArgs e)  {   if (src != null)   {    trackBar1.Maximum = src.Width;    trackBar1.Minimum = 0;    numAdjust = trackBar1.Value;    label4.Text = numAdjust.ToString();   }   else   {    MessageBox.Show("Please open one image!");   }  }  private void trackBar1_ValueChanged(object sender, EventArgs e)  {   pictureBox1.Invalidate();  }  private void trackBar1_MouseUp(object sender, MouseEventArgs e)  {   if (src != null)   {    Graphics g = pictureBox1.CreateGraphics();    g.DrawLine(new Pen(Color.Red, 2), new Point((int)(numAdjust), 0), new Point((int)(numAdjust), src.Height));    g.Dispose();   }   else   {    MessageBox.Show("Please open one image!");   }  }  #endregion }}

希望本文所述對大家的C#程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲麻莱县| 喀喇沁旗| 拜城县| 循化| 南木林县| 平凉市| 天水市| 常德市| 通道| 靖江市| 金川县| 前郭尔| 博客| 都江堰市| 石景山区| 武川县| 伊春市| 澳门| 凤台县| 双流县| 烟台市| 达拉特旗| 定结县| 济源市| 太原市| 天门市| 吐鲁番市| 潍坊市| 邵东县| 建水县| 东乌珠穆沁旗| 买车| 大连市| 中阳县| 东山县| 福清市| 安国市| 长宁县| 莲花县| 都匀市| 义乌市|