Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Записка_моя.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.69 Mб
Скачать

4 Программная реализация

4.1 Схема программного обеспечения

В качестве среды разработки данного приложения выбрана Microsoft Visual Studio 2010, т.к. она предоставляет широкие возможности для работы с изображениями.

Приложение представляет собой проект kursovai.sln, в который включены следующие модули (Рисунок 4.1):

  • MainForm.cs – модуль главного окна программы;

  • Note.cs – модуль, содержащий алгоритм по распознаванию нот;

  • Bmp.cs – модуль, содержащий методы для подготовке изображения с дальнейшему распознаванию;

  • Play.cs – модуль, хранящий методы для проигрывания распознанных нот.

Рисунок 4.1.1 – Архитектура программы

4.2 Описание разработанных классов, функций, методов

В ходе работы был реализованы следующий класс:

class PrepareBmp:Object – класс, содержащий методы для подготовки изображения к распознаванию.

В данном классе разработаны следующие методы:

  • public double getAngle(Bitmap bmp) – метод находящий угол на который необходимо повернуть изображение;

  • public Bitmap RotateImage(Bitmap image, float angle) – метод возвращающий повёрнутое изображение;

  • public Bitmap Binary (Bitmap bmp) – метод бинаризирующий изображение;

class MainFrom – класс, обрабатывающий работу формы и нажатие кнопок:

  • private void auto_rotare_Click(object sender, EventArgs e) – метод обрабатывающий кнопку по которой происходит автоматический поворот изображения;

  • private void btn_play_Click(object sender, EventArgs e) – метод, запускающий воспроизведение найденных нот.

  • private void rotare_ValueChanged(object sender, EventArgs e) – метод, для ручного поворота изображения.

class Play – класс, содержащий метод, для воспроизведения нот.

  • public void Play (string note, int time) – метод для воспроизведения ноты.

Рисунок 4.2.1 - Диаграмма используемых классов

Рисунок 4.2. 2 - Диаграмма используемых классов и методов

4.3 Тестовый пример и руководство пользователя

После загрузки приложения на вкладке «изображение» необходимо нажать кнопку «открыть» для загрузки изображения. Результат выполнения представлен на рисунке 4.3.1

Рисунок 4.3.1 – Результат загрузки изображения

Далее после загрузки, необходимо выполнить поворот изображения. Для это требуется нажать кнопку «Поворот», после чего произойдет автоматический поворот изображения. Если же пользователю необходимо выполнить поворот изображения на определенный угол, то перед нажатием н акнопку, необходимо выбрать значение угла поворота в CheckBox, который находится под кнопкой «Поворот». Результат выполнения представлен на рисунке 4.3.2

Рисунок 4.3.3 – Результат поворота изображения

Следующим этапом является выполнение бинаризации, для этого требуется нажать кнопку «Бинаризация». Результат представлен на рисунке 4.3.4

Рисунок 4.3.4 – Результат бинаризации изображения

После предварительной подготовки изображения следует распознавание нот, при этом автоматически выполняется сегментация нотного стана и скрипичного ключа. Для это требуется нажать кнопку «Распознать» и перейти на вкладку «Итог», чтобы увидеть результат, нажать кнопку «Играть», для того чтоб прослушить мелодию (рисунок 4.3.5)

Рисунок 4.3.5 – Результат распознавания нот

Следующим шагом, является отделение нот от нотного стана, для этого требуется нажать кнопку «Отделить ноты» на вкладке «Итог». Результат представлен на рисунке 4.3.6

Рисунок 4.3.6 - Результат отделения нот от нотного стана

Далее требуется вырезать ноту, чтобы произвести ее масштабирование. Для этого необходимо нажать кнопку «Вырезать ноту» и перейти на вкладку «Результат вырезания».

Рисунок 4.3.7 – Результат вырезания ноты

Далее происходит масшиабирование изображения для дальнейшего сохранения и передачи его на пересптрон. Для этого необходимо в TextBox ввести требуемый размер масштабирования и нажать на кнопку «Масштабировать». Результат представлен на рисунке 4.3.8

Рисунок 4.3.8 - Результат масштабирования

Далее требуется нажать кнопку «Сохранить» на вкладке «Результат вырезания». Откроится окно сохранения изображения и ввести имя . Результат представлен на изображении 4.3.9

Рисунок 4.3.9 – Окно для сохранения изображения

Далее следует определения длины ноты с помощью Персептрона. Необходимо задать размер изображения, т.е. ввести в TextBox данные и нажать на кнопку «Задать размер». Далее следует нажать кнопку «Открыть», для загрузки изображения.

Рисунок 4.3.10 – Окно загрузки изображения

Рисунок 4.3.11 – Результат загрузки изображения

Далее происходит обучение персептрона. Для это необходимо в выпадающем списке выбрать соответствующий класс данному изображению и нажать кнопку «Отнести к классу». Затем заново загрузить это же изображение и продолжать обучение до тех пор, пока н а выходе персептрона не будет верный ответ.

Рисунок 4.3.12 – Результат обучения персептрона

ЗАКЛЮЧЕНИЕ

В результате работы над данным курсовым проектом, было реализовано приложение, которое позволяет распознавать ноты на партитуре, воспроизводить, а также определять длину их звучания.

Однако, разработанное приложение позволяет распознавать только семь основных нот, относящихся к первой октаве.

При тестировании данного продукта в различных условиях, приложение показало довольно устойчивою работу и высокий процент распознавания нот. Но имеются недостатки, если партитура на изображении отклонена на некоторый угол своего изначального положения после сканирования.

Разработанное приложение является хорошей базой для реализации более серьезного продукта.

СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ

  1. Ковалева И.Л., «Алгоритмы обработки изображений», БНТУ, 2007

  2. Фисенко В.Т., Фисенко Т. Ю., «Компьютерная обработка и распознавание образов», Санкт-Петербург, 2008

  3. Гонсалес Р., Вудс Р., «Цифровая обработка изображений», Москва 2005

ПРИЛОЖЕНИЕ

UML диаграмма классов

Листинг программы

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Drawing.Imaging;

using System.Linq;

using System.Text;

using System.Windows.Forms;

//Добавление пространства имен

using System.Runtime.InteropServices;

using AForge.Imaging.Filters;

namespace kursachMRO

