- •Лист задания
- •Введение
- •1 Постановка задачи
- •2 Описание реализуемых методов и алгоритмов
- •2.1 Методы обработки изображений. Поворот изображения, получение серого изображения из исходного
- •2.2 Алгоритмы подавления шума
- •2.2.1 Фильтр свертка с маской и медианный фильтр
- •2.2.2 Метод k-ближайших соседей
- •2.3.1 Пороговая сегментация
- •2.3.2 Алгоритм водораздела
- •2.3 Методы обнаружения границ объектов на изображении
- •2.4 Метод описания контуров объектов. Оператор Кирша, оператор Превитта, оператор Лапласа.
- •2.5 Метод цепного кодирования
- •3 Описание программной реализации
- •3.1 Теоретические сведения о библиотеке OpenCv
- •3.2 Структуры данных, используемые в пп
- •3.3 Описание функций и методов, используемых в пп
- •Список использованных источников
- •Приложение а техническое задание
- •Приложение б руководство пользователя
- •Приложение в экранные формы
- •Приложение г листинг программы
Приложение б руководство пользователя
Для начала работы с приложением, необходимо загрузить картинку, с которой вы будете работать. Для этого выберите Файл/Открыть. Далее будет открыто диалоговое окно загрузки файла, и после выбора необходимой картинки она загрузится в приложение и отобразится на экране. Главное окно приложения имеет несколько вкладок редактирования, на левой панели формы: «Редактировать», «Фильтрация», «Сегментация», «Жук».
После того как изображение было загружено в приложение, его можно обработать, выбрав любой из вышеперечисленных пунктов. Каждый из пунктов имеет свои подпункты:
«Редактировать»: «Градации серого», «Повернуть на право», «Повернуть на лево», «добавить аддитивный шум», «Добавить импульсный шум»;
«Фильтрация»: «Медианный фильтр», «Фильтр К-ближайших соседей», «Взвешенно-медианный фильтр», «Фильтр с маской».
«Сегментация»: «Пороговая сегментация», «Фильтр водораздела», «Оператор Превита», «Оператор Кирша», «Оператор Лапласа»;
«Жук»: «Жук».
Когда будет выбран любой из вышеперечисленных пунктов, произойдет обработка изображения при помощи определенного алгоритма, и в окне приложения отобразится результат этой обработки.
Для пороговой сегментации вы сможете выбрать точность, используя элементы управления. Для фильтра свертки вы можете выбрать значения маски.
Приложение в экранные формы

Рисунок В.1 – Исходное изображение

Рисунок В.2 – Перевод изображения в полутоновое

Рисунок В.3 – Применение медианного фильтра

Рисунок В.4 – Применение оператора Кирша

Рисунок В.5 – Применение алгоритма водораздела

Рисунок В.6 – Демонстрация алгоритма «жука»
Приложение г листинг программы
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;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.UI;
namespace RI_Csharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.ColumnCount = 3;
dataGridView1.RowCount = 3;
dataGridView1.RowHeadersVisible = false;
dataGridView1.ColumnHeadersVisible = false;
button3.Enabled = false;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
dataGridView1.Rows[i].Height = 39;
dataGridView1.Columns[j].Width = 39;
}
}
label2.Text = trackBar1.Value.ToString();
trackBar1.Enabled = false;
tabControl1.Enabled = false;
Steps = 0;
button1.Enabled = false;
button2.Enabled = false;
}
//-----------ГЛОБАЛЬНЫЕ-ПЕРЕМЕННЫЕ----------------------------------
Image<Bgr, byte> Picture;
List<Image<Bgr, byte>> PictureSet = new List<Image<Bgr,byte>>();
int Steps = 0;
String TheWayToFile;
System.String TheWayToSave;
Random Rnd = new Random();
double[,] Mask = new double[3, 3];
float[,] kern = new float[3, 3];
//-----------ФУНКЦИОНАЛ---------------------------------------------
/// <summary>
/// Открытие изображения
/// </summary>
/// <param name="TheWay"></param>
/// <returns></returns>
private Image<Bgr, byte> OpenTheImage()
{
Image<Bgr, byte> Img;
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
TheWayToFile = openFileDialog1.FileName.ToString();
Img = new Image<Bgr, byte>(TheWayToFile);
return Img;
}
else
{
Img = new Image<Bgr, byte>(200,200);
return Img;
}
}
/// <summary>
/// Сохранение изображения
/// </summary>
/// <param name="Img"></param>
private void SaveTheImage(Image<Bgr, byte> Img)
{
if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK && saveFileDialog1.FileName != "")
{
TheWayToSave = saveFileDialog1.FileName.ToString();
Picture.Save(TheWayToSave);
}
}
/// <summary>
/// Перевод изображения в серые тона
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> ConvertToGray(Image<Bgr, byte> Img)
{
Image<Gray, byte> Gray;
Image<Bgr, byte> NotGray;
Gray = Img.Convert<Gray, byte>();
NotGray = Gray.Convert<Bgr, byte>();
return NotGray;
}
/// <summary>
/// Поворот изображения на право
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> RotateRight(Image<Bgr, byte> Img)
{
Image<Bgr, byte> Rotated = new Image<Bgr, byte>(Img.Height, Img.Width);
for (int i=0; i< Img.Height - 1;i++)
{
for (int j=0; j< Img.Width - 1;j++)
{
Rotated[j, Img.Height - i - 1] = Img[i, j];
}
}
return Rotated;
}
/// <summary>
/// Поворот изображения на лево
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> RotateLeft(Image<Bgr, byte> Img)
{
Image<Bgr, byte> Rotated = new Image<Bgr, byte>(Img.Height, Img.Width);
for (int i = 0; i < Img.Height - 1; i++)
{
for (int j = 0; j < Img.Width - 1; j++)
{
Rotated[Img.Width - j - 1, i] = Img[i, j];
}
}
return Rotated;
}
/// <summary>
/// Аддитивный шум
/// </summary>
/// <param name="Img"></param>
private void ANoise(Image<Bgr, byte> Img)
{
int[,] Generation = new int[Img.Width, Img.Height];
Bgr Q;
for (int i = 0; i < Img.Width; i++)
{
for (int j = 0; j < Img.Height; j++)
{
Generation[i, j] = Rnd.Next(-100,100);
}
}
double SKO = 0;
for (int i = 0; i < Img.Width; i++)
{
for (int j = 0; j < Img.Height; j++)
{
SKO = SKO + Generation[i, j] * Generation[i, j];
}
}
SKO = SKO / (Img.Width * Img.Height);
SKO = Math.Sqrt(SKO);
for (int i = 0; i < Img.Width; i++)
{
for (int j = 0; j < Img.Height; j++)
{
Generation[i, j] = Generation[i,j] * 20 / Convert.ToInt32(SKO);
}
}
for (int i = 0; i < Img.Width - 1; i++)
{
for (int j = 0; j < Img.Height - 1; j++)
{
Q = new Bgr(Img[j, i].Blue + Generation[i, j], Img[j, i].Green + Generation[i, j], Img[j, i].Red + Generation[i, j]);
Img[j, i] = Q;
}
}
}
/// <summary>
/// Импульсный шум
/// </summary>
/// <param name="Img"></param>
private void INoise(Image<Bgr, byte> Img)
{
double Sum = Img.Height * Img.Width;
double N = 100;
for (int i = 0; i < Img.Height - 1; i++)
{
for (int j = 0; j < Img.Width - 1; j++)
{
if (Rnd.NextDouble() > (Sum - N) / (Sum))
{
Img[i, j] = new Bgr(255, 255, 255);
}
}
}
}
/// <summary>
/// фильтр свертки с маской (Цветное изображение)
/// </summary>
/// <param name="Img"></param>
/// <param name="k"></param>
/// <returns></returns>
private Image<Bgr, byte> MaskFilter(Image<Bgr, byte> Img, float[,] k)
{
ConvolutionKernelF kernel = new ConvolutionKernelF(k);
Image<Bgr, float> Res0 = Img * kernel;
Image<Bgr, byte> Result = Res0.Convert<Bgr, byte>();
return Result;
}
/// <summary>
/// медианный фильтр
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> MedianFilter(Image<Bgr, byte> Img)
{
Image<Bgr, byte> Result = new Image<Bgr, byte>(Img.Width, Img.Height);
Result = Img.SmoothMedian(3);
return Result;
}
/// <summary>
/// фильтр к-ближайших соседей
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> KNearestFilter(Image<Bgr, Byte> Img)
{
Image<Bgr, byte> Result = new Image<Bgr, byte>(Img.Width, Img.Height);
int[] Box = new int[3];
int Steps = 0;
byte Level = 20;
for (int i = 1; i < (Img.Height - 2); i++)
{
for (int j = 1; j < (Img.Width - 2); j++)
{
Steps = 0;
Box[0] = 0;
Box[1] = 0;
Box[2] = 0;
for (int k = -1; k < 2; k++)
{
for (int z = -1; z < 2; z++)
{
if (Math.Abs(Img[i, j].Red - Img[i + k, j + z].Red) < Level && Math.Abs(Img[i, j].Blue - Img[i + k, j + z].Blue) < Level && Math.Abs(Img[i, j].Green - Img[i + k, j + z].Green) < Level)
{
Steps++;
Box[0] += Convert.ToInt32(Img[i + k, j + z].Blue);
Box[1] += Convert.ToInt32(Img[i + k, j + z].Green);
Box[2] += Convert.ToInt32(Img[i + k, j + z].Red);
}
}
}
Result[i, j] = new Bgr(Box[0] / Steps, Box[1] / Steps, Box[2] / Steps);
}
}
for (int i = 0; i < Img.Height - 1; i++)
{
Result[i, 0] = Img[i, 0];
Result[i, Img.Width - 1] = Img[i, Img.Width - 1];
}
for (int j = 0; j < Img.Width - 1; j++)
{
Result[0, j] = Img[0, j];
Result[Img.Height - 1, j] = Img[Img.Height - 1, j];
}
return Result;
}
/// <summary>
/// взвешенный медианный фильтр
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> WeightedMedianFilter(Image<Bgr, Byte> Img)
{
Image<Bgr, byte> Result = new Image<Bgr, byte>(Img.Width, Img.Height);
List<double> BoxRed = new List<double>();
List<double> BoxGreen = new List<double>();
List<double> BoxBlue = new List<double>();
for (int i = 1; i < (Img.Height - 2); i++)
{
for (int j = 1; j < (Img.Width - 2); j++)
{
BoxRed.Clear();
BoxRed.Add(Img[i - 1, j - 1].Red);
BoxRed.Add(Img[i + 1, j - 1].Red);
BoxRed.Add(Img[i - 1, j + 1].Red);
BoxRed.Add(Img[i + 1, j + 1].Red);
BoxRed.Add(Img[i, j - 1].Red);
BoxRed.Add(Img[i, j + 1].Red);
BoxRed.Add(Img[i - 1, j].Red);
BoxRed.Add(Img[i + 1, j].Red);
BoxRed.Add(Img[i, j - 1].Red);
BoxRed.Add(Img[i, j + 1].Red);
BoxRed.Add(Img[i - 1, j].Red);
BoxRed.Add(Img[i + 1, j].Red);
BoxRed.Add(Img[i, j].Red);
BoxRed.Add(Img[i, j].Red);
BoxRed.Add(Img[i, j].Red);
BoxGreen.Clear();
BoxGreen.Add(Img[i - 1, j - 1].Green);
BoxGreen.Add(Img[i + 1, j - 1].Green);
BoxGreen.Add(Img[i - 1, j + 1].Green);
BoxGreen.Add(Img[i + 1, j + 1].Green);
BoxGreen.Add(Img[i, j - 1].Green);
BoxGreen.Add(Img[i, j + 1].Green);
BoxGreen.Add(Img[i - 1, j].Green);
BoxGreen.Add(Img[i + 1, j].Green);
BoxGreen.Add(Img[i, j - 1].Green);
BoxGreen.Add(Img[i, j + 1].Green);
BoxGreen.Add(Img[i - 1, j].Green);
BoxGreen.Add(Img[i + 1, j].Green);
BoxGreen.Add(Img[i, j].Green);
BoxGreen.Add(Img[i, j].Green);
BoxGreen.Add(Img[i, j].Green);
BoxBlue.Clear();
BoxBlue.Add(Img[i - 1, j - 1].Blue);
BoxBlue.Add(Img[i + 1, j - 1].Blue);
BoxBlue.Add(Img[i - 1, j + 1].Blue);
BoxBlue.Add(Img[i + 1, j + 1].Blue);
BoxBlue.Add(Img[i, j - 1].Blue);
BoxBlue.Add(Img[i, j + 1].Blue);
BoxBlue.Add(Img[i - 1, j].Blue);
BoxBlue.Add(Img[i + 1, j].Blue);
BoxBlue.Add(Img[i, j - 1].Blue);
BoxBlue.Add(Img[i, j + 1].Blue);
BoxBlue.Add(Img[i - 1, j].Blue);
BoxBlue.Add(Img[i + 1, j].Blue);
BoxBlue.Add(Img[i, j].Blue);
BoxBlue.Add(Img[i, j].Blue);
BoxBlue.Add(Img[i, j].Blue);
BoxRed.Sort();
BoxGreen.Sort();
BoxBlue.Sort();
Result[i, j] = new Bgr(BoxBlue[8], BoxGreen[8], BoxRed[8]);
}
}
for (int i = 0; i < Img.Height-1; i++)
{
Result[i, 0] = Img[i, 0];
Result[i, Img.Width - 1] = Img[i, Img.Width - 1];
}
for (int j = 0; j < Img.Width-1; j++)
{
Result[0, j] = Img[0, j];
Result[Img.Height - 1, j] = Img[Img.Height - 1, j];
}
return Result;
}
/// <summary>
/// пороговая сегментация
/// </summary>
/// <param name="Img"></param>
/// <param name="LowLevel"></param>
/// <param name="HightLevel"></param>
/// <returns></returns>
private Image<Bgr, byte> Segmentation(Image<Bgr, Byte> Img, int LowLevel, int HightLevel)
{
Image<Gray, byte> Result = new Image<Gray, byte>(Img.Width, Img.Height);
Result = Img.Convert<Gray,byte>();
Result = Result.ThresholdBinary(new Gray(LowLevel), new Gray(HightLevel));
return Result.Convert<Bgr, byte>();
}
/// <summary>
/// алгоритм водораздела
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> WaterFilter(Image<Bgr, Byte> Img)
{
Image<Bgr, byte> Result = new Image<Bgr, byte>(Img.Width, Img.Height);
Result = Img;
Image<Bgr, byte> Water = new Image<Bgr, byte>(Img.Width, Img.Height);
Water = MedianFilter(Img.Erode(6));
Water = MedianFilter(Img.Dilate(3));
Water = Water / 86;
Water = Water.Convert<Bgr, Int32>().Convert<Bgr, byte>() * 86;
Water = MedianFilter(Water);
Image<Gray, byte> Kenny = new Image<Gray, byte>(Img.Width, Img.Height);
Kenny = Water.Canny(0, 250);
Result = Water - Kenny.Convert<Bgr, byte>();
return Result;
}
/// <summary>
/// оконтуривание Превита (Для входящего цветного изображения)
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> PrevitContur(Image<Bgr, Byte> Img)
{
Image<Gray, byte> Result = new Image<Gray, byte>(Img.Width, Img.Height);
float[,] PrevitMask = new float[3, 3] { { 1f, 0f, -1f }, { 1f, 0f, -1f }, { 1f, 0f, -1f } };
Result = MaskFilter(Img, PrevitMask).Convert<Gray,byte>();
return Result.Convert<Bgr,byte>();
}
/// <summary>
/// оконтуривание Лапласа (Для входящего цветного изображения)
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> LaplasContur(Image<Bgr, Byte> Img)
{
Image<Gray, byte> Result = new Image<Gray, byte>(Img.Width, Img.Height);
Result = Img.Convert<Gray,byte>();
Result = Result.Laplace(3).Convert<Gray,byte>();
return Result.Convert<Bgr, byte>();
}
/// <summary>
/// оконтуривание Кирша (Для входящего цветного изображения)
/// </summary>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr, byte> KirshContur(Image<Bgr, Byte> Img)
{
Image<Gray, byte> Result = new Image<Gray, byte>(Img.Width, Img.Height);
float[,] KirshMask = new float[3, 3] { { -3f, 5f, 5f }, { -3f, 0f, 5f }, { -3f, -3f, -3f } };
Result = MaskFilter(Img, KirshMask).Convert<Gray,byte>();
return Result.Convert<Bgr,byte>();
}
/// <summary>
/// Жук
/// </summary>
/// <param name="Start">Первая точка контура</param>
/// <param name="Img"></param>
/// <returns></returns>
private Image<Bgr,byte> Bug(Point Start,Image<Bgr,byte> Img)
{
Image<Gray, byte> Contur = new Image<Gray, byte>(Img.Width, Img.Height);
int lastMove = 2;
byte positionColor = 0;
Point P = Start;
int NullElements = 55555;
Contur[P.Y, P.X] = new Gray(255);
do
{
if (lastMove == 0)
{
if (positionColor == 0)
{
P.X = P.X;
P.Y = P.Y + 1;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 3;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
else
{
P.X = P.X;
P.Y = P.Y - 1;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 1;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
}
if (lastMove == 1)
{
if (positionColor == 0)
{
P.X = P.X - 1;
P.Y = P.Y;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 0;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
else
{
P.X = P.X + 1;
P.Y = P.Y;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 2;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
}
if (lastMove == 2)
{
if (positionColor == 0)
{
P.X = P.X;
P.Y = P.Y - 1;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 1;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
else
{
P.X = P.X;
P.Y = P.Y + 1;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 3;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
}
if (lastMove == 3)
{
if (positionColor == 0)
{
P.X = P.X + 1;
P.Y = P.Y;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 2;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
else
{
P.X = P.X - 1;
P.Y = P.Y;
Contur[P.Y, P.X] = new Gray(255);
lastMove = 0;
positionColor = (byte)Img[P.Y, P.X].Blue;
}
}
NullElements--;
}
while (NullElements > 0);
return Contur.Convert<Bgr, byte>();
}
//-----------РАБОТА-ПРИЛОЖЕНИЯ--------------------------------------
private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
{
Picture = OpenTheImage();
PictureSet.Clear();
PictureSet.Add(Picture);
Steps = 1;
button1.Enabled = false;
button2.Enabled = false;
imageBox.Image = Picture;
tabControl1.Enabled = true;
}
private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveTheImage(Picture);
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
Mask[e.ColumnIndex, e.RowIndex] = Convert.ToDouble(dataGridView1[e.ColumnIndex, e.RowIndex].Value);
kern[e.ColumnIndex, e.RowIndex] = (float) Mask[e.ColumnIndex, e.RowIndex];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (dataGridView1[i, j].Value == null)
{
button3.Enabled = false;
i = 3;
j = 3;
}
else
{
button3.Enabled = true;
}
}
}
}
private void button4_Click(object sender, EventArgs e)
{
Picture = ConvertToGray(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button5_Click(object sender, EventArgs e)
{
Picture = RotateRight(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button6_Click(object sender, EventArgs e)
{
Picture = RotateLeft(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button7_Click(object sender, EventArgs e)
{
ANoise(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button8_Click(object sender, EventArgs e)
{
INoise(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button9_Click(object sender, EventArgs e)
{
Picture = MedianFilter(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button10_Click(object sender, EventArgs e)
{
Picture = KNearestFilter(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button11_Click(object sender, EventArgs e)
{
Picture = WeightedMedianFilter(Picture);
AddToSet();
imageBox.Image = Picture;
}
private void button3_Click(object sender, EventArgs e)
{
Picture = MaskFilter(Picture,kern);
AddToSet();
imageBox.Image = Picture;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
label2.Text = trackBar1.Value.ToString();
imageBox.Image = Segmentation(Picture, trackBar1.Value, 255);
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
trackBar1.Enabled = true;
if (radioButton1.Enabled == true)
{
imageBox.Image = Segmentation(Picture, trackBar1.Value, 255);
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
trackBar1.Enabled = false;
if (radioButton2.Enabled == true)
{
imageBox.Image = WaterFilter(Picture);
}
}
private void radioButton3_CheckedChanged(object sender, EventArgs e)
{
trackBar1.Enabled = false;
if (radioButton3.Enabled == true)
{
imageBox.Image = PrevitContur(Picture);
}
}
private void radioButton4_CheckedChanged(object sender, EventArgs e)
{
trackBar1.Enabled = false;
if (radioButton4.Enabled == true)
{
imageBox.Image = LaplasContur(Picture);
}
}
private void radioButton5_CheckedChanged(object sender, EventArgs e)
{
trackBar1.Enabled = false;
if (radioButton5.Enabled == true)
{
imageBox.Image = KirshContur(Picture);
}
}
private void button12_Click(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
Picture = Segmentation(Picture,trackBar1.Value,255);
}
if (radioButton2.Checked == true)
{
Picture = WaterFilter(Picture);
}
if (radioButton3.Checked == true)
{
Picture = PrevitContur(Picture);
}
if (radioButton4.Checked == true)
{
Picture = LaplasContur(Picture);
}
if (radioButton5.Checked == true)
{
Picture = KirshContur(Picture);
}
AddToSet();
imageBox.Image = Picture;
}
private void AddToSet()
{
if (Steps != PictureSet.Count())
{
PictureSet.RemoveRange(Steps, (PictureSet.Count() - Steps));
}
PictureSet.Add(Picture);
Steps++;
if (Steps > 1)
{
button1.Enabled = true;
}
else
{
button1.Enabled = false;
}
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
if (Steps > 1)
{
Steps--;
Picture = PictureSet[Steps - 1];
button2.Enabled = true;
}
if (Steps == 1)
{
button1.Enabled = false;
}
imageBox.Image = Picture;
}
private void button2_Click(object sender, EventArgs e)
{
if (Steps < PictureSet.Count)
{
Steps++;
Picture = PictureSet[Steps-1];
button1.Enabled = true;
}
if (Steps >= PictureSet.Count)
{
button2.Enabled = false;
}
imageBox.Image = Picture;
}
private void button13_Click(object sender, EventArgs e)
{
Point P = new Point(1,Picture.Height / 2);
while (Picture[P.Y, P.X].Blue != 0)
{
P.X++;
}
imageBox.Image = Bug(P, Picture);
}
}
}
