※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

「色使いまねフィルタ」の編集履歴(バックアップ)一覧に戻る

色使いまねフィルタ - (2010/06/19 (土) 17:28:42) の1つ前との変更点

追加された行は青色になります

削除された行は赤色になります。

 C#プログラム
 製作者 堀江伸一
 
 pictureBox2つ、ボタン3つおいて使うサンプルフィルタ。
 
 ボタン2を押すとダイアログが出るので、フィルタの教師データとなる画像を選択。
 ボタン3も押すと、フィルタが適用される画像が準備される。
 
 
 ボタン1を押すと、フィルタが適用される。
 ボタン1を押すと、ボタン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;
 using System.Threading;
 public delegate void ExampleCallback(Bitmap outBit, PictureBox p1);
 
 namespace WindowsFormsApplication2
 {
     public partial class Form1 : Form
     {
         int tc = 0;
         //Bitmap lastB;
         public Form1()
         {
             InitializeComponent();
 
         }
 
         private void Form1_Load(object sender, EventArgs e)
         {
             pictureBox2.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11033455_m.jpg");
         }
 
         private void button1_Click(object sender, EventArgs e)
         {
             Bitmap b2 = new Bitmap(pictureBox1.Image);
             
             Bitmap b1 = new Bitmap(pictureBox2.Image);
             
 
 
 
             //pictureBox1.Image  =b1;
 
             pictFilter PTC1 = new WindowsFormsApplication2.pictFilter();
             //pict_RGB_And_Deviation aveDev = new pict_RGB_And_Deviation(150, 150, 150, 70, 70, 70);
             //上記メソッドは
             //b2 = PTC1.cercleChange(b2);
             //b1 = PTC1.cercleChange(b1);
    
             //pictureBox1.Image = b2;  
             pictureBox1.Image= PTC1.Color_imitation_filter(b1,b2,10);
 
             //pictureBox1.Image = PTC1.standard_deviation_filter(aveDev, b2);
             //pictureBox1.Image  =PTC1.lineFilter(b1);
             //b1=PTC1.lineFilter(b1);
 
             /*pictFilter PTC = new WindowsFormsApplication2.pictFilter(PTC1.lineFilter (b1), new ExampleCallback(ResultCallback),pictureBox1);
             Thread t1 =new Thread(new ThreadStart(PTC.cercleChange));
             t1.Start();
             t1.Join();
             */
             //pictFilter PTC = new WindowsFormsApplication2.pictFilter();
             //pictureBox1.Image = PTC.lineFilter(b1);
             //pictureBox1.Image = PTC.flatFilter2( PTC.cercleChange      (b1)) ;
             //b1.Dispose();
         }
         public static void ResultCallback(Bitmap outBit, PictureBox p1)
         {
             p1.Image = outBit;
         }
 
 
         private void pictureBox1_Click(object sender, EventArgs e)
         {
             tc++;
             pictureBox1.Top = 0;
             pictureBox1.Left = 0;
 
         }
 
         private void button2_Click(object sender, EventArgs e)
         {
             OpenFileDialog ofd = new OpenFileDialog();
             ofd.Filter = "画像ファイル(*.jpeg;*.jpg;*.gif)|*.jpeg;*.jpg;*.gif|すべてのファイル(*.*)|*.*";
             if (ofd.ShowDialog() == DialogResult.OK)
             {
                 pictureBox2.Image = Image.FromFile(ofd.FileName); 
             }
         }
 
         private void button3_Click(object sender, EventArgs e)
         {
             OpenFileDialog ofd = new OpenFileDialog();
             ofd.Filter = "画像ファイル(*.jpeg;*.jpg;*.gif)|*.jpeg;*.jpg;*.gif|すべてのファイル(*.*)|*.*";
             if (ofd.ShowDialog() == DialogResult.OK)
             {
                 pictureBox1.Image = Image.FromFile(ofd.FileName);
             }
         }
 
     }
     class pictFilter
     {
         Random rnd = new Random();
         Bitmap pictOut = null;
         int h;//絵の高さ
         int w;//絵の横幅
         Bitmap pictIn;
         ExampleCallback callback;
         PictureBox lastPict;
         cell[, ,] cells;
         int cell_size;
         public pictFilter()
         {
             h = 0;
             w = 0;
         }
 
 
         public Bitmap Color_imitation_filter(Bitmap b1, Bitmap b2,int c_size)
         {
             cell_size = c_size;
             int size=255/cell_size+5;
             cells = new cell[size, size, size];
 
             for (int i = 0; i < size; i++)
             {
                 for (int j = 0; j < size; j++)
                 {
                     for (int k = 0; k < size; k++)
                     {
                         cells[i, j, k] = new cell();
                     }
                 }
             }
 
             pict_RGB_And_Deviation aveDev1=new pict_RGB_And_Deviation(b1);
             pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2);
 
             int sabunR =(int)Math.Floor ( aveDev1.aveR - aveDev2.aveR);
             int sabunG =(int)Math.Floor ( aveDev1.aveG - aveDev2.aveG);
             int sabunB = (int)Math.Floor(aveDev1.aveB - aveDev2.aveB);    
 
             Color C1;
             Bitmap b3=new Bitmap (b2.Width,b2.Height );
             for (int i = 0; i < b1.Width; i++)
             {
                 for (int j = 0; j < b1.Height; j++)
                 {
                     C1 = b1.GetPixel(i, j);
                    
                     cells[get_cell_point(C1.R), get_cell_point(C1.G), get_cell_point(C1.B)].add(C1.R, C1.G, C1.B);
                 }
             }
             Color nextColor;
             
 
 
             for (int i = 0; i < b2.Width; i++)
             {
                 for (int j = 0; j < b2.Height; j++)
                 {
                     C1 = b2.GetPixel(i, j);
                     //nextColor=C1;
                     nextColor =Color.FromArgb(cutNum(0, 255, C1.R + sabunR/2),
                         cutNum(0, 255, C1.G + sabunG/2),
                         cutNum(0, 255, C1.B + sabunB/2));
                     //nextColor = getAveCountCell(nextColor);
                     nextColor  = getMaxCountCell(nextColor);
                     //
                     b3.SetPixel(i, j, nextColor); 
                 }
             }
 
 
                 return b3;
         }
 
 
         public Color getAveCountCell(Color C1)
         {
             List<cell> cell_list = new List<cell>(); //
             int rPoint, gPoint, bPoint;
             cell myCell;
             //Count数の比率からセルを平均的に返す処理
             rPoint = get_cell_point(C1.R);
             gPoint = get_cell_point(C1.G);
             bPoint = get_cell_point(C1.B);
             int sumCount=0;
 
             for (int i = -2; i < 3; i++)
             {
                 for (int j = -2; j < 3; j++)
                 {
                     for (int k = -2; k < 3; k++)
                     {
                         myCell = cells[rPoint+i, gPoint+j, bPoint+k];
                         
                         if (myCell.getCount() > 0)
                         {
                             cell_list.Add(myCell);
                             sumCount  +=myCell.getCount(); 
                         }
                     }
                 }
             }
 
             if (cell_list.Count > 0)
             {
                 int rndC=rnd.Next(sumCount);
                 int tSum=0;
                 Color C2=C1;
                 foreach (cell myCell1 in cell_list)
                 {
                     tSum +=myCell1.getCount();  
                     if(tSum>rndC){
                         C2=myCell1.aveColor() ;
                         break;
                     }
                 }
                 
                 
                 
                 
                 return Color.FromArgb(
                     (int)Math.Floor(C2.R * 0.1d + C1.R * 0.9d),
                     (int)Math.Floor(C2.G * 0.1d + C1.G * 0.9d),
                     (int)Math.Floor(C2.B * 0.1d + C1.B * 0.9d)
                     );
             }
             else
             {
                 return C1;
             }
 
         }
         
         public Color getMaxCountCell(Color C1)
         {
             List<cell> cell_list = new List<cell>(); //
             int maxCount = 1;
             int rPoint,gPoint,bPoint;
             cell myCell;
             //Countが最も大きいセルを返す処理
             rPoint=get_cell_point(C1.R );  
             gPoint=get_cell_point(C1.G);
             bPoint=get_cell_point (C1.B);
             for (int i = -2; i < 3; i++)
             {
                 for (int j = -2; j < 3; j++)
                 {
                     for (int k = -2; k < 3; k++)
                     {
                         myCell=cells[rPoint+i,gPoint+j,bPoint+k]; 
                         if(myCell.getCount ()>maxCount ){
                             cell_list.Clear();
                             cell_list.Add(myCell);
                             maxCount = myCell.getCount(); 
                         }else if(myCell.getCount ()==maxCount ){
                             cell_list.Add(myCell);
                         }
 
                     }
                 }
             }
 
             if (cell_list.Count>0)
             {                
                 Color C2;
                 C2=cell_list[rnd.Next(cell_list.Count)].aveColor()  ;
 
                 return Color.FromArgb(
-                    (int)Math.Floor (C2.R * 0.6d + C1.R * 0.4d),
-                    (int)Math.Floor (C2.G * 0.6d + C1.G * 0.4d),
-                    (int)Math.Floor (C2.B * 0.6d + C1.B * 0.4d)
+                    (int)Math.Floor (C2.R * 0.8d + C1.R * 0.2d),
+                    (int)Math.Floor (C2.G * 0.8d + C1.G * 0.2d),
+                    (int)Math.Floor (C2.B * 0.8d + C1.B * 0.2d)
                     ); 
             }
             else
             {
                 return C1;
             }
             
         }
 
 
 
         public int get_cell_point(int rgb)
         {
             return (rgb / cell_size) +2; 
         }
       
 
         public Bitmap standard_deviation_filter(pict_RGB_And_Deviation aveDev1, Bitmap b2)
         {
             Color C2;
             Bitmap outBit;
             double tR, tG, tB;
             int tR1, tG1, tB1;
             pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2);
 
             outBit = new Bitmap(b2.Width, b2.Height);
 
             for (int i = 0; i < b2.Width; i++)
             {
                 for (int j = 0; j < b2.Height; j++)
                 {
                     C2 = b2.GetPixel(i, j);
                     //tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR;
                     //tG = ((C2.G - aveDev2.aveG) / aveDev2.devG) * (C2.G - aveDev2.aveG) / aveDev2.devG * aveDev1.devG + aveDev1.aveG;
                     //tB = ((C2.B - aveDev2.aveB) / aveDev2.devB) * (C2.B - aveDev2.aveB) / aveDev2.devB * aveDev1.devB + aveDev1.aveB;
 
                     tR = Math.Log(3 * ((C2.R - aveDev2.aveR) / aveDev2.devR)) * aveDev1.devR + aveDev1.aveR;
                     tG = Math.Log(3 * ((C2.G - aveDev2.aveG) / aveDev2.devG)) * aveDev1.devG + aveDev1.aveG;
                     tB = Math.Log(3 * ((C2.B - aveDev2.aveB) / aveDev2.devB)) * aveDev1.devB + aveDev1.aveB;
                     
                     /*
                     tR = (C2.R - aveDev2.aveR);
                     tR = tR / 2.0 + 0.5;
                     if (tR > 0.5)
                     {
                         tR = -Math.Pow(2 * tR - 2, 0.7) / 2 + 1;
                     }
                     else
                     {
                         tR=2 * Math.Pow(tR, 0.7/2);
                     }
                     tR = tR * 2 - 1;
                     */
                     
                     
                     tR1 = cutNum(0, 255, (int)Math.Floor(tR));
                     tG1 = cutNum(0, 255, (int)Math.Floor(tG));
                     tB1 = cutNum(0, 255, (int)Math.Floor(tB));
                     outBit.SetPixel(i, j, Color.FromArgb(tR1, tG1, tB1));
 
                 }
             }
             //生物の遺伝子構造解析をして病気対策をするとき、遺伝子コードのパターンマッチにパソコンを使うとか、本当はそういうプログラム書けたらなと思ったり、
 
             return outBit;
         }
 
         public Bitmap standard_deviation_filter(Bitmap b1, Bitmap b2)
         {
             Color C2;
             Bitmap outBit;
             double tR, tG, tB;
             int tR1, tG1, tB1;
             pict_RGB_And_Deviation aveDev1 = new pict_RGB_And_Deviation(b1);
             pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2);
 
             outBit = new Bitmap(b2.Width, b2.Height);
 
             for (int i = 0; i < b2.Width; i++)
             {
                 for (int j = 0; j < b2.Height; j++)
                 {
                     C2 = b2.GetPixel(i, j);
                     tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR;
                     tG = (C2.G - aveDev2.aveG) / aveDev2.devG * aveDev1.devG + aveDev1.aveG;
                     tB = (C2.B - aveDev2.aveB) / aveDev2.devB * aveDev1.devB + aveDev1.aveB;
                     //tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR;
                     //tG = ((C2.G - aveDev2.aveG) / aveDev2.devG) * ((C2.G - aveDev2.aveG) / aveDev2.devG) * aveDev1.devG + aveDev1.aveG;
                     //tB = ((C2.B - aveDev2.aveB) / aveDev2.devB) * ((C2.B - aveDev2.aveB) / aveDev2.devB) * aveDev1.devB + aveDev1.aveB;
                     
 
                     tR1 = cutNum(0, 255, (int)Math.Floor(tR));
                     tG1 = cutNum(0, 255, (int)Math.Floor(tG));
                     tB1 = cutNum(0, 255, (int)Math.Floor(tB));
                     outBit.SetPixel(i, j, Color.FromArgb(tR1, tG1, tB1));
 
                 }
             }
             //生物の遺伝子構造解析をして病気対策をするとき、遺伝子コードのパターンマッチにパソコンを使うとか、本当はそういうプログラム書けたらなと思ったり、
 
             return outBit;
         }
 
 
 
 
 
 
         public pictFilter(Bitmap b1, ExampleCallback callbackDelegate, PictureBox p1)
         {
             this.pictIn = b1;
             h = 0;
             w = 0;
             callback = callbackDelegate;
             lastPict = p1;
         }
         public Bitmap cercleChange(Bitmap b1)
         {
             //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理
             //このメソッドはスレッドで呼ぶこと前提にしている
             float ccR = 128;
             float ccG = 128;
             float ccB = 128;
             float a = 2.0f;
             float b = 0.5f;
             double cR, cG, cB;
             double r1 = 0;
             double r2 = 0;
             Color C1;
             //double rk;
 
             this.h = b1.Height;
             this.w = b1.Width;
             Bitmap pictOut = new Bitmap(this.w, this.h);
             //Threadをとめる処理
 
             for (int i = 0; i < this.w; i++)
             {
                 for (int j = 0; j < this.h; j++)
                 {
                     C1 = b1.GetPixel(i, j);
                     r1 = Math.Sqrt((C1.R - ccR) * (C1.R - ccR) +
                         (C1.G - ccG) * (C1.G - ccG) +
                         (C1.B - ccB) * (C1.B - ccB)) / 255;
 
                     r2 = (a * r1 + b);
                     cR = r2 * (C1.R - ccR) + ccR;
                     cG = r2 * (C1.G - ccG) + ccG;
                     cB = r2 * (C1.B - ccB) + ccB;
 
 
                     pictOut.SetPixel(i, j,
                         Color.FromArgb(
                         cutNum(0, 255, (int)(cR)),
                         cutNum(0, 255, (int)(cG)),
                         cutNum(0, 255, (int)(cB))));
                     //これはLispではありませんw
                 }
             }
 
 
 
             //テンプレ
             //this.h = pictIn.Height;
             //this.w = pictIn.Width;
             //pictOut = new Bitmap(this.w, this.h);
             //for(int i=0;i<this.w;i++){
             //    for (int j = 0; j < this.h; j++)
             //    {   
             //    }
             //}
             return pictOut;
         }
         public void cercleChange()
         {
             //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理
             //このメソッドはスレッドで呼ぶこと前提にしている
             float ccR = 128;
             float ccG = 128;
             float ccB = 128;
             float a = 2.0f;
             float b = 0.5f;
             double cR, cG, cB;
             double r1 = 0;
             double r2 = 0;
             Color C1;
             //double rk;
 
             this.h = pictIn.Height;
             this.w = pictIn.Width;
             pictOut = new Bitmap(this.w, this.h);
             //Threadをとめる処理
 
             for (int i = 0; i < this.w; i++)
             {
                 for (int j = 0; j < this.h; j++)
                 {
                     C1 = pictIn.GetPixel(i, j);
                     r1 = Math.Sqrt((C1.R - ccR) * (C1.R - ccR) +
                         (C1.G - ccG) * (C1.G - ccG) +
                         (C1.B - ccB) * (C1.B - ccB)) / 255;
 
                     r2 = (a * r1 + b);
                     cR = r2 * (C1.R - ccR) + ccR;
                     cG = r2 * (C1.G - ccG) + ccG;
                     cB = r2 * (C1.B - ccB) + ccB;
 
 
                     pictOut.SetPixel(i, j,
                         Color.FromArgb(
                         cutNum(0, 255, (int)(cR)),
                         cutNum(0, 255, (int)(cG)),
                         cutNum(0, 255, (int)(cB))));
                     //これはLispではありませんw
                 }
                 if (i % 10 == 0)
                 {
                     Thread.Sleep(30);
                 }
             }
             //スレッドのOutput用命令
             callback(pictOut, lastPict);
 
 
 
             //テンプレ
             //this.h = pictIn.Height;
             //this.w = pictIn.Width;
             //pictOut = new Bitmap(this.w, this.h);
             //for(int i=0;i<this.w;i++){
             //    for (int j = 0; j < this.h; j++)
             //    {   
             //    }
             //}
             //return pictOut;
         }
         public Bitmap flatFilter2(Bitmap pictIn)
         {
             //色空間内の点の色座標をを法線ベクトル(1,1,1),rgbAve=r+g+bとなる平面から遠くへ引き離したり、近づけたりする処理
             Color C1;
             this.h = pictIn.Height;
             this.w = pictIn.Width;
             double flatLen = 0;
             double r1 = 0;
 
             float rgbAve = 256;
             pictOut = new Bitmap(this.w, this.h);
             double a = -1.0;
             double b = 2.0;
             double root3 = Math.Sqrt(3);
             double v1 = 184;
             double maxRGB = 0, minRGB = 0;
 
             for (int i = 0; i < this.w; i++)
             {
                 for (int j = 0; j < this.h; j++)
                 {
                     C1 = pictIn.GetPixel(i, j);
                     flatLen = (C1.R + C1.G + C1.B - rgbAve) / (root3); //点と平面までの距離
                     r1 = Math.Sign(flatLen) * ((a * Math.Abs(flatLen) / v1 + b));//点と平面までの距離に基づいて、次の点の平面からの距離を決定する。
                     maxRGB = Math.Max(C1.R + r1 * v1, Math.Max(C1.G + r1 * v1, C1.B + r1 * v1));
                     if (maxRGB > 255)
                     {
                         if (C1.R > C1.G && C1.R > C1.B)
                         {
                             r1 = r1 - (255 - C1.R) / v1 - 1;
                         }
                         else if (C1.G > C1.R && C1.G > C1.B)
                         {
                             r1 = r1 - (255 - C1.G) / v1 - 1;
                         }
                         else
                         {
                             r1 = r1 - (255 - C1.B) / v1 - 1;
                         }
                     }
                     minRGB = Math.Min(C1.R + r1 * v1, Math.Min(C1.G + r1 * v1, C1.B + r1 * v1));
                     if (minRGB < 0)
                     {
                         if (C1.R < C1.G && C1.R < C1.B)
                         {
                             r1 = r1 - (C1.R) / v1 - 1;
                         }
                         else if (C1.G < C1.R && C1.G < C1.B)
                         {
                             r1 = r1 - (C1.G) / v1 - 1;
                         }
                         else
                         {
                             r1 = r1 - (C1.B) / v1 - 1;
                         }
                     }
 
 
                     pictOut.SetPixel(i, j, Color.FromArgb(
                         cutNum(0, 255, (int)(C1.R + r1 * v1)),
                         cutNum(0, 255, (int)(C1.G + r1 * v1)),
                         cutNum(0, 255, (int)(C1.B + r1 * v1))));
                 }
             }
             return pictOut;
         }
 
 
         public Bitmap adsorptionFilter(Bitmap pictIn)
         {
             //テンプレ
             Color C1;
             this.h = pictIn.Height;
             this.w = pictIn.Width;
             pictOut = new Bitmap(this.w, this.h);
             byte maxRGB;
             byte minRGB;
             double rgbR, rgbG, rgbB;
 
             for (int i = 0; i < this.w; i++)
             {
                 for (int j = 0; j < this.h; j++)
                 {
 
 
 
                     C1 = pictIn.GetPixel(i, j);
                     rgbR = C1.R;
                     rgbG = C1.G;
                     rgbB = C1.B;
 
                     maxRGB = (byte)Math.Max(rgbR, Math.Max(rgbG, rgbB));
                     minRGB = (byte)Math.Min(rgbR, Math.Min(rgbG, rgbB));
 
 
                     if (255 - maxRGB < minRGB)
                     {
                         if (rgbR == maxRGB)
                         {
                             rgbR = 255 * 0.5 + rgbR * 0.5;
                         }
                         else if (rgbB == maxRGB)
                         {
                             rgbB = 255 * 0.5 + rgbB * 0.5;
                         }
                         else
                         {
                             rgbG = 255 * 0.5 + rgbG * 0.5;
                         }
                     }
                     else
                     {
                         if (C1.R == minRGB)
                         {
                             rgbR = rgbR * 0.5;
                         }
                         else if (C1.G == minRGB)
                         {
                             rgbG = rgbG * 0.5;
                         }
                         else
                         {
                             rgbB = rgbB * 0.5;
                         }
                     }
 
                     pictOut.SetPixel(i, j,
                         Color.FromArgb(
                             (int)rgbR,
                             (int)rgbG,
                             (int)rgbB));
                 }
             }
             return pictOut;
         }
 
 
 
 
 
         public Bitmap lineFilter(Bitmap pictIn)
         {
             //テンプレ
             Color C1;
             this.h = pictIn.Height;
             this.w = pictIn.Width;
             double r1;
             double r2;
             double[] vecOB = { -1, -1, 1 };
             double[] vecOH = { 0, 0, 0 };
             double[] vecOA = { 0, 0, 0 };
             double[] vecHA = { 0, 0, 0 };
             double[] vecOA2 = { 0, 0, 0 };
             double[] vecCen = { 255, 255, 0 };
             double LenOH, LenOB, LenHA = 0;
 
             double a = -1.0;
             double b = 2.0;
             LenOB = Math.Sqrt(vecOB[0] * vecOB[0] + vecOB[1] * vecOB[1] + vecOB[2] * vecOB[2]);
             pictOut = new Bitmap(this.w, this.h);
 
 
 
             for (int i = 0; i < this.w; i++)
             {
                 for (int j = 0; j < this.h; j++)
                 {
                     LenHA = 0;
 
 
                     C1 = pictIn.GetPixel(i, j);
                     vecOA[0] = C1.R - vecCen[0];
                     vecOA[1] = C1.G - vecCen[1];
                     vecOA[2] = C1.B - vecCen[2];
 
                     LenOH = (vecOA[0] * vecOB[0] + vecOA[1] * vecOB[1] + vecOA[2] * vecOB[2]) / LenOB;
 
 
                     for (int k = 0; k < 3; k++)
                     {
                         vecOH[k] = LenOH / LenOB * vecOB[k];
                         vecHA[k] = -vecOH[k] + vecOA[k];
                         LenHA += vecHA[k] * vecHA[k];
                     }
                     LenHA = Math.Sqrt(LenHA);
                     r1 = LenHA / 255;
                     r2 = (a * r1 + b);
 
 
                     for (int k = 0; k < 3; k++)
                     {
                         //vecOA2[k] = cutNum(0,255,(int)( r2 * vecHA[k]  + vecOH[k]+vecCen[k]));
                         vecOA2[k] = cutNum(0, 255, (int)(r2 * vecHA[k] * 0 + vecOH[k] + vecCen[k]));
                     }
 
                     pictOut.SetPixel(i, j,
                         Color.FromArgb(
                             (int)vecOA2[0],
                             (int)vecOA2[1],
                             (int)vecOA2[2]));
                 }
             }
             return pictOut;
         }
 
 
         public Bitmap flatFilter(Bitmap pictIn)
         {
             //テンプレ
             Color C1;
             this.h = pictIn.Height;
             this.w = pictIn.Width;
             int rgbR, rgbG, rgbB;
             pictOut = new Bitmap(this.w, this.h);
 
 
 
             for (int i = 0; i < this.w; i++)
             {
                 for (int j = 0; j < this.h; j++)
                 {
                     C1 = pictIn.GetPixel(i, j);
                     if (C1.R + C1.G + C1.B > 255)
                     {
                         rgbR = (int)(C1.R * 0.5 + 255 * 0.5);
                         rgbG = (int)(C1.G * 0.5 + 255 * 0.5);
                         rgbB = (int)(C1.B * 0.5 + 255 * 0.5);
                     }
                     else
                     {
                         rgbR = (int)(C1.R * 0.5);
                         rgbG = (int)(C1.G * 0.5);
                         rgbB = (int)(C1.B * 0.5);
                     }
                     pictOut.SetPixel(i, j, Color.FromArgb(rgbR, rgbG, rgbB));
                 }
             }
             return pictOut;
         }
 
 
         private int cutNum(int min, int max, int t)
         {
             if (t < min)
             {
                 t = min;
             }
             if (t > max)
             {
                 t = max;
             }
             return t;
         }
 
     }
     public class pict_RGB_And_Deviation
     {
         public double aveR, aveG, aveB;
         public double devR, devG, devB;
         public pict_RGB_And_Deviation(double inAveR, double inAveG, double inAveB, double inDevR, double inDevG, double inDevB)
         {
             aveR = inAveR;
             aveG = inAveG;
             aveB = inAveB;
             devR = inDevR;
             devG = inDevG;
             devB = inDevB;
         }
         public pict_RGB_And_Deviation(Bitmap b1)
         {
             Color C1;
             double countPictSize;
             for (int i = 0; i < b1.Width; i++)
             {
                 for (int j = 0; j < b1.Height; j++)
                 {
                     C1 = b1.GetPixel(i, j);
                     aveR += (double)C1.R;
                     aveG += (double)C1.G;
                     aveB += (double)C1.B;
                 }
             }
             countPictSize = b1.Width * b1.Height;
             aveR /= countPictSize;
             aveG /= countPictSize;
             aveB /= countPictSize;
             for (int i = 0; i < b1.Width; i++)
             {
                 for (int j = 0; j < b1.Height; j++)
                 {
                     C1 = b1.GetPixel(i, j);
                     devR += ((double)C1.R - aveR) * ((double)C1.R - aveR);
                     devG += ((double)C1.G - aveG) * ((double)C1.G - aveG);
                     devB += ((double)C1.B - aveB) * ((double)C1.B - aveB);
                 }
             }
             if (countPictSize > 1)
             {
                 countPictSize--;
             }
             else
             {
                 countPictSize = 1;
             }
 
             devR = Math.Sqrt(devR / countPictSize);
             devG = Math.Sqrt(devG / countPictSize);
             devB = Math.Sqrt(devB / countPictSize);
         }
     }
     public class cell
     {
         int sumR = 0;
         int sumG = 0;
         int sumB = 0;
         int count = 0;
 
         public int getCount()
         {
             return count;
         }
 
         public void add(int r, int g, int b)
         {
             count++;
             sumR += r;
             sumG += g;
             sumB += b;
         }
         public void add(Color C)
         {
             count++;
             sumR += C.R;
             sumG += C.G;
             sumB += C.B;
 
         }
         public Color aveColor()
         {
             if (count > 0)
             {
                 
 
                 return Color.FromArgb(
                     (int)sumR/count,
                     (int)sumG/count,
                     (int)sumB/count) ;
             }else{
                 return (Color.FromArgb(0,0,0) );
             }
         }
     }
 
 }