{

public partial class MainForm : Form

{

int first_black_right;

int first_black_left;

private List<Note> list;

private Bitmap ProcessedBitmap, InputBitmap;

PictureBox pic = new PictureBox();

private int begin_x;

private int begin_y; //Координаты картинки на исходном pictureBox.

bool resize = false;

private int scroller_vert = -1;

private int scroller_hor = -1;

/////////для персептрона

private Bitmap _img, _img1;

double AjCount;

int[,] masXiAj, masRA;

int[] masXi, mas_Rj;

int size;

List<int[]> listYj = new List<int[]>();

List<int[]> listLj = new List<int[]>();

List<int[]> listRj = new List<int[]>();

List<int[]> listNumbers = new List<int[]>();

int[] number0 = { 0, 0 };

int[] number1 = { 0, 1 };

int[] number2 = { 1, 0 };

int[] number3 = { 1, 1 };

// для вырезания области

[DllImport("user32.dll")]

public static extern int SendMessage(

int hWnd, // handle to destination window

uint Msg, // message

long wParam, // first message parameter

long lParam // second message parameter

);

//И вот сам таймер для скроллинга.

private void timer1_Tick(object sender, EventArgs e)

{

if (scroller_vert > -1)

{

SendMessage(panel2.Handle.ToInt32(), 277, 1, scroller_vert);

}

if (scroller_hor > -1)

{

SendMessage(panel2.Handle.ToInt32(), 276, 1, scroller_hor);

}

}

public MainForm()

{

listNumbers.Add(number0);

listNumbers.Add(number1);

listNumbers.Add(number2);

listNumbers.Add(number3);

InitializeComponent();

image1.Visible = false;

}

// identification

private void btn_Go_Click(object sender, EventArgs e)

{

if (ProcessedBitmap == null)

{

MessageBox.Show("Откройте файл");

}

else

{

list = Identification_Note((Bitmap)ProcessedBitmap);

String TextBoxString = "";

for (int i = 0; i < list.Count; i++)

{

TextBoxString += list[i].Name + ",";

// Play_Note(list[i].Name, list[i].Time);

}

textBox2.Text = TextBoxString;

MessageBox.Show("Смотри итог");

}

}

// open file

private void btn_OpenFile_Click(object sender, EventArgs e)

{

OpenFileDialog dialog = new OpenFileDialog();

dialog.Filter = "Image files (.bmp)|*.bmp";

if (dialog.ShowDialog() == DialogResult.OK)

{

this.path = dialog.FileName;

textBox1.Text = path;

InputBitmap = new Bitmap(path);

//pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

pictureBox1.Image = (Image)InputBitmap;

// pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;

this.ProcessedBitmap = new Bitmap(InputBitmap);

pictureBox2.Image = ProcessedBitmap;

textBox2.Text = "Make rotare image and then Click identificate note...";

//Делаем нашей картинке приёмнику родителем картинку источник.

pic.Parent = pictureBox2;

//Теперь делаем её прозрачной но задаём ей рамку BorderStyle.

pic.BackColor = Color.Transparent;

pic.SizeMode = PictureBoxSizeMode.AutoSize;

pic.BorderStyle = BorderStyle.FixedSingle;

pic.Visible = false;

listBox1.Items.Clear();

logging("Открыт файл");

}

}

// find etalons

private int[] findEtalonsPoint(int x, int yStart, int yFinish, Bitmap bmp)

{

int h = 0;

int[] mas = new int[5];

int colFreePixels = 5;

for (int i = yStart; i < yFinish - 5; i++)

{

if (bmp.GetPixel(x, i).R != 255)

{

int free = 0;

for (int j = 1; j <= colFreePixels; j++)

{

free++;

}

if (free == colFreePixels)

{

if (h == 5)

{

return null;

}

else

{

mas[h] = i;

i += colFreePixels;

h++;

}

}

}

}

return mas;

}

// подсчитать количество точек

private int pointCounter(int x, int yStart, int yFinish, Bitmap bmp)

{

int h = 0;

for (int i = yStart; i < yFinish; i++)

{

if (bmp.GetPixel(x, i).R != 255)

{

h++;

}

}

return h;

}

// подсчитать количество пикселей в блоках

private int countPixelInBlock(int x, int yStart, int yFinish, Bitmap bmp)

{

int blockWidth = 5;

int h = 0;

for (int i = yStart; i < yFinish; i++)

{

for (int j = 0; j < blockWidth; j++)

{

if (bmp.GetPixel(x + j, i).R != 255)

{

h++;

}

}

}

return h;

}

// координату с нотой

private Point findNote(int x, int[] etalons, int distanceBetweenLines, Bitmap bmp, out String note)

{

note = "";

int halfDist = (int)(distanceBetweenLines / 2);

int si = countPixelInBlock(x, etalons[1] + halfDist, etalons[2] + halfDist, bmp);

int la = countPixelInBlock(x, etalons[2], etalons[3], bmp);

int sol = countPixelInBlock(x, etalons[2] + halfDist, etalons[3] + halfDist, bmp);

int fa = countPixelInBlock(x, etalons[3], etalons[4], bmp);

int mi = countPixelInBlock(x, etalons[3] + halfDist, etalons[4] + halfDist, bmp);

int re = countPixelInBlock(x, etalons[4], etalons[4] + distanceBetweenLines, bmp);

int Do = countPixelInBlock(x, etalons[4] + halfDist, etalons[4] + distanceBetweenLines + halfDist, bmp);

int maxPixel = Math.Max(si, Math.Max(la, Math.Max(sol, Math.Max(fa, Math.Max(mi, Math.Max(re, Do))))));

if (maxPixel > distanceBetweenLines * 2)

{

if (maxPixel == si)

{ note = "si"; return new Point(x, etalons[2]); }

else if (maxPixel == la)

{

note = "la"; return new Point(x, etalons[2] + halfDist);

}

else if (maxPixel == sol) { note = "sol"; return new Point(x, etalons[3]); }

else if (maxPixel == fa) { note = "fa"; return new Point(x, etalons[3] + halfDist); }

else if (maxPixel == mi) { note = "mi"; return new Point(x, etalons[4]); }

else if (maxPixel == re) { note = "re"; return new Point(x, etalons[4] + halfDist); }

else if (maxPixel == Do) { note = "do"; return new Point(x, etalons[4] + distanceBetweenLines); }

}

return new Point();

}

// логирование

private void logging(String s)

{

listBox1.Items.Add(s);

}

private List<Note> Identification_Note(Bitmap bmp)

{

// выходная картинка

Bitmap resultBmp = new Bitmap(bmp.Width, bmp.Height);

// перья для рисования

Pen yellowPen = new Pen(Color.Yellow, 1);

Pen blackPen = new Pen(Color.Black, 1);

Pen redPen = new Pen(Color.Red, 1);

Pen black = new Pen(Color.Black,1);

Pen bluePen = new Pen(Color.Blue, 4);

Graphics g = Graphics.FromImage(resultBmp);

// ------

Point start = new Point();

Point finish = new Point();

// Point start_right = new Point();

Boolean flag_first_point = true;

Boolean flag_last_point = false;

List<Note> ListNote = new List<Note>();

SolidBrush red_brush = new SolidBrush(Color.Red);

SolidBrush black_brush = new SolidBrush(Color.Black);

SolidBrush newbrush = new SolidBrush(Color.Coral);

//////

int x_right=0, y_rignt=0;

bool stop_right = true;

bool stop_left = true;

int rectX = 0, rectY = 0;

//нахождение первого черного пикселя с правой стороны изображения

for (x_right = bmp.Width-1; x_right > 0; x_right--)

{

for (y_rignt = 0; y_rignt < bmp.Height; y_rignt++)

{

if (bmp.GetPixel(x_right, y_rignt).R == 0 && stop_right)

{

first_black_right = x_right;

stop_right = false;

}

}

}

// нахождение первого черного пикселя с левой соторны изображения

for (int x_left = 1; x_left < bmp.Width; x_left++)

{

for (int y_left = 1; y_left < bmp.Height; y_left++)

{

if (bmp.GetPixel(x_left,y_left).R==0 && stop_left)

{

first_black_left = x_left;

stop_left = false;

}

}

}

try

{

logging("Началось распознавание");

// цикл проходящий весь лист

for (int m = finish.Y + 10; m < bmp.Height; m++)

{

// находжение одной линейки нот

// первая точка

for (int o = 0; o < bmp.Width; o++)

{

if (bmp.GetPixel(o, m).R != 255)

{

g.DrawRectangle(blackPen, o, m, 1, 1);

// первая точка

if (flag_first_point)

{

start = new Point(o, m);

logging("Найдено начало скрипичного ключа");

flag_first_point = false;

}

}

// нахождение последней точки

if ((!flag_first_point) && (!flag_last_point) && (o == start.X) && (m > start.Y + 20))

{

int isFreeLine = 0; // если = 21 - пустая линия

// в диапозоне от -10 до 10 идёт поиск чёрных точек, если не найден то выделен скрипичный ключ

for (int l = -10; l <= 10; l++)

{

if (bmp.GetPixel(o + l, m + 1).R == 255)

{

isFreeLine++;

}

}

if (isFreeLine >= 21)

{

finish = new Point(o, m);

flag_first_point = true;

bool next_note = true;

bool flag_rec_etalons = true;

// расспознавание нот (цикл идёт в диапозоне от т старта до т. финишь)

int distanceBetweenLine = 0; // расстояние между 2мя линиями

int[] etalons = new int[5];

int colPixelsInEtalons = 0;

int pogreshnost = 0;

int len_red = etalons.Length;

for (int i = start.X + 10; i < bmp.Width - 5; i++)

{

// находим 5-линии

if (flag_rec_etalons)

{

if ((etalons = findEtalonsPoint(i, start.Y, finish.Y, bmp)) != null)

{

flag_rec_etalons = false;

// нарисуем точки эталонов

logging("Найдены линии");

// для прорисовки ключа желтого

rectY = finish.Y - start.Y;

rectX = rectY / 2;

for (int w = start.X - (rectX) / 3 - 2; w < i; w++)

{

for (int h = start.Y; h < rectY + start.Y + 1; h++)

{

if (bmp.GetPixel(w, h).R == 0)

{

g.DrawRectangle(yellowPen, w, h, 1, 1);

}

}

}

// количество точек в эталоне для сравнения

colPixelsInEtalons = pointCounter(i, start.Y, finish.Y, bmp);

//прорисовка красных линий

int width_red = first_black_right - first_black_left + 1;

for (int k = 0; k < etalons.Length; k++)

{

g.FillRectangle(red_brush, first_black_left - 1, etalons[k], width_red, colPixelsInEtalons / 5 + 2);

for (int q = 1; q < resultBmp.Width - 2; q++)

{

if (resultBmp.GetPixel(q, etalons[k]).R == 255 && resultBmp.GetPixel(q, etalons[k]).G == 0 && resultBmp.GetPixel(q, etalons[k]).B == 0)

{

if (resultBmp.GetPixel(q, etalons[k] - 1).A == 255 && resultBmp.GetPixel(q, etalons[k] - 1).R == 0 && resultBmp.GetPixel(q, etalons[k] - 1).B == 0 && resultBmp.GetPixel(q, etalons[k] - 1).B == 0)

{

g.FillRectangle(black_brush, q, etalons[k], colPixelsInEtalons / 5, colPixelsInEtalons / 5 + 1);

}

if (resultBmp.GetPixel(q, etalons[k] + 1).A == 255 && resultBmp.GetPixel(q, etalons[k] + 1).R == 0 && resultBmp.GetPixel(q, etalons[k] + 1).G == 0 && resultBmp.GetPixel(q, etalons[k] + 1).B == 0) {

g.FillRectangle(black_brush, q, etalons[k], colPixelsInEtalons / 5 , colPixelsInEtalons / 5 + 2);

}

}

}

}

logging("Количество точек в линиях - " + colPixelsInEtalons);

// находим расстояние между 2-мя линиями

distanceBetweenLine = etalons[1] - etalons[0];

pogreshnost = distanceBetweenLine / 4;

logging("Расстояние между 2мя линиями - " + distanceBetweenLine);

}

}

else

{

if ((pointCounter(i, start.Y, finish.Y, bmp) > colPixelsInEtalons + distanceBetweenLine / 2)

&& (pointCounter(i, start.Y, finish.Y, bmp) <= colPixelsInEtalons

+ distanceBetweenLine)

&& (next_note))

{

logging("Найдено скопление точек. Определяем ноту.");

String note;

Point p = findNote(i, etalons, distanceBetweenLine, bmp, out note);

if (!note.Equals(""))

{

g.DrawRectangle(bluePen, p.X, p.Y, 2, 2);

g.DrawString(note, new Font(FontFamily.GenericSansSerif, 10), Brushes.Red, new Point(p.X, p.Y));

ListNote.Add(new Note(note, 1000 / 4));

logging("Это нота - " + note);

i += distanceBetweenLine * 2;

}

next_note = false;

}

else if ((pointCounter(i, start.Y, finish.Y, bmp) >= colPixelsInEtalons - pogreshnost)

&& (pointCounter(i, start.Y, finish.Y, bmp) <= colPixelsInEtalons

+ pogreshnost))

{

next_note = true;

if (findEtalonsPoint(i, start.Y, finish.Y, bmp) != null)

{

etalons = findEtalonsPoint(i, start.Y, finish.Y, bmp);

}

}

}

}

break;

}

}

}

}

}

catch (Exception e)

{

MessageBox.Show("Ошибка: " + e);

}

// освобождаем ресурсы

blackPen.Dispose();

redPen.Dispose();

g.Dispose();

pictureBox3.Image = resultBmp;

pictureBox3.Invalidate();

return ListNote;

}

// play notes

private void btn_play_Click(object sender, EventArgs e)

{

Play pn = new Play();

for (int i = 0; i < list.Count; i++)

{

pn.Play_Note(list[i].Name, list[i].Time);

}

}

// определение угла поворота

public double getAngle(Bitmap bmp)

{

Pen greenPen = new Pen(Color.Green, 2);

Bitmap b = new Bitmap(bmp);

Graphics g = Graphics.FromImage(b);

Point p1 = new Point();

Point p2 = new Point();

// нахождение первой точки ( цикл x-середина, у-с верха)

int x = bmp.Width / 2;

for (int y = 0; y < bmp.Height; y++)

{

if (bmp.GetPixel(x, y).R != 255)

{

p1 = new Point(x, y);

g.DrawRectangle(greenPen, x, y, 2, 2);

break;

}

}

// нахождение второй точки

x = bmp.Width / 3;

for (int y = 0; y < bmp.Height; y++)

{

if (bmp.GetPixel(x, y).R != 255)

{

p2 = new Point(x, y);

g.DrawRectangle(greenPen, x, y, 2, 2);

break;

}

}

// вычисление угла

double a = Math.Abs(p1.Y - p2.Y);

double c = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y));

double angle = Math.Asin(a / c);

if (p1.Y > p2.Y) angle = (-angle) * 57.295779513;

else angle = angle * 57.295779513;

pictureBox2.Image = b;

pictureBox2.Invalidate();

return angle;

}

