「TVの砂嵐を再現するフィルタ」の編集履歴(バックアップ)一覧に戻る

TVの砂嵐を再現するフィルタ - (2010/05/23 (日) 12:02:13) のソース

TVの砂嵐を再現するフィルタ
何に使うかは不明。
とりあえず作ったら予定と違うこんなフィルタが出来てしまった。
C#サンプルソース。
&ref(テレビの砂嵐を再現するフィルタ.png)
という変換を行う。
こんなフィルタを作るって何か間違っている気がする。





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 WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Bitmap b1 = new Bitmap(pictureBox1.Image);    // 変数の宣言
            

            //pictureBox1.Image  =b1;
            PictToCircle PTC = new WindowsFormsApplication2.PictToCircle();

            //PTC.changeCircle(b1);
            b1=PTC.changePictToLine(b1);

            //b1 = (PTC.getPict());
            pictureBox1.Image = b1;
            //b1.Dispose();
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/so_036.jpg");
        }
        
    }


    class PictToCircle
    {
        Random rnd = new Random();
        Bitmap b1 = null;
        Bitmap b2 = null;
        int h;//高さ
        int w;//横幅
        int max;//横と高さのうちで大きいほう
        
        public Bitmap  changePictToLine(Bitmap inBit)
        {
            Color C;
                //アルゴリズムを分かりやすくするために (行、列に直す)
                byte[,] bmpData = new byte[inBit.Height, (inBit.Width) * 3 ];
                
                // bitmapクラスの画像ピクセル値を配列に挿入
                for (int i = 0; i < inBit.Height; i++)
                {
                    for (int j = 0; j < inBit.Width; j++)
                    {
                        C=inBit.GetPixel(j,i );
                        bmpData[i,j*3+0] = C.R;
                        bmpData[i,j*3+1] = C.G;
                        bmpData[i,j*3+2] = C.B;
                    }
                }
                



            
            int w=inBit.Width;
            double[] a=new double [3];
            double[] b=new double [3];
            double[] bBunbos=new double[12];
            double[] xAves=new double[12];
            double[] yVers=new double[12];

            for (int i = 4; i < 12;i++ )
            {
                xAves[i]  =(i + 1.0) / 2.0;
                for (double k = 0; k < i; k++)
                {
                    bBunbos[i] +=(k - xAves[i] )*(k-xAves[i] ); 
                }
            }

            int colPoint;
            int loopUp;
            double  r2,g2,b2;
            
            
            
            
            for (int i = 0; i < inBit.Height; i++)
            {
            
            
                colPoint = 0;
            do
            {
                if (w - colPoint < 5)
                {
                    //とりあえずの数式
                    colPoint = w;
                }
                else
                {
                    
                    
                    if (w - colPoint < 12)
                    {
                        loopUp = w - colPoint;
                    }
                    else
                    {
                        loopUp = 12;
                    }

                    for (int k = 4; k < loopUp; k++)
                    {
                        a[0]=a[1]=a[2]=0;
                        b[0]=b[1]=b[2]=0;
                        for (int u = 0; u < k; u++)
                        {
                            
                            a[0]+=bmpData[i,colPoint*3+u*3+0];
                            a[1]+=bmpData[i,colPoint*3+u*3+1];
                            a[2]+=bmpData[i,colPoint*3+u*3+2];
                            b[0] += bmpData[i, colPoint * 3 + u * 3 + 0] *1.0* xAves[k];
                            b[1] += bmpData[i, colPoint * 3 + u * 3 + 1] *1.0* xAves[k];
                            b[2] += bmpData[i, colPoint * 3 + u * 3 + 2] *1.0* xAves[k];
                        }
                        a[0] /= k;
                        a[1] /= k;
                        a[2] /= k;
                        b[0] /= bBunbos[k] ;
                        b[1] /= bBunbos[k] ;
                        b[2] /= bBunbos[k] ;
                        double [] verTemps=new double[3];
                        double[] verSum = new double[3];
                        for (int u = 0; u < k; u++)
                        {
                            r2=bmpData[i, colPoint * 3 + u * 3 + 0];
                            g2 = bmpData[i, colPoint * 3 + u * 3 + 1];
                            b2 = bmpData[i, colPoint * 3 + u * 3 + 2];
                            verTemps[0] = (r2 - b[0] * (xAves[k] - u) + a[0]);
                            verTemps[0] *= verTemps[0];
                            verTemps[1] = (g2 - b[1] * (xAves[k] - u) + a[1]);
                            verTemps[1] *= verTemps[1];
                            verTemps[2] = (b2 - b[2] * (xAves[k] - u) + a[2]);
                            verTemps[2] *= verTemps[2];
                            verSum[0] += verTemps[0];
                            verSum[1] += verTemps[1];
                            verSum[2] += verTemps[2];
                        
                        }
                        yVers[k] = 0; 
                        for (int s = 0; s < 3; s++)
                        {
                            verTemps[s] = Math.Sqrt(1.0 / (k - 1.0) * verSum[s] *1.0);
                        }
                        yVers[k] = verTemps[0] * verTemps[1] * verTemps[2];
                        
                    }
                    double  minVer=yVers[4] ;
                    int minLen=4;
                    for (int k = 4; k < loopUp; k++)
                    {
                        if (minVer > yVers[k])
                        {
                            minVer = yVers[k];
                            minLen = k;
                        }
                    }
                    for (int k = 0; k < minLen; k++)
                    {
                       bmpData[i, k*3+colPoint*3+0]=(byte )(b[0] * (xAves[minLen] - k)+a[0]);
                       bmpData[i, k*3+colPoint*3+1]=(byte )(b[1] * (xAves[minLen] - k)+a[1]);
                       bmpData[i, k*3+colPoint*3+2]=(byte )(b[2] * (xAves[minLen] - k)+a[2]);
                    }
                        colPoint+=minLen; 
                }

            } while (colPoint  < w );
            }

            Color c;
            for (int i = 0; i < inBit.Height; i++)
            {
                for (int j = 0; j < inBit.Width; j++)
                {

                    c = Color.FromArgb(bmpData[i, j * 3 + 0],
                    bmpData[i, j * 3 + 1],
                    bmpData[i, j * 3 + 2]);
                    inBit.SetPixel(j, i, c);
                }
            }
            return inBit;
        }

        



        public PictToCircle()
        {
            
        }








        public void changeCircle(Bitmap bmp1)
        {
            this.b1 = bmp1;
            this.b2 = null;
            this.b1 = bmp1;
            this.h = bmp1.Height;
            this.w = bmp1.Width;
            this.max = Math.Max(this.h, this.w);
            this.b2 = new Bitmap(b1.Width, b1.Height);
            for (int i = 0; i < w; i++)
            {
                for (int j = 0; j < h; j++)
                {
                    b2.SetPixel(i, j, Color.White);
                }

            }
            
            int nowSize = (int)Math.Floor(max / 3.0);
            int tUp = 0;
            int incK = 1;

            while (nowSize > 1)
            {

                nowSize = (int)(nowSize / 1.717);
                for (int i = 0; i < b1.Width / nowSize; i++)
                {
                    for (int j = 0; j < b1.Height / nowSize; j++)
                    {
                        if (nowSize > 5)
                        {
                            tUp = 8;
                        }
                        else
                        {
                            tUp = 3;
                            incK = 2;
                        }
                        for (int k = 0; k < tUp; k+=incK)
                        {
                            CellToCircle(rnd.Next(4 * nowSize) - 2 * nowSize + i * nowSize, rnd.Next(4 * nowSize) - 2 * nowSize + j * nowSize, nowSize);
                        }
                    }
                }

            }


        }






        public void CellToCircle(int x, int y, int size)
        {
            if (rnd.Next(100) > 95)
            {
                size += rnd.Next(2);
            }

            int sx = cutNum(0, this.b1.Width - 1, x - size);
            int sy = cutNum(0, this.b1.Height - 1, y - size);
            int ex = cutNum(1, this.b1.Width, x + size);
            int ey = cutNum(1, this.b1.Height, y + size);

            int checkR = 1600;
            if (size > 4)
            {
                checkR = 2500;
            }
            else
            {
                checkR = 4900;
            }
            float aveR = 0;
            float aveG = 0;
            float aveB = 0;
            Color c1;
            int th = (int)Math.Floor((Math.Sqrt(size * 3)));
            int tw = th;
            int t1 = ((ex - sx) / tw + 1) * ((ey - sy) / tw + 1);


            for (int i = sx; i < ex; i += tw)
            {
                for (int j = sy; j < ey; j += th)
                {
                    //各色の平均をとる
                    c1 = b1.GetPixel(i, j);
                    aveR += c1.R;
                    aveG += c1.G;
                    aveB += c1.B;
                }
            }

            aveR /= t1;
            aveG /= t1;
            aveB /= t1;


            float ave = 0;
            float count = 0;
            for (int i = sx; i < ex; i += tw)
            {
                for (int j = sy; j < ey; j += th)
                {
                    //平均からの距離を図る
                    c1 = b1.GetPixel(i, j);
                    ave = (aveR - c1.R) * (aveR - c1.R);
                    ave += (aveG - c1.G) * (aveG - c1.G);
                    ave += (aveB - c1.B) * (aveB - c1.B);

                    if (ave < checkR)
                    {
                        count++;
                    }
                }
            }
            if (rnd.Next(10) > 3)
            {
                c1 = b1.GetPixel(rnd.Next(ex - sx) + sx, rnd.Next(ey - sy) + sy);

            }
            else
            {
                c1 = Color.FromArgb((int)(aveR), (int)(aveG), (int)(aveB));
            }
            float tUp2 = 0;
            if (size > 12)
            {
                tUp2 = 0.5F;
            }
            else if (size > 7)
            {
                tUp2 = 0.4F;
            }
            else
            {
                tUp2 = 0.3F;
            }

            if (count / t1 > tUp2)
            {
                cellToCircle2(sx, sy, ex, ey, x, y, size, c1);
            }
        }


        void cellToCircle2(int sx, int sy, int ex, int ey, int x, int y, int size, Color c)
        {
            Color c2;
            int tHeight, sy2, ey2;

            int size2 = size * size;
            byte r1, g1, b1;

            for (int i = sx; i < ex; i++)
            {
                if (size > 2)
                {
                    tHeight = (int)Math.Floor(Math.Sqrt(size2 - (double)((x - i) * (x - i))));
                    sy2 = cutNum(sy, ey, y - tHeight);
                    ey2 = cutNum(sy, ey, y + tHeight);
                }
                else
                {
                    sy2 = sy;
                    ey2 = ey;
                }
                for (int j = sy; j < ey; j++)
                {

                    if (size >7)
                    {
                        c2 = this.b1.GetPixel(i, j);
                        
                        r1 = (byte)cutNum(0, 255, (int)(c.R * 0.7 +  c2.R * 0.3));
                        g1 = (byte)cutNum(0, 255, (int)(c.G * 0.7 + c2.G * 0.3));
                        b1 = (byte)cutNum(0, 255, (int)(c.B * 0.7 + c2.B * 0.3));
                        c2 = Color.FromArgb(r1, g1, b1);
                        this.b2.SetPixel(i, j, c2);
                    }
                    else
                    {
                        c2 = this.b1.GetPixel(i, j);
                        g1 = c2.G;
                        b1 = c2.B;
                        r1 = c2.R;
                        c2 = this.b2.GetPixel(i, j);
                        if (((int)(r1) - g1) - b1 > 100)
                        {
                           r1 = (byte)(r1 * 0.3 + 255 * 0.7);
                           g1 =(byte)((g1 * 0.5) + rnd.Next(10));
                           b1 = (byte)((g1 * 0.5)+ rnd.Next(10));
                        }
                        if (((int)(g1) - r1) - b1 > 100)
                        {
                            g1 = (byte)(g1 * 0.3 + 255 * 0.7);
                            r1 = (byte)((g1 * 0.4)+rnd.Next(10));
                            b1 = (byte)((b1 * 0.4)+rnd.Next(10));
                        }
                        if (((int)(b1) - r1) - g1 > 100)
                        {
                            b1 = (byte)(b1 * 0.3 + 255 * 0.7);
                            r1 = (byte)((r1 * 0.4)+rnd.Next(10));
                            g1 = (byte)((g1 * 0.4)+rnd.Next(10));
                        }

                        if (((int)(b1) + r1) + g1 <400)
                        {
                            b1 = (byte)(b1 * 0.6);
                            r1 = (byte)(r1 * 0.6);
                            g1 = (byte)(g1 * 0.6);
                        }
                        r1 = (byte)cutNum(0, 255, (int)(c.R * 0.4 + r1 * 0.3+c2.R*0.4));
                        g1 = (byte)cutNum(0, 255, (int)(c.G * 0.4+  g1 * 0.3+c2.G*0.4 ));
                        b1 = (byte)cutNum(0, 255, (int)(c.B * 0.4 + b1 * 0.3+c2.B*0.4 ));
                        c2 = Color.FromArgb(r1, g1, b1);
                        this.b2.SetPixel(i, j, c2);
                    }



                }
            }
        }
        public Bitmap getPict()
        {
            return this.b2;
        }









        private int cutNum(int min, int max, int t)
        {
            if (t < min)
            {
                t = min;
            }
            if (t > max)
            {
                t = max;
            }
            return t;
        }

    }
}