Face Image Size

顔の画像をサイズを整えて保存します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. 顔画像の識別は、画像から目立った特徴を抽出することで識別します。
    パーツの相対位置や大きさ、目や鼻やほお骨やあごの形を特徴として利用します。
    最初のステップとして入力した顔の画像(カラー画像)を、鼻の頭を中心に 256×256 のサイズで保存します。
  2. サイズを整えて保存する image.cs のソースコードです。
    テンプレートのプロジェクトは Image Guid を参照して下さい。
    //★ 顔画像のサイズを整える    前田 稔
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Imaging;
    
    public class MyForm : Form
    {
        Bitmap  bmp;
        Bitmap  mark;
        string  ImgFile = "";
        int     x0=0, y0=0, x1=0, y1=0;
    
        public MyForm()
        {
            Text = "画像のサイズを整える";
            BackColor = SystemColors.AppWorkspace;
    
            OpenFileDialog opendlg = new OpenFileDialog();
            opendlg.Filter = "画像ファイル (*.bmp)|*.bmp|すべてのファイル (*.*)|*.*" ;
            if (opendlg.ShowDialog() == DialogResult.OK)
            {   ImgFile = opendlg.FileName;  }
    
            try
            {   bmp = new Bitmap(ImgFile);  }
            catch
            {   MessageBox.Show("画像ファイルが読めません!", ImgFile);
                return ;
            }
    
            mark = new Bitmap("C:\\DATA\\Test\\mark.gif");
            Width = bmp.Width;
            Height = bmp.Height+32;
            Paint += new PaintEventHandler(MyHandler);
            MouseDown += new MouseEventHandler(OnMyMouseDown);
            FormClosing += new FormClosingEventHandler(Form_Closing); 
        }
    
        private void MyHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawImage(bmp, new Point(0,0));
            if (x0!=0)  g.DrawImage(mark, new Point(x0,y0));
            if (x1!=0)  g.DrawImage(mark, new Point(x1,y1));
        }
    
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {   if (x1!=0)
            {   x0=y0=x1=y1= 0;
                Invalidate();
                return;
            }
            if (x0==0)
            {   x0= e.X;
                y0= e.Y;
                Invalidate();
                return;
            }
            x1= e.X;
            y1= e.Y;
            Invalidate();
        }
    
        private void Form_Closing(object sender, FormClosingEventArgs e)
        {   Bitmap  b256 = new Bitmap(256, 256);
            int     wk;
     
            if (x1==0)  return;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Title = "保存するファイルを選択してください";
            saveFileDialog1.Filter = "BMP FILE|*.bmp|すべてのファイル|*.*";
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
            {   wk = y0 - y1;
                Rectangle des = new Rectangle(0, 0, 256, 256);
                Rectangle sou = new Rectangle(0, 0, wk*4, wk*4);
                sou.X= x0-wk-wk;
                sou.Y= y0-wk-wk;
                Graphics g= Graphics.FromImage(b256);
                g.DrawImage(bmp, des, sou, GraphicsUnit.Pixel);
                b256.Save(saveFileDialog1.FileName, ImageFormat.Bmp);
            }
        }
    }
    
    class image01
    {
        [STAThread]
        public static void Main()
        {
            MyForm mf = new MyForm();
            Application.Run(mf);
        }
    }
    
  3. C#のプログラムは、C言語で Win32API を使って作成する場合に比べて非常に簡単です。
    C言語のプログラムは Face Image を参照して下さい。
    切り出した画像を保存するので using System.Drawing.Imaging; を追加して下さい。
    b256.Save() が BMP File にイメージを書き出す関数です。
    using System.Drawing.Imaging;
    
        ・・・
    
        {   Bitmap  b256 = new Bitmap(256, 256);
    
        ・・・
    
            b256.Save(saveFileDialog1.FileName, ImageFormat.Bmp);
    
  4. HD(ハードディスク)から画像ファイルを選択するので、Main() に [STAThread] を付け加えて下さい。
    opendlg.ShowDialog() がファイルの選択です。
        [STAThread]
        public static void Main()
    
        ・・・
    
            OpenFileDialog opendlg = new OpenFileDialog();
            opendlg.Filter = "画像ファイル (*.bmp)|*.bmp|すべてのファイル (*.*)|*.*" ;
            if (opendlg.ShowDialog() == DialogResult.OK)
            {   ImgFile = opendlg.FileName;  }
    
  5. それでは流れに沿って詳しく説明しましょう。
    bmp が画像ファイルの領域で、mark がクリックされた座標に表示するマークの領域です。
    ImgFile は入力する Image File の名前です。
    x0, y0, x1, y1 は画像を整えるための、鼻の頭と眉間の座標です。
    public class MyForm : Form
    {
        Bitmap  bmp;
        Bitmap  mark;
        string  ImgFile = "";
        int     x0=0, y0=0, x1=0, y1=0;
    
  6. MyForm() のコンストラクタでは、画像ファイルを選択して bmp に読み込みます。
    正常に読み込めたときはマーク画像(mark.gif)も読み込みます。
    ウインドウサイズを画像に合わせて、ペイントとマウスダウンとフォームクローズのイベントを設定します。
        public MyForm()
        {
            ・・・
    
            OpenFileDialog opendlg = new OpenFileDialog();
            opendlg.Filter = "画像ファイル (*.bmp)|*.bmp|すべてのファイル (*.*)|*.*" ;
            if (opendlg.ShowDialog() == DialogResult.OK)
            {   ImgFile = opendlg.FileName;  }
    
            ・・・
    
            mark = new Bitmap("C:\\DATA\\Test\\mark.gif");
            Width = bmp.Width;
            Height = bmp.Height+32;
            Paint += new PaintEventHandler(MyHandler);
            MouseDown += new MouseEventHandler(OnMyMouseDown);
            FormClosing += new FormClosingEventHandler(Form_Closing); 
    
  7. ウインドウの描画では、bmp を描画したあとでマークが設定されていれば重ねて描画します。
    マーク画像は透明色を設定した黒い小さな点の GIF 画像です。
        private void MyHandler(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawImage(bmp, new Point(0,0));
            if (x0!=0)  g.DrawImage(mark, new Point(x0,y0));
            if (x1!=0)  g.DrawImage(mark, new Point(x1,y1));
        }
    
  8. マウスダウンでは、鼻の頭と眉間の座標をクリックします。
    失敗したときは、3個目をクリックすると座標がリセットされるのでやり直して下さい。
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {   if (x1!=0)
            {   x0=y0=x1=y1= 0;
                Invalidate();
                return;
            }
            if (x0==0)
            {   x0= e.X;
                y0= e.Y;
                Invalidate();
                return;
            }
            x1= e.X;
            y1= e.Y;
            Invalidate();
        }
    
  9. ウインドウを閉じるときに画像サイズを整えて BMP ファイルに保存します。
    鼻の頭から眉間の長さを wk とすると、切り取る画像の範囲は鼻の頭を中心に wk*4 となります。
    Bitmap b256 の領域に切り取った画像を g.DrawImage() で 256*256 のサイズに拡大(縮小)して転送します。
    saveFileDialog1 で選択したファイルに b256.Save() で BMP 形式で保存します。
    C#には Bitmap Class にイメージファイルを保存する Save() メソッドがサポートされています。
        private void Form_Closing(object sender, FormClosingEventArgs e)
        {   Bitmap  b256 = new Bitmap(256, 256);
            int     wk;
     
            if (x1==0)  return;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.Title = "保存するファイルを選択してください";
            saveFileDialog1.Filter = "BMP FILE|*.bmp|すべてのファイル|*.*";
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
            {   wk = y0 - y1;
                Rectangle des = new Rectangle(0, 0, 256, 256);
                Rectangle sou = new Rectangle(0, 0, wk*4, wk*4);
                sou.X= x0-wk-wk;
                sou.Y= y0-wk-wk;
                Graphics g= Graphics.FromImage(b256);
                g.DrawImage(bmp, des, sou, GraphicsUnit.Pixel);
                b256.Save(saveFileDialog1.FileName, ImageFormat.Bmp);
            }
        }
    
  10. DrawImage() 関数には多くのオーバーロードが用意されているのですが、今回は次のオーバーロードを使っています。
    g.DrawImage(bmp, des, sou, GraphicsUnit.Pixel);
    
    bmp:    Bitmap Image
    des:    受け取り側の矩形(256*256)
    sou:    送り側の矩形(鼻の頭を中心に wk*4 の幅と高さ)
    Pixel:  イメージデータ(ピクセル)の並び
    

[Next Chapter ↓] Color ⇒ Grayscale
[Previous Chapter ↑] Image Guid

超初心者のプログラム入門(C# Frame Work)