// поворот

public Bitmap RotateImage(Bitmap image, float angle)

{

Pen whitePen = new Pen(Color.White, 1);

if (image == null)

throw new ArgumentNullException("image");

const double pi2 = Math.PI / 2.0;

double oldWidth = (double)image.Width;

double oldHeight = (double)image.Height;

// Convert degrees to radians

double theta = ((double)angle) * Math.PI / 180.0;

double locked_theta = theta;

// Ensure theta is now [0, 2pi)

while (locked_theta < 0.0)

locked_theta += 2 * Math.PI;

double newWidth, newHeight;

int nWidth, nHeight; // The newWidth/newHeight expressed as ints

#region Explaination of the calculations

#endregion

double adjacentTop, oppositeTop;

double adjacentBottom, oppositeBottom;

if ((locked_theta >= 0.0 && locked_theta < pi2) ||

(locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)))

{

adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth;

oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth;

adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight;

oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight;

}

else

{

adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight;

oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight;

adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth;

oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth;

}

newWidth = adjacentTop + oppositeBottom;

newHeight = adjacentBottom + oppositeTop;

nWidth = (int)Math.Ceiling(newWidth);

nHeight = (int)Math.Ceiling(newHeight);

Bitmap rotatedBmp = new Bitmap(nWidth, nHeight);

using (Graphics g = Graphics.FromImage(rotatedBmp))

{

for (int i = 0; i < nWidth; i++)

{

for (int j = 0; j < nHeight; j++)

{

g.DrawRectangle(whitePen, i, j, 1, 1);

}

}

Point[] points;

if (locked_theta >= 0.0 && locked_theta < pi2)

{

points = new Point[] {

new Point( (int) oppositeBottom, 0 ),

new Point( nWidth, (int) oppositeTop ),

new Point( 0, (int) adjacentBottom )

};

}

else if (locked_theta >= pi2 && locked_theta < Math.PI)

{

points = new Point[] {

new Point( nWidth, (int) oppositeTop ),

new Point( (int) adjacentTop, nHeight ),

new Point( (int) oppositeBottom, 0 )

};

}

else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))

{

points = new Point[] {

new Point( (int) adjacentTop, nHeight ),

new Point( 0, (int) adjacentBottom ),

new Point( nWidth, (int) oppositeTop )

};

}

else

{

points = new Point[] {

new Point( 0, (int) adjacentBottom ),

new Point( (int) oppositeBottom, 0 ),

new Point( (int) adjacentTop, nHeight )

};

}

g.DrawImage(image, points);

}

return rotatedBmp;

}

// change angle

private void rotare_ValueChanged(object sender, EventArgs e)

{

this.ProcessedBitmap = RotateImage(InputBitmap, (float)numericUpDown1.Value);

pictureBox2.Image = ProcessedBitmap;

logging("Поворот на " + numericUpDown1.Value.ToString() + "градусов");

// ProcessedBitmap.Save(@"D:\pictFromKursach.bmp");

}

//бинаризация

private Bitmap Binarization(Bitmap bmp, int level)

{

Bitmap bmp_temp = bmp;

byte border = (byte)numericUpDown6.Value;

byte[,] img_current = new byte[bmp_temp.Width, bmp_temp.Height];

int proc_var = 0;

for (int i = 0; i < bmp_temp.Width; i++)

for (int j = 0; j < bmp_temp.Height; j++)

{

proc_var = (bmp_temp.GetPixel(i, j).R + bmp_temp.GetPixel(i, j).G + bmp_temp.GetPixel(i, j).B) / 3;

if ((byte)proc_var <= level)

bmp_temp.SetPixel(i, j, Color.Black);

else

bmp_temp.SetPixel(i, j, Color.White);

}

// MessageBox.Show("Бинаризация выполнена");

return bmp_temp;

}

private void button4_Click(object sender, EventArgs e)

{

// ProcessedBitmap = MakeGray(ProcessedBitmap);

ProcessedBitmap = Binarization(ProcessedBitmap, int.Parse(numericUpDown6.Value.ToString()));

pictureBox2.Image = ProcessedBitmap;

}

// для вырезания области

private void pictureBox2_MouseMove(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

pic.Width = e.X - begin_x;

pic.Height = e.Y - begin_y;

//Скроллинг...

scroller_hor = -1;

scroller_vert = -1;

if (e.X > panel2.Width - 5)

{ scroller_hor = 0; }

if (e.Y > panel2.Height - 5)

{ scroller_vert = 0; }

}

}

static public Image Copy(Image srcBitmap, Rectangle section)

{

// Вырезаем выбранный кусок картинки

Bitmap bmp = new Bitmap(section.Width, section.Height);

using (Graphics g = Graphics.FromImage(bmp))

{

g.DrawImage(srcBitmap, 0, 0, section, GraphicsUnit.Pixel);

}

//Возвращаем кусок картинки.

return bmp;

}

private void pictureBox2_MouseDown(object sender, MouseEventArgs e)

{

if (e.Button == MouseButtons.Left)

{

begin_x = e.X;

begin_y = e.Y;

pic.Left = e.X;

pic.Top = e.Y;

pic.Width = 0;

pic.Height = 0;

pic.Visible = true;

timer1.Start();

resize = true;

}

}

private void pictureBox2_MouseUp(object sender, MouseEventArgs e)

{

pic.Width = 0;

pic.Height = 0;

pic.Visible = false;

timer1.Stop();

if (resize == true)

{

if ((e.X > begin_x + 10) && (e.Y > begin_y + 10)) //Чтобы совсем уж мелочь не вырезал - и по случайным нажатиям не срабатывал! (можно убрать +10)

{

Rectangle rec = new Rectangle(begin_x, begin_y, e.X - begin_x, e.Y - begin_y);

ProcessedBitmap = (Bitmap)Copy(pictureBox2.Image, rec);

pictureBox2.Image = ProcessedBitmap;

}

}

resize = false;

}

// автоматический поворот

private void auto_rotare_Click(object sender, EventArgs e)

{

double angle = getAngle(InputBitmap);

// MessageBox.Show("Угол поворота = " + angle.ToString());

ProcessedBitmap = RotateImage(ProcessedBitmap, (float)angle);

numericUpDown1.Value = (decimal)angle;

//pictureBox2.Image = ProcessedBitmap;

logging("Автоповорот на " + angle.ToString() + "градусов");

}

private bool proverka(int h, int w)

{

//проверка на бинарное изображение

int count = 0;

for (int x = 0; x < w; x++)

{

for (int y = 0; y < h; y++)

{

if (_img.GetPixel(x, y).R == _img.GetPixel(x, y).G && _img.GetPixel(x, y).G == _img.GetPixel(x, y).B && (_img.GetPixel(x, y).R == 255 | _img.GetPixel(x, y).R == 0))

{

count += 1;

}

}

}

if (count == h * w)

return true;

else

return false;

}

private void button2_Click(object sender, EventArgs e)

{

OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.Filter = "Bitmap Image|*.bmp";

//открытие изображения

if (openFileDialog1.ShowDialog() == DialogResult.OK)

{

string openFilePath = openFileDialog1.FileName;

_img = new Bitmap(openFilePath);

//проверка типа изображения

if (proverka(_img.Height, _img.Width))

{

_img1 = _img;

image1.Visible = true;

image1.Image = _img1;

create_matrixX();

create_matrixYj();

create_matrixLj();

}

else

{

MessageBox.Show("Неправильные данные", "Ошибка");

}

}

}

private void matixXiAj_Click(object sender, EventArgs e)

{

// Инициализация размеров матрицы

int rowsCount = int.Parse(attributeRows.Text);

int columnsCount = int.Parse(attributeColumns.Text);

AjCount = Math.Round(rowsCount * columnsCount * 0.6);

size = rowsCount * columnsCount;

masXiAj = new int[size, Convert.ToInt32(AjCount)];

// Заполнение матрицы

for (int i = 0; i < size; i++)

{

for (int j = 0; j < AjCount; j++)

{

masXiAj[i, j] = 0;

}

}

Random rand = new Random();

int rand_value, rand_index;

for (int i = 0; i < size; i++)

{

rand_value = rand.Next(2);

rand_index = rand.Next(Convert.ToInt32(AjCount));

if (rand_value == 0)

masXiAj[i, rand_index] = -1;

else

masXiAj[i, rand_index] = 1;

}

create_matrixLj_random();

create_matrixRA();

}

