Home Course Index << Prev Next >> PDF Version of this Page

Course IPCis: Image Processing with C#
Chapter C4: The Lowpass Project


Copyright © by V. Miszalok, last update: 2011-10-02

Mail me...
Let me know
what you think
  Projekt lowpass1
  Seitenaufbau, Bildaufbau
  Unterprogamm lowpass
  Noise und Clear
  Experimente
  Weitere Aufgaben

Projekt lowpass1

Main Menu nach dem Start von Visual C# 2010: File → New Project... → Visual Studio installed templates: Windows Forms Application
Name: lowpass1 → Location: C:\temp → Create directory for solution:
ausschalten → OK
Sie müssen zwei überflüssige Files löschen: Form1.Designer.cs und Program.cs.
Außerdem löschen Sie den gesamten Code von Form1.cs.

 

Seitenaufbau, Bildaufbau

Schreiben in das leere Codefenster Form1.cs folgenden Code:

using System;
using System.Drawing;
using System.Windows.Forms;

public class Form1 : Form
{ [STAThread] static void Main() { Application.Run( new Form1() ); }
  const Int32 xSize = 11;
  const Int32 ySize = 12;
  Byte[,]  i0     = new Byte[ySize,xSize];
  Brush[]  brush  = new Brush[10];
  Button[] button = new Button[ySize];
  Int32 i, x, y, xx, yy, dx, dy, sum, divisor;
  Int32 lowpass_weight = 1;

  public Form1()
  { BackColor  = Color.White;
    Text       = "Lowpass1";
    SetStyle( ControlStyles.ResizeRedraw, true );
    Width  = 800;
    Height = 600;
    for ( i=0; i < 10; i++ )
      brush[i] = new SolidBrush( Color.FromArgb( i*25, i*25, i*25 ) );
    for ( y=0; y < ySize; y++ )
    { button[y] = new Button();
      Controls.Add(button[y]);
      button[y].BackColor = Color.Gray;
      button[y].Text = "nothing";
      button[y].Name = y.ToString();
      button[y].Click += new EventHandler( do_it );
    }
    button[0].Name = button[0].Text = "Homunculus";
    button[1].Name = button[1].Text = "Lowpass 3x3";
    button[2].Name = button[2].Text = "Lowpass 5x5";
    button[3].Name = button[3].Text = "Lowpass 7x7";
    button[4].Name = button[4].Text = "LPCentWeight";
    button[5].Name = button[5].Text = "Noise";
    button[6].Name = button[6].Text = "Clear";
  }
  protected override void OnPaint( PaintEventArgs e )
  { Graphics g = e.Graphics;
    Rectangle r = ClientRectangle;
    dx = r.Width / (xSize+2);
    dy = r.Height / ySize;
    for ( y=0; y < ySize; y++ )
    { button[y].Top = y*dy+1;
      button[y].Left = xSize*dx+1;
      button[y].Width = 2*dx-2;
      button[y].Height = dy-2;
    }
    for ( y=0; y < ySize; y++ )
      for ( x=0; x < xSize; x++ )
        g.FillRectangle( brush[i0[y,x]], x*dx, y*dy, dx, dy );
  }
  protected void do_it( object sender, System.EventArgs e )
  { switch( ((Button)sender).Name )
    { case "Homunculus":
        i0 =  new Byte[,]{ {9,0,0,0,0,0,0,0,0,0,9},
                           {0,0,0,0,9,9,9,0,0,0,0},
                           {0,0,0,0,9,5,9,0,0,0,0},
                           {0,0,0,0,9,9,9,0,0,0,0},
                           {0,0,0,0,0,9,0,0,0,0,0},
                           {0,9,9,9,9,9,9,9,9,9,0},
                           {0,0,0,0,9,9,9,0,0,0,0},
                           {0,0,0,0,9,9,9,0,0,0,0},
                           {0,0,0,0,9,0,9,0,0,0,0},
                           {0,0,0,0,9,0,9,0,0,0,0},
                           {0,0,0,0,9,0,9,0,0,0,0},
                           {9,0,0,0,0,0,0,0,0,0,9} };
        Invalidate();
        break;
    }
  }
}

Klicken Sie DebugStart Without Debugging Ctrl F5. Erproben Sie das Programm. Nur der erste Button "Homunculus" tut etwas, alle anderen sind tot.

 

Unterprogramm lowpass

