Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

МУ по VC++

.pdf
Скачиваний:
45
Добавлен:
09.02.2015
Размер:
1.53 Mб
Скачать

МИНОБРНАУКИ

Санкт-Петербургский государственный электротехнический университет «ЛЭТИ»

Кафедра САПР

Ш. С. Фахми

МЕТОДИЧЕСКИЕ УКАЗАНИЯ

по дисциплине

«Алгоритмы и структуры данных»

к лабораторным работам

«МЕТОДЫ ОБРАБОТКИ ИЗОБРАЖЕНИЙ»

Санкт-Петербург

2014

Общая характеристика и требования к отчету

Комплексная цель цикла лабораторных работ: изучение алгоритмов пространственной обработки изображений и их программная реализация.

Варианты заданий и цифровые изображения выдаются преподавателем перед началом выполнения лабораторной работы. Лабораторные работы выполняются индивидуально.

По результатам выполненных работ студент сдает преподавателю на проверку:

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

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

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

В методических указаниях также приведены примеры реализации алгоритмов обработки изображений на языке программирования MS Visual C++ 2010.

Функции завершенной программы:

загрузка изображения заданного формата;

сохранение обработанного изображения в заданном формате;

перевод цветного изображения в полутоновое;

пороговая бинаризация изображения (предусмотреть возможность изменения порога);

фильтрация изображения;

изменение контрастности изображения (желательно отображение гистограммы);

обнаружение линий и выделение контуров;

поиск объектов на изображении (необходимо предусмотреть отображение эталона и обрабатываемого изображения, выделение присутствующих объектов на изображении).

2

Рис. 1 Пример диалогового окна программы обработки изображений

3

Введение

Создание начального проекта в MS Visual C++ 2010

Запустите MS Visual C++ 2010. Перед вами откроется главное окно программы, представленное на рисунке 1.

Рис.1 – Главное окно MS Visual C++ 2010

Создайте новый проект. Для этого выполните последовательность команд: File New Project. Перед вами появится окно создание проекта, представленное на рисунке 2.

4

Рис. 2 – Окно New Project

В левой части окна выберите шаблоны Visual C++. Затем в средней части выберите Windows Forms Application. Введите имя проекта и

укажите его расположение. Нажмите кнопку ОК.

Главное окно MS Visual C++ 2010 примет вид, изображенный на рисунке 3.

5

Рис. 3 – Новый проект

В рабочей области окна расположен макет главного окна вашей будущей программы. На форму можно добавлять управляющие элементы с панели элементов View Toolbox, по умолчанию расположено слева (или справа) от рабочей области.

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

ВMS Visual C++ 2010 отображение графической информации можно выполнить с помощью компонента PictureBox, который находится во вкладке Стандартные элементы управления Панели элементов.

Расположим на форме один элемент PictureBox, семь элементов TextBox, семь элементов Label, один элемент OpenFileDialog, один элемент SaveFileDialog и четыре элемента Button, так чтобы форма приняла вид, изображённый на рисунке 4.

6

Рис. 4 – Форма будущей программы

Программа, приведенная в Листинг 1, по щелчку на соответствующей кнопке загружает в компонент изображение, выбранное в диалоговом окне Open. Затем она отображает в нескольких полях редактирования основную информацию об этом изображении. В данном проекте для имен компонентов используется значения, действующие по умолчанию. Щёлкните дважды по соответствующей кнопке. Откроется редактор кода. В функцию обработки нажатия клавиши введите код, представленный в листинге 1.

Листинг 1 Загрузка изображения и получение информации о нем

Bitmap^ MyImage; Bitmap^ MyImageDefault; private:

System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { Stream^ myStream;

OpenFileDialog^ openFileDialog1 = gcnew OpenFileDialog; openFileDialog1->Filter = "Bmp files (*.bmp)|*.BMP";

if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK )

{

if ( (myStream = openFileDialog1->OpenFile()) != nullptr )

{

MyImage = gcnew Bitmap( openFileDialog1->FileName ); MyImageDefault = gcnew Bitmap( MyImage ); pictureBox1->SizeMode = PictureBoxSizeMode::StretchImage; pictureBox1->ClientSize = System::Drawing::Size( 256, 256 ); pictureBox1->Image = dynamic_cast<Image^>(MyImage); textBox1->Text = openFileDialog1->FileName;

textBox2->Text = String::Format( "{0}", MyImage->Width ); textBox3->Text = String::Format( "{0}", MyImage->Height );

7

textBox4->Text = String::Format( "{0}", MyImage->PixelFormat ); myStream->Close();

}

}

}

Первый оператор отображает диалоговое окно Открыть в виде объекта OpenFileDialog1 типа OpenFileDialog, с использованием фильтра для BMP-файлов. Если это диалоговое окно возвращает ненулевой указатель, значит, пользователь выбрал файл, который затем загружается в «растровый» компонент PictureBox1. Для получения информации нужно получить доступ к свойствам компонента MyImage. В частности, PixelFormat – это свойство перечислимого типа, указывающего формат данных о цвете для каждого пикселя изображения. Формат пикселей определяет количество бит памяти, связанных с данными одной точки. Также этот формат определяет порядок цветовых составляющих в данных одного пикселя.

Для хранения графических объектов, содержащихся в битовых матрицах, в MS Visual C++ 2010 определен класс Bitmap. Таким образом, запомнить содержимое графического изображения и затем восстанавливать его, если оно будет испорчено или изменено пользователем можно с использованием объекта типа Bitmap. Код, решающий эту задачу, может иметь вид:

//Сохранение изображения private:

System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { Stream^ myStream;

SaveFileDialog^ saveFileDialog1 = gcnew SaveFileDialog; saveFileDialog1->Filter = "Bmp files (*.bmp)|*.BMP";

if ( saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK )

{

if ( (myStream = saveFileDialog1->OpenFile()) != nullptr )

{

try

{

if ( pictureBox1->Image != nullptr )

{

pictureBox1->Image->Save( saveFileDialog1->FileName, System::Drawing::Imaging::ImageFormat::Bmp );

}

}

catch ( Exception^ )

{

MessageBox::Show( "There was a problem saving the file." "Check the file permissions." );

}

myStream->Close();

}

}

}

//Восстановление изображения private:

System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { if ( MyImage != nullptr )

{

pictureBox1->SizeMode = PictureBoxSizeMode::StretchImage; pictureBox1->ClientSize = System::Drawing::Size( 256, 256 );

8

pictureBox1->Image = dynamic_cast<Image^>(MyImageDefault); MyImage = gcnew Bitmap( MyImageDefault );

}

}

В процедуре button2_Click создаётся объект saveFileDialog1 типа SaveFileDialog с использованием фильтра для BMP-файлов. Затем с помощью методов ShowDialog и OpenFile пользователю предоставляется возможность выбрать директорию и имя сохраняемого файла. После этого в выбранный файл сохраняется содержимое объекта pictureBox1.

Если же надо восстановить в pictureBox1 прежнее изображение, испорченное по каким-то причинам, то это можно сделать с помощью процедуры button3_Click, которая сначала устанавливает необходимые свойства объекта pictureBox1, а затем свойству Image присваивает исходное изображение.

Доступ к значениям отдельных пикселей изображений

Доступ можно получить с помощью метода GetPixel компонента Bitmap. Этот метод имеет два параметра – X и Y, измеряемые начиная от верхнего левого угла изображения. В Листинг 2 демонстрируется, как получить доступ к позиции мыши и значению пикселей, а также показать пользователю перемещение указателя мыши по изображению. Эту информацию можно увидеть в трех полях редактирования. Создайте обработчик события MouseMove. Для этого на вкладке свойств формы нужно перейти в раздел методов и дважды щёлкнуть мышкой в строчке метода MouseMove. Затем вводим код, представленный ниже

Листинг 2 Получение значения пикселя при перемещении указателя

System::Void pictureBox1_MouseMove(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {

textBox5->Text = String::Format( "{0}", e->X ); textBox6->Text = String::Format( "{0}", e->Y ); if ( MyImage != nullptr )

{

Color pixelColor = MyImage->GetPixel( e->X, e->Y ); textBox7->Text = String::Format( "{0}", pixelColor );

}

}

Текущая координата мыши передается в обработчик события в качестве параметров X и Y. Значение пикселя имеет тип Color, а его интерпретация зависит от значения свойства PixelFormat. Для изображений в оттенках серого каждый оттенок содержится в младшем байте значения пикселя. Для 24-разрядных цветных изображений младшие три байта представляют RGB - интенсивности для синего, зеленого и красного, соответственно. Значение $00FF0000 представляет синий цвет, $0000FF00 – зеленый, а $000000FF – красный.

Установить значение пикселя можно с помощью метода SetPixel. Например, после добавления следующего кода в обработчик событий MouseMove будет нарисована линия, повторяющая движение указателя мыши.

MyImage->SetPixel( e->X, e->Y, Color::White);

9

pictureBox1->Image = dynamic_cast<Image^>(MyImage);

В Листинг 3 представлен пример преобразования цветного изображения в полутоновое.

Листинг 3 Преобразование в полутоновое изображение

private:

System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) { if ( MyImage != nullptr )

{

for (int x=0; x<MyImage->Width; x++)

{

for (int y=0; y<MyImage->Height; y++)

{

Color pixelColor = MyImage->GetPixel( x, y ); Byte Y =

(int)(pixelColor.R*0.3+pixelColor.G*0.59+pixelColor.B*0.11);

Color newColor = Color::FromArgb( Y, Y, Y ); MyImage->SetPixel( x, y, newColor );

}

}

pictureBox1->SizeMode = PictureBoxSizeMode::StretchImage; pictureBox1->ClientSize = System::Drawing::Size( 256, 256 ); pictureBox1->Image = dynamic_cast<Image^>(MyImage);

}

}

10