private void create_matrixX()

{

int k = 0;

masXi = new int[size];

// Заполнение массива

for (int i = 0; i < _img1.Height; i++)

{

for (int j = 0; j < _img1.Width; j++)

{

if (_img1.GetPixel(j, i).R == 0)

masXi[k++] = 1;

else if (_img1.GetPixel(j, i).R == 255)

masXi[k++] = 0;

}

}

}

private void create_matrixYj()

{

int[] masYj = new int[Convert.ToInt32(AjCount)];

int sum = 0;

// Заполнение массива

for (int j = 0; j < AjCount; j++)

{

sum = 0;

for (int i = 0; i < size; i++)

{

sum += masXi[i] * masXiAj[i, j];

}

sum -= 1;

if (sum >= 0)

masYj[j] = 1;

else

masYj[j] = 0;

}

listYj.Add(masYj);

}

private void create_matrixLj_random()

{

int[] masLj = new int[Convert.ToInt32(AjCount)];

// Заполнение матрицы

Random rand = new Random();

int rand_value;

for (int j = 0; j < AjCount; j++)

{

rand_value = rand.Next(3);

masLj[j] = rand_value - 1;

}

listLj.Add(masLj);

}

private void create_matrixLj()

{

int[] last_Lj = listLj[listLj.Count - 1];

int[] last_Yj = listYj[listYj.Count - 1];

int[] masLj = new int[Convert.ToInt32(AjCount)];

int index_from, index_to, sum, sum_index;

// Формирование R кодов для текущего изображения

sum_index = 0;

mas_Rj = new int[2];

for (int i = 0; i < 2; i++)

{

index_from = sum_index;

index_to = index_from + masRA[i, 0];

sum_index += masRA[i, 0];

sum = 0;

for (int j = index_from; j < index_to; j++)

{

sum += last_Lj[j] * last_Yj[j];

}

if (sum >= 0)

mas_Rj[i] = 1;

else

mas_Rj[i] = 0;

}

listRj.Add(mas_Rj);

// Насройки отображения элемента DataGridView

dataGridTest.RowCount = listRj.Count;

dataGridTest.ColumnCount = 2;

dataGridTest.RowHeadersDefaultCellStyle.Padding = new Padding(0, 3, 0, 3);

for (int i = 0; i < listRj.Count; i++)

{

dataGridTest.Rows[i].HeaderCell.Value = Convert.ToString(i+1);

}

for (int j = 0; j < 2; j++)

{

dataGridTest.Columns[j].SortMode = ataGridViewColumnSortMode.NotSortable;

dataGridTest.Columns[j].HeaderText = "R" + Convert.ToString(j + 1);

}

for (int i = 0; i < listRj.Count; i++)

{

int[] temp_mas = listRj[i];

for (int j = 0; j < 2; j++)

{

dataGridTest.Rows[i].Cells[j].Value = temp_mas[j];

}

}

}

private void create_matrixRA()

{

// Привязка R элементов к соответсвующим А элементам

double count121 = Math.Round(AjCount / 2);

double count122 = AjCount - count121;

masRA = new int[2, 1];

masRA[0, 0] = Convert.ToInt32(count121);

masRA[1, 0] = Convert.ToInt32(count122);

}

// class note

public class Note

{

// название ноты

public string Name { get; set; }

// длительность звучания

public int Time { get; set; }

public Note(String Name, int Time)

{

this.Name = Name;

this.Time = Time;

}

}

private void button1_Click_1(object sender, EventArgs e)

{

int[] last_Lj = listLj[listLj.Count - 1];

int[] last_Yj = listYj[listYj.Count - 1];

int[] masLj = new int[Convert.ToInt32(AjCount)];

int[] mas_test = listNumbers[comboBox1.SelectedIndex];

int sum_index, index_from, index_to;

// Формирование матрицы Lj для текущего изображения

sum_index = 0;

int k = 0;

for (int i = 0; i < 2; i++)

{

if (mas_test[i] == 1)

k = 1;

else

k = -1;

index_from = sum_index;

index_to = index_from + masRA[i, 0];

sum_index += masRA[i, 0];

for (int j = index_from; j < index_to; j++)

{

if (last_Yj[j] == 1)

masLj[j] = last_Lj[j] + k;

else

masLj[j] = last_Lj[j];

}

}

listLj.Add(masLj);

}

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]