Version2: Beenden Sie Ihr Programm lowpass1.
Schreiben Sie eine neue Funktion unterhalb der Klammer, die protected void do_it(...) abschließt, aber noch vor die Klammer, die das Hauptprogramm public class Form1 : System.Windows.Forms.Form abschließt:

  private void lowpass(Int32 Z, Int32 MidWeight) //with border handling
  { Byte[,] help = new Byte[ySize,xSize];
    for ( y=0; y < ySize; y++ )
      for ( x=0; x < xSize; x++ )
      { divisor = MidWeight - 1; //MidWeight == 1 means no weight
        sum = divisor * i0[y,x];
        for ( yy=y-Z; yy <= y+Z; yy++ )
        { if ( yy < 0 || yy >= ySize ) continue;
          for ( xx=x-Z; xx <= x+Z; xx++ )
          { if ( xx < 0 || xx >= xSize ) continue;
            sum += i0[yy,xx]; divisor++;
          }
        }
        help[y,x] = Convert.ToByte( (float)sum / (float)divisor );
      }
    i0 = help;
  }

Schreiben Sie folgende neuen Cases unterhalb des letzten break; von case "Homunculus": im Event Handler protected void do_it(...):

      case "Lowpass 3x3":
        lowpass( 1, lowpass_weight );
        Invalidate();
        break;
      case "Lowpass 5x5":
        lowpass( 2, lowpass_weight );
        Invalidate();
        break;
      case "Lowpass 7x7":
        lowpass( 3, lowpass_weight );
        Invalidate();
        break;
      case "LPCentWeight":
        lowpass_weight++;
        button[4].Text = "LPCentWeight=" + lowpass_weight.ToString();
        break;

Klicken Sie DebugStart Without Debugging Ctrl F5. Erproben Sie die 3 Tiefpässe und die Wirkung von höheren (> 9) Faktoren von LPCentWeight.

 

Noise und Clear

Version3: Beenden Sie Ihr Programm lowpass1.
Schreiben Sie folgende neuen Cases unterhalb des letzten break; von case "LPCentWeight": im Event Handler protected void do_it(...):

      case "Noise":
        Random random = new Random();
        for ( y=0; y < ySize; y++ )
           for ( x=0; x < xSize; x++ )
           {  Int32 noise =  random.Next() % 3 - 1;
              noise += i0[y,x];
              if ( noise < 0 ) i0[y,x] = 0;
              else if ( noise > 9 ) i0[y,x] = 9;
              else                  i0[y,x] = (Byte)noise;
           }
        Invalidate();
        break;
      case "Clear":
        lowpass_weight = 1;
        button[4].Text = "LPCentWeight=1";
        for ( y=0; y < ySize; y++ )
           for ( x=0; x < xSize; x++ ) i0[y,x] = 0;
        Invalidate();
        break;

Klicken Sie DebugStart Without Debugging Ctrl F5. Erproben Sie Noise (auch mehrfach drücken) und Clear.

 

Experimente

(1) Verändern Sie Pixel in der Homunculus-Matrix (nur Werte zwischen 0 und 9 !).
(2) Vergrößern Sie const Int32 xSize von 11 auf 12 und const Int32 ySize von 12 auf 13. Fügen Sie an die Homunculus-Matrix entsprechend eine Spalte und eine Zeile an.
(3) Vergrößern Sie das Bild um weitere Spalten und Zeilen bis die Buttons rechts zu klein werden.

 

Weitere Aufgaben

Klicken Sie auf Help in der Menüleiste von Visual Studio. Klicken Sie auf das Untermenü Index.
Gehen Sie in das Feld Filtered by: und wählen Sie dort .NET Framework. Dann geben Sie im Feld Look for: folgende Schlüsselwörter ein und lesen Sie die Texte:
Button class (System.Windows.Forms), all members
consuming events
→ Lesen Sie das Unterkapitel Consuming an Event in a Windows Forms Application.
Erarbeiten Sie sich die Logik der 4 verschachtelten for-Schleifen im Unterprogramm lowpass.
Programmieren Sie eine vereinfachte mylowpass-Funktion der festen Größe 3x3, ohne Randbehandlung und ohne Mittengewichtung.
Erfinden und erproben Sie neue Varianten des Programms in Form von neuen Projekten lowpass2, lowpass3 usw. nach obigem Muster.

A rich choice of filter algorithms in C# can be found here: ../../Samples/Index_of_Samples.htm

top of page: