Алгоритмизации обработки изображений
Яркость точек и гистограммы изображения. Изменение яркости и контрастности. Метод ранговой фильтрации с оценкой середины диапазона. Наложение шумов на изображение. Преобразование изображения в негатив. Получение матрицы яркостей и построение гистограмм.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 11.12.2012 |
Размер файла | 1,5 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
Реферат
Пояснительная записка к курсовой работе: 23 страницы, 1 приложение, 12 рисунков.
Цель работы - практическое закрепление теоретической части курса и приобретение навыков алгоритмизации обработки изображений .
Яркость и контрастность, матрица яркостей, гистограмма, бинаризация, градации серого, негатив, наложение шумов, фильтрация.
СОДЕРЖАНИЕ
Введение
1. Лист заданий
2. Описание поставленных задач
2.1 Яркость точек и гистограммы изображения
2.2 Изменение яркости и контрастности
2.3 Бинаризация
2.4 Преобразование к оттенкам серого
2.5 Негатив
2.6 Наложение шумов на изображение
2.7 Метод ранговой фильтрации с оценкой середины диапазона
3. Алгоритмы используемых методов
3.1 Расчет таблицы яркостей. Построение гистограмм
3.2 Изменение баланса изображения
3.3 Бинаризация
3.4 Перевод в полутоновое изображение
3.5 Перевод в негатив
3.6 Наложение шумов на изображение
3.7 Метод ранговой фильтрации с оценкой середины диапазона
4. Описание разработанной программы
4.1 Стартовое окно и загрузка изображеня
4.2 Получение матрицы яркостей и построение гистограмм
4.3 Изменение яркости и контрастности изображения
4.4 Бинаризация изображения
4.5 Перевод изображения в градации серого
4.6 Преобразование изображения в неагтив
4.7 Наложение шумов на изображение
4.8 Метод ранговой фильтрации с оценкой середины диапазона
Вывод
Список используемой литературы
Приложение А
Введение
80 процентов всей информации человек получает средствами визуального контакта с окружающей средой, т.е. с помощью наших глаз. Человек с помощью зрения распознает объекты, воспринимает их размеры, форму и расположение в пространстве. В наше время этим активно пользуются, используя изображение практически во всем, и чем лучше будет качество изображения, чем лучше оно будет преподнесено, тем больше внимания на него обратят люди и тем больше информации усвоят, ведь гораздо приятнее смотреть на красивую, яркую фотографию, чем на какую-нибудь невзрачную картинку.
При просмотре хорошей фотографии человек запоминает и воспринимает гораздо больше деталей, что еще раз доказывает важность хорошего качества изображения. Сейчас имеется достаточно большое количество техники, которая может сфотографировать объекты, которые мы видим, но результат не всегда может «порадовать глаз». Изображения могут быть сильно яркими или темными, «полинявшими», зашумленными и т.д. Этот курсовой проект посвящен тому, как избавиться от некоторых таких проблем и улучшить (хоть и не на много) качество изображения.
1. Лист задания
1. Вывод изображения на экран.
2. Вывод на экран матрицы значений яркости изображения.
3. Построение гистограмм.
4. Изменение цветности:
· бинаризация (переход к чёрно-белому);
· переход к оттенкам серого;
· негатив
5. Возможность изменения яркости и контрастности.
6. Задание по варианту:
- метод ранговой фильтрации с оценкой середины диапазона.
2. Описание поставленных задач
2.1 Яркость точки и гистограммы изображения
Человеческий глаз более чувствителен к зеленому цвету, чем к красному и синему вместе взятым. Избыточность по зеленым пикселям дает изображение, которое кажется менее шумным и более четким, чем при равном количестве цветов. Яркость каждого пикселя находится по формуле:
Y:=0.3*R+0.59*G+0.11*B
Гистограмма - это представленная зависимость числа повторений каждого значения яркости на всём изображении от этого самого значения. Для изображения можно рассматривать 4 вида гистограмм: 3 по каналам(RGB) и одну по вычисленной яркости.
2.2 Изменение яркости и контрастности
Эти изменения можно обобщить выражением «изменение баланса изображения», так как яркость и контрастность схожи, и относятся к сфере восприятия изображения человеком, различие заключается в том, что яркость увеличивает или уменьшает количество белого (обесцвечивает) изображение, а контраст, наоборот, регулирует количество черного (теней).
Повышение/снижение яркости - это, соответственно, сложение/вычитание значения каждого канала с некоторым фиксированным значением в пределах от 0 до 255. Обязательно необходимо контролировать выход нового значения канала за пределы диапазона 0..255.
Повышение/снижение контрастности - это, соответственно, умножение/деление значения каждого канала на некоторое фиксированное значение. Это ведет к изменению соотношений между цветами и, соответственно, к более чётким цветовым границам. На практике существует такой принцип: изменение контрастности не должно приводить к изменению средней яркости по изображению, поэтому пользуются следующей формулой:
NewY:=K*(OldY-AveY)+AveY
В этой формуле NewY - новое значение одного из каналов, K - коэффициент контрастности (K=(0..1) - снижение, K<1 - повышение контрастности), OldY - текущее значение того же канала, AveY - среднее значение того же канала по изображению. Коррекция нового значения при выходе его за пределы 0..255 обязательна.
2.3 Бинаризация
Бинаризация - это преобразование изображения, в общем случае, к одноцветному (чаще всего к черно-белому). При выполнении бинаризации выбирается некий порог (например, 155), все значения ниже которого превращаются в цвет фона, а выше - в основной цвет. Само преобразование можно осуществлять по каналам, но в этом случае результирующее изображение не будет в прямом смысле бинарным (чёрно-белым), а будет содержать 8 чистых цветов, представляющих собой комбинации чистых красного, зелёного и голубого цветов, то есть будет бинарным по каналам. Поэтому лучше проводить преобразование над «полным» цветом точки.
2.4 Преобразование к оттенкам серого
Преобразование к оттенкам серого заключается в получении яркости каждой точки по известной ранее формуле Y:=0.3*R+0.59*G+0.11*B, а также в последующем копировании полученного значения в каждый из каналов RGB.
2.5 Негатив
Получение негатива происходит простой заменой каждого значения канала на его дополнение до 255. Например, R=255-R.
2.6 Наложение шумов на изображение
Шум изображения - это дефект качества цифрового снимка, который возникает из-за неправильной передачи цвета и яркости.
Для оценки работы фильтра на изображение необходимо для начала наложить некоторый искусственный шум. Зашумление можно выполнять любым способом, изменяющим каким-либо образом значения каких-то точек изображения. Алгоритмы наложения шумов (аддитивный, мультипликативный, импульсный) будут описаны дальше.
2.7 Метод ранговой фильтрации с оценкой середины диапазона
Фильтрация позволяет избавиться от существующего на изображении шума. Для фильтров характерно понятие апертуры фильтра - размера той части изображения, с которой непосредственно работает фильтр в данный момент времени. Это окно последовательно передвигается по изображению, пока не будет обработано все изображение.
Скользящее окно определяет особый вид передвижения апертуры фильтра, когда при достижении боковой границы изображения окно опускается на 1 пиксель вниз и начинает движение в обратном направлении. При этом на последующих шагах будут использоваться так же уже преобразованные ранее пиксели.
Новое значение яркости или насыщенности цветовых каналов центрального в окне пикселя устанавливается равным середине между максимальным и минимальными значениями яркости или насыщенности его соседей.
3. Алгоритмы используемых методов
3.1 Расчет таблицы яркостей. Построение гистограмм
Чтобы построить таблицу яркостей необходимо рассчитать уровни яркости для каждого пикселя и занести полученные значения в матрицу(DataGridView в нашем случае). Для каждого пикселя применяем формулу
Где i, j - координаты пикселя, для которого находится уровень яркости, -уровни соответствующих каналов для данного пикселя.
Для построения гистограмм необходимо подсчитать количество пикселей для каждого уровня яркости и для каждого уровня насыщенности по каналам RGB. При построении гистограммы яркостей можно воспользоваться рассчитанной таблицей яркости и подсчитать количество пикселей для каждого уровня яркости. После чего выполним построение гистограммы. Для гистограмм по каналам RGB необходимо проделать аналогичные операции, только над уровнями насыщенности каждого из каналов.
3.2 Изменение баланса изображения
Изменение яркости проводится по следующему алгоритму: необходимо считать уровни каждого из каналов пикселя, после чего к каждому из этих каналов прибавить некоторое фиксированное значение, которое будет показывать тип преобразования яркости: при увеличении яркости - значение будет положительным, а при уменьшении - отрицательным.
После суммирования текущего уровня каждого канала с фиксированным значением необходимо поместить полученные значения в соответствующие каналы, предварительно откорректировав значение, если оно вышло за пределы .
Для изменения контраста изображения необходимо для начала рассчитать среднее значение по каждому из каналов RGB для всего изображения.
Где N - количество пикселей, n-ширина, m-высота изображения, - уровни соответствующих каналов для пикселя по координатам .
После этого необходимо определить коэффициент преобразования K, а затем воспользоваться для значений каждого канала для каждого из пикселей формулами:
На следующем шаге необходимо поместить полученные значения в соответствующие каналы, предварительно откорректировав значение, если оно вышло за пределы . Приведенные выше формулы нужно применить для каждого пикселя в изображении.
3.3 Бинаризация
При выполнении бинаризации необходимо для начала найти порог бинаризации. В этих целях сначала строим гистограммы изображения, после чего по полученной гистограмме выбираем некоторое значение яркости, которое условно будет отделять фон изображения от объектов. Порог необходимо выбирать так, чтобы потерять как можно меньше деталей желаемого объекта и при этом избавиться от как можно большего количества фоновых объектов, которые не несут в себе полезной информации.
После преобразования изображение будет состоять только из пикселей двух цветов.
3.4 Перевод в полутоновое изображение
Преобразование изображения в полутоновое состоит в том, чтобы каждому пикселю по всем трем каналам RGB присвоить значение яркости этого пикселя. Поэтому сначала необходимо рассчитать яркость пикселя по формуле:
Затем полученное значение присваивается всем трем каналам:
В приведенных формулах i,j-координаты пикселя, - уровни соответствующих каналов для пикселя по координатам .
Данные преобразования необходимо выполнить для каждого пикселя для получения полутонового изображения.
3.5 Перевод в негатив
Преобразование изображения к его негативу состоит в том, что бы каждому из пикселей по всем трем каналам RGB присвоить новое значение, являющееся дополнением старого до 255.
Где -новые значения каналов, i,j-координаты пикселя.
3.6 Наложение шумов на изображение
Наложение шума состоит в том, что бы изменить значение составляющих канала нескольких случайных пикселей. Для наложения шумов сначала нужно определить, какое число пикселей будет зашумлено. Это число можно задать вручную либо воспользоваться генератором псевдослучайных чисел.
Затем необходимо сформировать случайные координаты в пределах изображения для этих пикселей. После чего для одного либо нескольких каналов RGB каждого из пикселей сформировать новое случайное значение. После чего присваивать измененным каналам новые значения.
3.6.1 Наложение аддитивного шума
Смысл аддитивного шума заключается в увеличении яркости или значения цвета пикселя на некоторую небольшую величину, значение которой должно быть различным (случайным) для каждой следующей точки.
3.6.2 Наложение мультипликативного шума
Смысл мультипликативного шума заключается в умножении яркости или значения цвета пикселя на некоторую небольшую величину, значения которой близки к 1 и в каждой точке различны (случайны).
3.6.3 Наложение импульсного шума
Смысл импульсного шума заключается в искажении яркости или цвета пикселя настолько, что он теряет всякую информацию о своем неискаженном значении.
3.7 Метод ранговой фильтрации с оценкой середины диапазона
Для выполнения фильтрации необходимо для начала выбрать размер апертуры фильтра. Обычно она берется размерами 3х3, но иногда есть смысл взять апертуру и большего размера. В общем случае окно фильтра будет выглядеть следующим образом:
Маска для ранговой фильтрации имеет следующий вид (можно ее и не учитывать):
Для каждого шага фильтр будет находить минимум и максимум, и находить среднее между ними, по всем трем каналам.
После чего окно будет смещаться на следующую позицию. При последующих вычислениях фильтр будет работать с окном, состоящим не только из элементов исходного изображения, но и из элементов, ранее подвергнувшихся преобразованию.
4. Описание разработанной программы
4.1 Стартовое окно и загрузка изображения
После запуска программы на экране появится форма, изображенная на рис. 4.1.1:
Рис. 4.1.1
Т. К. это программа для обработки изображений, то для начала работы необходимо загрузить изображение. Это можно осуществить тремя способами:
- на главной форме кликнув на кнопку «Загрузить изображение»;
- зайти в «Меню->Файл->Открыть»;
- горячей клавишей «Ctrl+O»;
Все эти три варианта приведут к появлению диалогового окна ,в котором можно выбрать изображения типа :*bmp, *.jpg, *.jpeg, *.png, *.tif, *.tiff. После загрузки изображения в программу оно будет отображено в окне главной формы, как показано на рис. 4.1.2:
Рис.4.1.2
4.2 Получение матрицы яркостей и построение гистограмм
Для получения матрицы яркостей загруженного ранее изображения необходимо кликнуть на кнопку «Матрица яркостей», после нескольких секунд ожидания на экране появится форма показанная на рис.4.2.3
Рис.4.2.3
В этих таблицах показаны значения яркостей по каждому пикселю, по трем каналам, а также выходной яркости. Любую из этих таблиц, при желании можно сохранить в Excel, перейдя в «Меню->Матрица->Сохранить_№».
Построение гистограмм можно выполнить двумя способами:
- на главной форме нажать на кнопку «Построение гистограмм»;
- после получения матриц яркостей в той же форме перейти в «Меню->Гистограмма->Построение»;
На экране появится форма, изображенная на рис. 4.2.4:
Рис.4.2.4
Все гистограммы также можно сохранить перейдя в «Меню->Гистограмма->Сохранение->Сохранить_№».
4.3 Изменение яркости и контрастности изображения
После загрузки изображения станут доступными бегунки «Яркость» и «Контрастность», при их перемещении будет происходить соответственно изменение яркости и контрастности(рис.4.3.1):
Рис.4.3.1
4.4 Бинаризация изображения
Перед началом бинаризации, необходимо выбрать порог бинаризации, который можно установить в поле рядом с кнопкой «Бинаризация»(рис.4.4.1):
Рис.4.4.1
После выбора порога и нажатия на кнопку «Бинаризация» изображение будет преобразовано и отображено в этом же окне(рис.4.4.2):
Рис.4.4.2
private void bBinary_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
BitmapData bitmap_data;
IntPtr bitmap_pixels;
unsafe
{
//Блокируем участок в памяти
bitmap_data = picture.LockBits(new Rectangle(0, 0, picture.Width, picture.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//Получаем указатель на первый пиксель
bitmap_pixels = bitmap_data.Scan0;
byte* bitmap_pbitS = (byte*)bitmap_pixels.ToPointer();
//Указываем, что точка будет занимать 3 байта
byte bytes_per_pixel = 3;
byte cc_binary = (byte)numericUpDown1.Value;
byte cc_r, cc_g, cc_b, cc_bright;
for (int x = 0; x < picture.Width; x++)
{
for (int y = 0; y < picture.Height; y++)
{
//Вычисляем указатель на точку, которая соответствует координатам x, y
byte* pixel_gr = (byte*)bitmap_pbitS + (y * bitmap_data.Stride) + (x * bytes_per_pixel);
//Считываем 3 компонента цвета
cc_b = *pixel_gr;
cc_g = *(pixel_gr + 1);
cc_r = *(pixel_gr + 2);
//Вычисляем яркость
cc_bright = (byte)Math.Round(cc_b * 0.3f + cc_g * 0.59f + cc_r * 0.11f);
//Устанавливаем в памяти компоненты цвета(белый или черный)
if (cc_bright > cc_binary)
{
*pixel_gr = 255;
pixel_gr++;
*pixel_gr = 255;
pixel_gr++;
*pixel_gr = 255;
}
else
{
*pixel_gr = 0;
pixel_gr++;
*pixel_gr = 0;
pixel_gr++;
*pixel_gr = 0;
}
}
}
picture.UnlockBits(bitmap_data);
pictureBox1.BackgroundImage = picture;
}}
4.5 Перевод изображение в градации серого
Здесь уже никакого порога нет, поэтому для перевода изображения в градации серого просто жмем на кнопку «Серое изображение» (рис.4.5.1):
Рис.4.5.1
private void bGray_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
BitmapData bitmap_data;
IntPtr bitmap_pixels;
unsafe
{
//Блокируем участок в памяти
bitmap_data = picture.LockBits(new Rectangle(0, 0, picture.Width, picture.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//Получаем указатель на первый пиксель
bitmap_pixels = bitmap_data.Scan0;
byte* bitmap_pbitS = (byte*)bitmap_pixels.ToPointer();
//Указываем, что точка будет занимать 3 байта
byte bytes_per_pixel = 3;
byte cc_r, cc_g, cc_b, cc_gray;
for (int x = 0; x < picture.Width; x++)
{
for (int y = 0; y < picture.Height; y++)
{
//Вычисляем указатель на точку, которая соответствует координатам x, y
byte* pixel_gr = (byte*)bitmap_pbitS + (y * bitmap_data.Stride) + (x * bytes_per_pixel);
//Считываем 3 компонента цвета
cc_b = *pixel_gr;
cc_g = *(pixel_gr + 1);
cc_r = *(pixel_gr + 2);
//Вычисляем серый
cc_gray = (byte)Math.Round(cc_b * 0.3f + cc_g * 0.59f + cc_r * 0.11f);
//Устанавливаем в памяти компоненты цвета
*pixel_gr = cc_gray;
pixel_gr++;
*pixel_gr = cc_gray;
pixel_gr++;
*pixel_gr = cc_gray;
}
}
picture.UnlockBits(bitmap_data);
pictureBox1.BackgroundImage = picture;
}}
4.6 Преобразование изображения в негатив
Как и в предыдущем случае, все очень просто, достаточно нажать на «Негатив» и вуаля(рис.4.6.1):
Рис.4.6.1
private void bNegative_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
BitmapData bitmap_data;
IntPtr bitmap_pixels;
unsafe
{
//Блокируем участок в памяти
bitmap_data = picture.LockBits(new Rectangle(0, 0, picture.Width, picture.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//Получаем указатель на первый пиксель
bitmap_pixels = bitmap_data.Scan0;
byte* bitmap_pbitS = (byte*)bitmap_pixels.ToPointer();
//Указываем, что точка будет занимать 3 байта
byte bytes_per_pixel = 3;
byte cc_r, cc_g, cc_b;
for (int x = 0; x < picture.Width; x++)
{
for (int y = 0; y < picture.Height; y++)
{
//Вычисляем указатель на точку, которая соответствует координатам x, y
byte* pixel_gr = (byte*)bitmap_pbitS + (y * bitmap_data.Stride) + (x * bytes_per_pixel);
//Считываем 3 компонента цвета
cc_b = *pixel_gr;
cc_g = *(pixel_gr + 1);
cc_r = *(pixel_gr + 2);
//Устанавливаем в памяти компоненты цвета
*pixel_gr = (byte)(255 - cc_b);
//*pixel_gr++;
*(pixel_gr + 1) = (byte)(255 - cc_g);
//*pixel_gr++;
*(pixel_gr + 2) = (byte)(255 - cc_r);
}
}
picture.UnlockBits(bitmap_data);
pictureBox1.BackgroundImage = picture;
}
}
Все изменения, проведенные выше перечисленных пунктах можно сохранить на диск перейдя в «Меню->Сохранить», либо наоборот отменить все проделанные действия нажав на «Исходное изображение».
4.7 Наложение шумов на изображение
Как было упомянуто, выше в данной программе имеется возможность добавление трех видов шумов, для зашумления изображения необходимо перейти в «Меню->Наложение шумов» и выбрать требуемый шум, в результате получит такую картину (рис.4.7.1):
Рис.4.7.1
4.8 Метод ранговой фильтрации с оценкой середины диапазона
Для данной работы была использована простая картинка с белым, однородным фоном. Данный вариант не очень хорошо подходит для ранговой фильтрации, так как при нахождении среднего между максимумом (белым фоном) и минимумом(шумом на белом фоне) оно получается далеко не белое, в результате на белом фоне появляются пятна(рис.4.8.1):
Рис.4.8.1
Если взять какое-либо другое изображение, то результат будет другим(рис.4.8.2):
До После
Рис.4.8.2
Для доказательства недостатка ранговой фильтрации на током изображении в данном проекте приведен еще один метод фильтрации (Медианная фильтрация, коротко она заключается в выборе среднего, но не в смысле среднего арифметического, а элемента, который расположен посредине(5 элемент) из упорядоченных девяти значений (в случае апертуры = 3х3)), результат его работы приведен на рис.4.8.3:
Рис.4.8.3
Полные алгоритмы перечисленных выше действий приведены в приложении А.
Выводы
В ходе выполненной курсовой работы мною были закреплена теоретическая часть курса и приобретены практические навыки алгоритмизации обработки изображений.
Разработанная программа позволяет выполнять любую из поставленных задач, большинство действий не требуют никакого вмешательства пользователя, а происходят автоматически. Программа выполнена в среде разработки Visual Studio, на языке программирования C#.
Список используемой литературы
1. Методические указания к выполнению курсового проекта по курсу «Обработка сигналов и изображений»;
2. Гонсалес Р., Вудс Р. - Цифровая обработка изображений;
3. Яншин - Обработка изображений на языке Си;
4. Ярославский - Введение в цифровую обработку изображений;
яркость изображение шум негатив
Приложение А
Листинг класса Form1.cs:
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.Drawing.Imaging;
namespace Kursach
{
public partial class Form1 : Form
{
Bitmap bitmap1;
Graphics graphics1, g;
Image MemForImage;
int FLAG = 0, Z = 1;
string name, filename;
private Color selectionColor;
DopForm Form2 = new DopForm();
public Form1()
{
InitializeComponent();
}
private void LoadImage(bool jpg)
{
openFileDialog1.InitialDirectory = "\\";
if (jpg)
openFileDialog1.Filter = "All Graphics Types|*.bmp;*.jpg;*.jpeg;*.png;*.tif;*.tiff";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
MemForImage = Image.FromFile(openFileDialog1.FileName);
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
pictureBox1.BackgroundImage = MemForImage;
using (Bitmap bmp = new Bitmap(pictureBox1.BackgroundImage))
{
selectionColor = GetDominantColor(bmp, false);
selectionColor = CalculateOppositeColor(selectionColor);
}
}
catch (Exception ex)
{
MessageBox.Show("Ошибка при загрузке" + ex.Message);
}
}
}
/// <summary>
/// Returns the dominant color of an image
/// </summary>
private Color GetDominantColor(Bitmap bmp, bool includeAlpha)
{
// GDI+ still lies to us - the return format is BGRA, NOT ARGB.
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
int stride = bmData.Stride;
IntPtr Scan0 = bmData.Scan0;
int r = 0;
int g = 0;
int b = 0;
int a = 0;
int total = 0;
unsafe
{
byte* p = (byte*)(void*)Scan0;
int nOffset = stride - bmp.Width * 4;
int nWidth = bmp.Width;
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < nWidth; x++)
{
r += p[0];
g += p[1];
b += p[2];
a += p[3];
total++;
p += 4;
}
p += nOffset;
}
}
bmp.UnlockBits(bmData);
r /= total;
g /= total;
b /= total;
a /= total;
if (includeAlpha)
return Color.FromArgb(a, r, g, b);
else
return Color.FromArgb(r, g, b);
}
/// <summary>
/// Calculates the opposite color of a given color.
/// Source: http://dotnetpulse.blogspot.com/2007/01/function-to-calculate-opposite-color.html
/// </summary>
/// <param name="clr"></param>
/// <returns></returns>
private Color CalculateOppositeColor(Color clr)
{
return Color.FromArgb(255 - clr.R, 255 - clr.G, 255 - clr.B);
}
private void button1_Click(object sender, EventArgs e)
{
LoadImage(true);
label1.Text = "Яркость:";
label2.Text = "Контраст:";
trackBar1.Enabled = true;
trackBar1.Value = 50;
trackBar2.Enabled = true;
trackBar2.Value = 50;
}
private void Form1_Load(object sender, EventArgs e)
{
bitmap1 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
graphics1 = Graphics.FromImage(bitmap1);
}
private void button2_Click(object sender, EventArgs e)
{
DialogResult rsl = MessageBox.Show("Хотите выйти?", "Выход", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (rsl == DialogResult.Yes)
Application.Exit();
}
private void button3_Click(object sender, EventArgs e)
{
button4_Click(sender, e);
Form2.построениеToolStripMenuItem_Click(sender, e);
}
private void button4_Click(object sender, EventArgs e)
{
int i, j, fl = 0;
Color mycol;
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int[,] r = new int[picture.Height, picture.Width];
int[,] g = new int[picture.Height, picture.Width];
int[,] b = new int[picture.Height, picture.Width];
int[,] br = new int[picture.Height, picture.Width];
Form2.dataGridView1.Rows.Clear();
Form2.dataGridView1.Columns.Clear();
Form2.dataGridView2.Rows.Clear();
Form2.dataGridView2.Columns.Clear();
Form2.dataGridView3.Rows.Clear();
Form2.dataGridView3.Columns.Clear();
Form2.dataGridView4.Rows.Clear();
Form2.dataGridView4.Columns.Clear();
for (i = 0; i < picture.Height - 1; i++)
{
for (j = 0; j < picture.Width - 1; j++)
{
mycol = picture.GetPixel(j, i);
r[i, j] = mycol.R;
g[i, j] = mycol.G;
b[i, j] = mycol.B;
br[i, j] = Convert.ToInt16(mycol.R * 0.3 + mycol.G * 0.59 + mycol.B * 0.11);
if ((mycol.R != mycol.G) || (mycol.G != mycol.B) || (mycol.R != mycol.B))
fl = 1;
}
}
progressBar1.Minimum = 1;
progressBar1.Value = 1;
progressBar1.Step = 1;
if (fl == 0)
{
progressBar1.Maximum = picture.Height * picture.Width + picture.Width;
Form2.dataGridView1.RowCount = picture.Height;
Form2.dataGridView1.ColumnCount = picture.Width + 1;
Form2.dataGridView1.Columns[0].Name = "№";
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView1.Columns[j + 1].Name = Convert.ToString(j + 1);
progressBar1.PerformStep();
}
for (i = 0; i < picture.Height - 1; i++)
{
Form2.dataGridView1.Rows[i].Cells[0].Value = Convert.ToString(i + 1);
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView1.Rows[i].Cells[j + 1].Value = br[i, j];
progressBar1.PerformStep();
}
}
Form2.label10.Text = "1";
}
else
{
progressBar1.Maximum = 4 * (picture.Height * picture.Width) + 4* picture.Width;
Form2.dataGridView1.RowCount = picture.Height;
Form2.dataGridView1.ColumnCount = picture.Width + 1;
Form2.dataGridView1.Columns[0].Name = "№";
Form2.dataGridView2.RowCount = picture.Height;
Form2.dataGridView2.ColumnCount = picture.Width + 1;
Form2.dataGridView2.Columns[0].Name = "№";
Form2.dataGridView3.RowCount = picture.Height;
Form2.dataGridView3.ColumnCount = picture.Width + 1;
Form2.dataGridView3.Columns[0].Name = "№";
Form2.dataGridView4.RowCount = picture.Height;
Form2.dataGridView4.ColumnCount = picture.Width + 1;
Form2.dataGridView4.Columns[0].Name = "№";
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView1.Columns[j + 1].Name = Convert.ToString(j + 1);
progressBar1.PerformStep();
}
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView2.Columns[j + 1].Name = Convert.ToString(j + 1);
progressBar1.PerformStep();
}
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView3.Columns[j + 1].Name = Convert.ToString(j + 1);
progressBar1.PerformStep();
}
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView4.Columns[j + 1].Name = Convert.ToString(j + 1);
progressBar1.PerformStep();
}
for (i = 0; i < picture.Height - 1; i++)
{
Form2.dataGridView1.Rows[i].Cells[0].Value = Convert.ToString(i + 1);
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView1.Rows[i].Cells[j + 1].Value = br[i, j];
progressBar1.PerformStep();
}
}
for (i = 0; i < picture.Height - 1; i++)
{
Form2.dataGridView2.Rows[i].Cells[0].Value = Convert.ToString(i + 1);
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView2.Rows[i].Cells[j + 1].Value = r[i, j];
progressBar1.PerformStep();
}
}
for (i = 0; i < picture.Height - 1; i++)
{
Form2.dataGridView3.Rows[i].Cells[0].Value = Convert.ToString(i + 1);
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView3.Rows[i].Cells[j + 1].Value = g[i, j];
progressBar1.PerformStep();
}
}
for (i = 0; i < picture.Height - 1; i++)
{
Form2.dataGridView4.Rows[i].Cells[0].Value = Convert.ToString(i + 1);
for (j = 0; j < picture.Width - 1; j++)
{
Form2.dataGridView4.Rows[i].Cells[j + 1].Value = b[i, j];
progressBar1.PerformStep();
}
}
Form2.label10.Text = "3";
}
Form2.Show();
}
private void button5_Click(object sender, EventArgs e)
{
Form2.Show();
}
private void button6_Click(object sender, EventArgs e)
{
try
{
MemForImage = Image.FromFile(openFileDialog1.FileName);
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
pictureBox1.BackgroundImage = MemForImage;
using (Bitmap bmp = new Bitmap(pictureBox1.BackgroundImage))
{
selectionColor = GetDominantColor(bmp, false);
selectionColor = CalculateOppositeColor(selectionColor);
}
}
catch (Exception ex)
{
MessageBox.Show("Ошибка при загрузке" + ex.Message);
}
label1.Text = "Яркость:";
label2.Text = "Контраст:";
trackBar1.Value = 50;
trackBar2.Value = 50;
}
private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
{
Graphics gr = graphics1;
PictureBox pb = pictureBox1;
gr = pb.CreateGraphics();
SaveFileDialog savedialog = new SaveFileDialog();
savedialog.Title = "Сохранить картинку как ...";
savedialog.OverwritePrompt = true;
savedialog.CheckPathExists = true;
savedialog.Filter =
openFileDialog1.Filter = //"JPEG - Формат изображения|*.jpg";
"JPEG File(*.jpg)|*.jpg|" +
"Bitmap File(*.bmp)|*.bmp|" +
"GIF File(*.gif)|*.gif|" +
"TIF File(*.tif)|*.tif|" +
"PNG File(*.png)|*.png";
savedialog.ShowHelp = true;
Rectangle r = pb.RectangleToScreen(pb.ClientRectangle);
Bitmap b = new Bitmap(r.Width, r.Height);
Graphics g = Graphics.FromImage(b);
g.CopyFromScreen(r.Location, new Point(0, 0), r.Size);
if (savedialog.ShowDialog() == DialogResult.OK)
{
// Get the user-selected file name
string fileName = savedialog.FileName;
// Get the extension
string strFilExtn =
fileName.Remove(0, fileName.Length - 3);
// Save file
pb.BackColor = System.Drawing.Color.Transparent;
name = strFilExtn;
filename = fileName;
}
switch (name)
{
case "bmp":
pb.Image.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp);
break;
case "jpg":
b.Save(filename);
break;
case "gif":
pb.Image.Save(filename, System.Drawing.Imaging.ImageFormat.Gif);
break;
case "tif":
pb.Image.Save(filename, System.Drawing.Imaging.ImageFormat.Tiff);
break;
case "png":
pb.Image.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
break;
default:
break;
}
try
{
process1 = new System.Diagnostics.Process();
this.process1.StartInfo.Domain = "";
this.process1.StartInfo.LoadUserProfile = false;
this.process1.StartInfo.Password = null;
this.process1.StartInfo.StandardErrorEncoding = null;
this.process1.StartInfo.StandardOutputEncoding = null;
this.process1.StartInfo.UserName = "";
this.process1.SynchronizingObject = this;
process1.StartInfo.FileName = filename;
process1.EnableRaisingEvents = true;
process1.Start();
}
catch { }
}
private void button7_Click(object sender, EventArgs e)
{
сохранитьToolStripMenuItem_Click(sender, e);
}
private void button8_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
BitmapData bitmap_data;
IntPtr bitmap_pixels;
unsafe
{
//Блокируем участок в памяти
bitmap_data = picture.LockBits(new Rectangle(0, 0, picture.Width, picture.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//Получаем указатель на первый пиксель
bitmap_pixels = bitmap_data.Scan0;
byte* bitmap_pbitS = (byte*)bitmap_pixels.ToPointer();
//Указываем, что точка будет занимать 3 байта
byte bytes_per_pixel = 3;
byte cc_r, cc_g, cc_b, cc_gray;
for (int x = 0; x < picture.Width; x++)
{
for (int y = 0; y < picture.Height; y++)
{
//Вычисляем указатель на точку, которая соответствует координатам x, y
byte* pixel_gr = (byte*)bitmap_pbitS + (y * bitmap_data.Stride) + (x * bytes_per_pixel);
//Считываем 3 компонента цвета
cc_b = *pixel_gr;
cc_g = *(pixel_gr + 1);
cc_r = *(pixel_gr + 2);
//Вычисляем серый
cc_gray = (byte)Math.Round(cc_b * 0.3f + cc_g * 0.59f + cc_r * 0.11f);
//Устанавливаем в памяти компоненты цвета
*pixel_gr = cc_gray;
pixel_gr++;
*pixel_gr = cc_gray;
pixel_gr++;
*pixel_gr = cc_gray;
}
}
picture.UnlockBits(bitmap_data);
pictureBox1.BackgroundImage = picture;
}
}
private void button10_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
BitmapData bitmap_data;
IntPtr bitmap_pixels;
unsafe
{
//Блокируем участок в памяти
bitmap_data = picture.LockBits(new Rectangle(0, 0, picture.Width, picture.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//Получаем указатель на первый пиксель
bitmap_pixels = bitmap_data.Scan0;
byte* bitmap_pbitS = (byte*)bitmap_pixels.ToPointer();
//Указываем, что точка будет занимать 3 байта
byte bytes_per_pixel = 3;
byte cc_r, cc_g, cc_b;
for (int x = 0; x < picture.Width; x++)
{
for (int y = 0; y < picture.Height; y++)
{
//Вычисляем указатель на точку, которая соответствует координатам x, y
byte* pixel_gr = (byte*)bitmap_pbitS + (y * bitmap_data.Stride) + (x * bytes_per_pixel);
//Считываем 3 компонента цвета
cc_b = *pixel_gr;
cc_g = *(pixel_gr + 1);
cc_r = *(pixel_gr + 2);
//Устанавливаем в памяти компоненты цвета
*pixel_gr = (byte)(255 - cc_b);
//*pixel_gr++;
*(pixel_gr + 1) = (byte)(255 - cc_g);
//*pixel_gr++;
*(pixel_gr + 2) = (byte)(255 - cc_r);
}
}
picture.UnlockBits(bitmap_data);
pictureBox1.BackgroundImage = picture;
}
}
private void button9_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
BitmapData bitmap_data;
IntPtr bitmap_pixels;
unsafe
{
//Блокируем участок в памяти
bitmap_data = picture.LockBits(new Rectangle(0, 0, picture.Width, picture.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//Получаем указатель на первый пиксель
bitmap_pixels = bitmap_data.Scan0;
byte* bitmap_pbitS = (byte*)bitmap_pixels.ToPointer();
//Указываем, что точка будет занимать 3 байта
byte bytes_per_pixel = 3;
byte cc_binary = (byte)numericUpDown1.Value;
byte cc_r, cc_g, cc_b, cc_bright;
for (int x = 0; x < picture.Width; x++)
{
for (int y = 0; y < picture.Height; y++)
{
//Вычисляем указатель на точку, которая соответствует координатам x, y
byte* pixel_gr = (byte*)bitmap_pbitS + (y * bitmap_data.Stride) + (x * bytes_per_pixel);
//Считываем 3 компонента цвета
cc_b = *pixel_gr;
cc_g = *(pixel_gr + 1);
cc_r = *(pixel_gr + 2);
//Вычисляем яркость
cc_bright = (byte)Math.Round(cc_b * 0.3f + cc_g * 0.59f + cc_r * 0.11f);
//Устанавливаем в памяти компоненты цвета(белый или черный)
if (cc_bright > cc_binary)
{
*pixel_gr = 255;
pixel_gr++;
*pixel_gr = 255;
pixel_gr++;
*pixel_gr = 255;
}
else
{
*pixel_gr = 0;
pixel_gr++;
*pixel_gr = 0;
pixel_gr++;
*pixel_gr = 0;
}
}
}
picture.UnlockBits(bitmap_data);
pictureBox1.BackgroundImage = picture;
}
}
public int CorrectColor(int C)
{
if (C >255)
{
return 255;
}
else if (C <0)
{
return 0;
}
else
return C;
}
private void аддитивныйToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int i, x, y, n;
int r, g, b;
Random rand = new Random();
progressBar1.Value = 1;
progressBar1.Step = 1;
n = rand.Next(picture.Width * 30, picture.Width * 32);
progressBar1.Maximum = n;
i = 0;
while (i < n)
{
x = rand.Next(0, picture.Width);
y = rand.Next(0, picture.Height);
r = picture.GetPixel(x, y).R + rand.Next(-40, 40);
g = picture.GetPixel(x, y).G + rand.Next(-40, 40);
b = picture.GetPixel(x, y).B + rand.Next(-40, 40);
r = CorrectColor(r);
g = CorrectColor(g);
b = CorrectColor(b);
picture.SetPixel(x, y, Color.FromArgb(r, g, b));
i++;
progressBar1.PerformStep();
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
private void мультипликативныйToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int i, x, y, n;
int r, g, b;
Random rand = new Random();
progressBar1.Value = 1;
progressBar1.Step = 1;
n = rand.Next(picture.Width * 30, picture.Width * 32);
progressBar1.Maximum = n;
i = 0;
while (i < n)
{
x = rand.Next(0, picture.Width);
y = rand.Next(0, picture.Height);
r = picture.GetPixel(x, y).R;
g = picture.GetPixel(x, y).G;
b = picture.GetPixel(x, y).B;
r = (int)(r * (rand.NextDouble() + 0.5));
g = (int)(g * (rand.NextDouble() + 0.5));
b = (int)(b * (rand.NextDouble() + 0.5));
r = CorrectColor(r);
g = CorrectColor(g);
b = CorrectColor(b);
picture.SetPixel(x, y, Color.FromArgb(r, g, b));
i++;
progressBar1.PerformStep();
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
private void импульсныйToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int i, x, y, n;
int r, g, b;
Random rand = new Random();
progressBar1.Value = 1;
progressBar1.Step = 1;
n = rand.Next(picture.Width * 30, picture.Width * 32);
progressBar1.Maximum = n;
i = 0;
while (i < n)
{
x = rand.Next(0, picture.Width);
y = rand.Next(0, picture.Height);
r = rand.Next(0, 256);
g = rand.Next(0, 256);
b = rand.Next(0, 256);
picture.SetPixel(x, y, Color.FromArgb(r, g, b));
i++;
progressBar1.PerformStep();
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
private void ранговаяФильтрацияToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int i, j, k, m, count;
int[] R, G, B;
int minR, minG, minB, maxR, maxG, maxB;
int sR, sG, sB;
R = new int[8];
G = new int[8];
B = new int[8];
progressBar1.Value = 1;
progressBar1.Step = 1;
progressBar1.Maximum = picture.Width * picture.Height;
//На элементы будет наложена матрица вида:
// 1 1 1
// 1 1 1
// 1 1 1
for (i = 1; i < (picture.Width - 1); i++)
{
for (j = 1; j < (picture.Height - 1); j++)
{
count = 0;
//Считываем уровни всех пикселей для красного в окне фильтра
for (k = -1; k <= 1; k++)
{
for (m = -1; m <= 1; m++)
{
if (m == 0 && k == 0)
{
continue;
}
R[count] = picture.GetPixel(i + k, j + m).R;
G[count] = picture.GetPixel(i + k, j + m).G;
B[count] = picture.GetPixel(i + k, j + m).B;
count++;
}
}
progressBar1.PerformStep();
//Находим минимум и максимум, используя стандартные методы C#
minR = R.Min(); maxR = R.Max();
minG = G.Min(); maxG = G.Max();
minB = B.Min(); maxB = B.Max();
//Находим среднее значение между максимумом и минимумом
sR = (maxR + minR) / 2;
sG = (maxG + minG) / 2;
sB = (maxB + minB) / 2;
//Помещаем средние значения на место центрального в окне фильтра
picture.SetPixel(i, j, Color.FromArgb(sR, sG, sB));
}
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
private void trackBar1_MouseUp(object sender, MouseEventArgs e)
{
int bright = trackBar1.Value - 50;
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int r, g, b;
for (int i = 0; i < picture.Width - 1; i++)
{
for (int j = 0; j < picture.Height - 1; j++)
{
r = picture.GetPixel(i, j).R;
g = picture.GetPixel(i, j).G;
b = picture.GetPixel(i, j).B;
r += bright;
g += bright;
b += bright;
r = CorrectColor(r);
b = CorrectColor(b);
g = CorrectColor(g);
picture.SetPixel(i, j, Color.FromArgb(r, g, b));
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
}
private void выходToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void trackBar2_MouseUp(object sender, MouseEventArgs e)
{
double K;
K = Convert.ToDouble(trackBar2.Value) / Convert.ToDouble(50);
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int AveR = 0, AveG = 0, AveB = 0;
int r, g, b;
for (int i = 0; i < picture.Width - 1; i++)
{
for (int j = 0; j < picture.Height - 1; j++)
{
AveR = AveR + picture.GetPixel(i, j).R;
AveG = AveG + picture.GetPixel(i, j).G;
AveB = AveB + picture.GetPixel(i, j).B;
}
}
AveR = AveR / (picture.Width * picture.Height);
AveG = AveG / (picture.Width * picture.Height);
AveB = AveB / (picture.Width * picture.Height);
for (int i = 0; i < picture.Width; i++)
{
for (int j = 0; j < picture.Height; j++)
{
r = picture.GetPixel(i, j).R;
g = picture.GetPixel(i, j).G;
b = picture.GetPixel(i, j).B;
r = (int)((r - AveR) * K) + AveR;
g = (int)((g - AveG) * K) + AveG;
b = (int)((b - AveB) * K) + AveB;
r = CorrectColor(r);
g = CorrectColor(g);
b = CorrectColor(b);
picture.SetPixel(i, j, Color.FromArgb(r, g, b));
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
label1.Text = "Яркость" + "(" + Convert.ToString(trackBar1.Value - 50) + ")" + ":";
label1.Refresh();
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
label2.Text = "Контраст" + "(" + Convert.ToString(Convert.ToDouble(trackBar2.Value) / Convert.ToDouble(50)) + ")" + ":";
label2.Refresh();
}
private void медианныйФильтрToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int i, j, k, m, count;
int[] R, G, B;
R = new int[9];
G = new int[9];
B = new int[9];
//Матрица для этого фильтра будет иметь вид:
// 1 1 1
// 1 1 1
// 1 1 1
progressBar1.Value = 1;
progressBar1.Step = 1;
progressBar1.Maximum = picture.Width * picture.Height;
for (i = 1; i < (picture.Width - 1); i++)
{
//Вначаледвигаемсявправо
for (j = 1; j < (picture.Height - 1); j++)
{
count = 0;
//Считываем уровни всех пикселей для красного в окне фильтра
for (k = -1; k <= 1; k++)
{
for (m = -1; m <= 1; m++)
{
R[count] = picture.GetPixel(i + k, j + m).R;
G[count] = picture.GetPixel(i + k, j + m).G;
B[count] = picture.GetPixel(i + k, j + m).B;
count++;
}
}
progressBar1.PerformStep();
//Сортируем полученные массивы, используя стандартные методы C#
Array.Sort(R);
Array.Sort(G);
Array.Sort(B);
//Помещаем медианный элемент на место центрального в окне фильтра
picture.SetPixel(i, j, Color.FromArgb(R[4], G[4], B[4]));
}
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
int SumMod8(int x, int y)
{
int summ =0;
summ= x + y;
while (summ >7)
{
summ= summ -8;
}
return summ;
}
private void методКиршаToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap picture = new Bitmap(pictureBox1.BackgroundImage);
int i, j, g;
double[] S, T, A;
S =new double[8];
T =new double[8];
A =new double[8];
double max, mod;
progressBar1.Value = 1;
progressBar1.Step = 1;
progressBar1.Maximum = picture.Width * picture.Height;
for (i =1; i < (picture.Width -1); i++)
{
for (j =1; j < (picture.Height -1); j++)
{
//Получаем уровни яркости каждого пикселя в окне 3х3
// A0 A1 A2
// A7 F' A3
// A6 A5 A4
A[0] =0.3* picture.GetPixel(i -1, j -1).R +0.59* picture.GetPixel(i -1, j -1).G +0.11* picture.GetPixel(i -1, j -1).B;
A[1] =0.3* picture.GetPixel(i, j -1).R +0.59* picture.GetPixel(i, j -1).G +0.11* picture.GetPixel(i, j -1).B;
A[2] =0.3* picture.GetPixel(i +1, j -1).R +0.59* picture.GetPixel(i +1, j -1).G +0.11* picture.GetPixel(i +1, j -1).B;
A[3] =0.3* picture.GetPixel(i +1, j).R +0.59* picture.GetPixel(i +1, j).G +0.11* picture.GetPixel(i +1, j).B;
A[4] =0.3* picture.GetPixel(i +1, j +1).R +0.59* picture.GetPixel(i +1, j +1).G +0.11* picture.GetPixel(i +1, j +1).B;
A[5] =0.3* picture.GetPixel(i, j +1).R +0.59* picture.GetPixel(i, j +1).G +0.11* picture.GetPixel(i, j +1).B;
A[6] =0.3* picture.GetPixel(i -1, j +1).R +0.59* picture.GetPixel(i -1, j +1).G +0.11* picture.GetPixel(i -1, j +1).B;
A[7] =0.3* picture.GetPixel(i -1, j).R +0.59* picture.GetPixel(i -1, j).G +0.11* picture.GetPixel(i -1, j).B;
for (g =0; g <8; g++)
{
//Находим сумму Si
S[g] = A[g] +A[SumMod8(g, 1)] + A[SumMod8(g, 2)];
//Находимсумму Ti
T[g] = A[SumMod8(g, 3)] + A[SumMod8(g, 4)] + A[SumMod8(g, 5)] + A[SumMod8(g, 6)] + A[SumMod8(g, 7)];
}
max=0;
for (g =0; g <8; g++)
{
//Расчитываемзначение |5*Si-3*Ti|
mod=Math.Abs((5* S[g]) - (3* T[g]));
//Находим максимум из полученных решений
if (mod > max)
{
max = mod;
}
}
//Для обеспечения более хорошей наблюдаемости повышаем полученное значение на 100
max = max +100;
//Выполняем коррекцию в пределах 0...255
if (max >255)
{
max=255;
}
else if (max <0)
{
max =0;
}
progressBar1.PerformStep();
//Помещаем результирующее значение в каждый из каналов R, G, B на место F'
picture.SetPixel(i, j, Color.FromArgb((int)max, (int)max, (int)max));
}
}
pictureBox1.BackgroundImage = picture;
pictureBox1.Refresh();
}
private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
{
LoadImage(true);
label1.Text = "Яркость:";
label2.Text = "Контраст:";
trackBar1.Enabled = true;
trackBar1.Value = 50;
trackBar2.Enabled = true;
trackBar2.Value = 50;
}
}
}
Листинг класса DopForm.cs:
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 Microsoft.Office.Interop;
using Excel = Microsoft.Office.Interop.Excel;
namespace Kursach
{
public partial class DopForm : Form
{
Bitmap bitmap1, bitmap2, bitmap3, bitmap4;
Graphics graphics1, graphics2, graphics3, graphics4;
double[] dop = new double[256];
int FLAG=0;
string name, filename;
public DopForm()
{
InitializeComponent();
}
private void refr1()
{
pictureBox1.Image = bitmap1;
}
private void refr2()
{
pictureBox2.Image = bitmap2;
}
private void refr3()
{
pictureBox3.Image = bitmap3;
}
private void refr4()
{
pictureBox4.Image = bitmap4;
}
private void DopForm_Load(object sender, EventArgs e)
{
bitmap1 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
graphics1 = Graphics.FromImage(bitmap1);
bitmap2 = new Bitmap(pictureBox2.Width, pictureBox2.Height);
graphics2 = Graphics.FromImage(bitmap2);
bitmap3 = new Bitmap(pictureBox3.Width, pictureBox3.Height);
graphics3 = Graphics.FromImage(bitmap3);
bitmap4 = new Bitmap(pictureBox4.Width, pictureBox4.Height);
graphics4 = Graphics.FromImage(bitmap4);
refr1(); refr2(); refr3(); refr4();
}
public void Save_data(int opr)
{
int i, j;
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Worksheet oSheet;
progressBar1.Minimum = 1;
progressBar1.Value = 1;
progressBar1.Step = 1;
DataGridView dv = new DataGridView();
if (opr == 1)
dv = dataGridView1;
else if (opr == 2)
dv = dataGridView2;
else if (opr == 3)
dv = dataGridView3;
else
dv = dataGridView4;
progressBar1.Maximum = dv.RowCount * dv.ColumnCount;
try
{
oXL = new Excel.Application();
oWB = (Excel.Workbook)oXL.Workbooks.Add(Type.Missing);
//oSheet = (Excel.Worksheet)oXL.Worksheets.Add(Type.Missing);
oSheet = (Excel.Worksheet)oWB.ActiveSheet;
for (i = 0; i < dv.ColumnCount - 1; i++)
oSheet.Cells[1, i+1] = i;
for (i = 0; i < dv.RowCount - 1; i++)
{
for (j = 0; j < dv.ColumnCount - 1; j++)
{
oSheet.Cells[i + 2, j+1] = dv.Rows[i].Cells[j].Value;
progressBar1.PerformStep();
}
}
oXL.Visible = true;
oXL.UserControl = true;
}
catch (Exception theException)
{
String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat(errorMessage, theException.Message);
errorMessage = String.Concat(errorMessage, " Line: ");
errorMessage = String.Concat(errorMessage, theException.Source);
MessageBox.Show(errorMessage, "Error");
}
}
private void закрытьToolStripMenuItem_Click(object sender, EventArgs e)
{
Hide();
}
private void сохранить1ToolStripMenuItem_Click(object sender, EventArgs e)
{
Save_data(1);
}
private void сохранить2ToolStripMenuItem1_Click(object sender, EventArgs e)
{
Save_data(2);
}
private void сохранить3ToolStripMenuItem1_Click(object sender, EventArgs e)
{
Save_data(3);
}
private void сохранить4ToolStripMenuItem1_Click(object sender, EventArgs e)
{
Save_data(4);
}
private void histogramm(int hist)
{
int i, j;
int zn, dl;
double dop_max;
double my;
Graphics gr;
Bitmap bp;
DataGridView dg;
if (hist == 1)
{
gr = graphics1;
//graphics1.Clear(Color.Transparent);
//graphics2.Clear(Color.Transparent);
//graphics3.Clear(Color.Transparent);
//graphics4.Clear(Color.Transparent);
bp = bitmap1;
dg = dataGridView1;
}
else if (hist == 2)
{
gr = graphics2;
//graphics2.Clear(Color.Transparent);
//graphics1.Clear(Color.Transparent);
bp = bitmap2;
dg = dataGridView2;
}
else if (hist == 3)
{
gr = graphics3;
//graphics3.Clear(Color.Transparent);
bp = bitmap3;
dg = dataGridView3;
}
else
{
gr = graphics4;
//graphics4.Clear(Color.Transparent);
bp = bitmap4;
dg = dataGridView4;
}
gr.DrawLine(new Pen(Color.Black), 5, 5, 5, bp.Height - 5);
gr.DrawLine(new Pen(Color.Black), 0, bp.Height - 15, bp.Width - 5, bp.Height - 15);
gr.DrawLine(new Pen(Color.Black), (bp.Width - 10) / 5 + 5, bp.Height - 17, (bp.Width - 10) / 5 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 2 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 2 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 3 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 3 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 4 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 4 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 5 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 5 + 5, bp.Height - 13);
gr.DrawString("50", new Font("Arial", 8), new SolidBrush(Color.Red), (bp.Width - 10) / 5 - 5, bp.Height - 15);
gr.DrawString("100", new Font("Arial", 8), new SolidBrush(Color.Red), ((bp.Width - 10) / 5) * 2 - 7, bp.Height - 15);
gr.DrawString("150", new Font("Arial", 8), new SolidBrush(Color.Red), ((bp.Width - 10) / 5) * 3 - 5, bp.Height - 15);
gr.DrawString("200", new Font("Arial", 8), new SolidBrush(Color.Red), ((bp.Width - 10) / 5) * 4 - 7, bp.Height - 15);
gr.DrawString("255", new Font("Arial", 8), new SolidBrush(Color.Red), ((bp.Width - 10) / 5) * 5 - 5, bp.Height - 15);
for (i = 0; i < dg.RowCount - 1; i++)
{
for (j = 0; j < dg.ColumnCount - 2; j++)
{
zn = (int)dg.Rows[i].Cells[j + 1].Value;
dop[zn]++;
}
}
dop_max = dop[0];
for (i = 1; i < 256; i++)
if (dop[i] > dop_max)
dop_max = dop[i];
my = Convert.ToDouble(bp.Height - 20) / Convert.ToDouble(dop_max);
for (i = 0; i < 255; i++)
{
dl = Convert.ToInt32(dop[i] * my);
//graphics1.DrawLine(new Pen(Color.Blue), 6 + i, bp.Height - 15, 6 + i, bp.Height - 15 - dl);
gr.DrawLine(new Pen(Color.Blue), 6 + i, bp.Height - 15, 6 + i, bp.Height - 15 - dl);
}
}
public void построениеToolStripMenuItem_Click(object sender, EventArgs e)
{
FLAG = 0;
int k;
tabControl1.SelectedIndex = 1;
graphics1.Clear(Color.Transparent);
graphics2.Clear(Color.Transparent);
graphics3.Clear(Color.Transparent);
graphics4.Clear(Color.Transparent);
if (label10.Text == "1")
{
histogramm(1);
refr1();
}
else
{
for (k = 1; k < 5;k++ )
histogramm(k);
refr1();
refr2();
refr3();
refr4();
}
}
private void ogibayushaya(int ogib)
{
FLAG = 1;
int i, j, z;
int zn;
double my, dop_max;
Graphics gr;
Bitmap bp;
DataGridView dg;
if (ogib == 1)
{
gr = graphics1;
graphics1.Clear(Color.Transparent);
graphics2.Clear(Color.Transparent);
graphics3.Clear(Color.Transparent);
graphics4.Clear(Color.Transparent);
bp = bitmap1;
dg = dataGridView1;
}
else if (ogib == 2)
{
gr = graphics2;
graphics2.Clear(Color.Transparent);
graphics1.Clear(Color.Transparent);
bp = bitmap2;
dg = dataGridView2;
}
else if (ogib == 3)
{
gr = graphics3;
graphics3.Clear(Color.Transparent);
bp = bitmap3;
dg = dataGridView3;
}
else
{
gr = graphics4;
graphics4.Clear(Color.Transparent);
bp = bitmap4;
dg = dataGridView4;
}
gr.DrawLine(new Pen(Color.Black), 5, 5, 5, bp.Height - 5);
gr.DrawLine(new Pen(Color.Black), 0, bp.Height - 15, bp.Width - 5, bp.Height - 15);
gr.DrawLine(new Pen(Color.Black), (bp.Width - 10) / 5 + 5, bp.Height - 17, (bp.Width - 10) / 5 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 2 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 2 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 3 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 3 + 5, bp.Height - 13);
gr.DrawLine(new Pen(Color.Black), ((bp.Width - 10) / 5) * 4 + 5, bp.Height - 17, ((bp.Width - 10) / 5) * 4 + 5, bp.Height - 13);
Подобные документы
Методика устранения посторонних шумов и коррекции искажения типа дисфокусировки. Обрезка сильно искаженных краев изображения. Построение яркостной гистограммы изображения и его преобразование в индексный формат с восьмицветовой палитрой в пакете Matlab.
контрольная работа [4,7 M], добавлен 13.01.2012Общий алгоритм сравнения двух изображений. Метод максимальных площадей. Метод гистограмм. Подготовка изображения к распознаванию. Моделирование многомерной функции. Распределение векторов. Деформируемые модели. Реализация программного обеспечения.
дипломная работа [384,2 K], добавлен 29.09.2008Задачи цифровой обработки изображений. Методы пороговой сегментации. Создание программы представления рисунка в виде матрицы и применения к нему пороговой обработки. Разработка интерфейса программы загрузки и фильтрации изображения с выбранным порогом.
курсовая работа [2,0 M], добавлен 12.11.2012Описание метода обработки "Выделение контурных линий" и особенностей его применения и программной реализации. Способы увеличения контрастности. Значение правильного подбора формы гистограммы для качества компьютерной обработки растрового изображения.
курсовая работа [940,2 K], добавлен 24.06.2013Программа визуализации космических изображений. Файлы формата LAN. В программе реализован инструмент ресинтеза цветного изображения, отображаемого в главном окне, инструмент выравнивания гистограмм яркости каналов и диалоговое окно вывода гистограмм.
курсовая работа [2,9 M], добавлен 12.05.2012Основные понятия о представлении изображения. Определение величины порога с помощью гистограммы яркостей. Глобальная, локальная, адаптивная пороговая обработка. Метод дискриминантного критерия. Исследования на искусственных и предметных изображениях.
дипломная работа [5,1 M], добавлен 23.12.2012Разработка приложения, целью которого ставится преобразование черно-белых полутоновых изображений в цветные. Обзор методики обработки изображения, способов преобразования изображения с помощью нейронной сети. Описания кластеризации цветового пространства.
дипломная работа [6,3 M], добавлен 17.06.2012Алгоритм реализации векторного пространства, метод фильтрации шумов на изображении. Формально-логическая модель разработки программного обеспечения, выбор инструментальных средств его реализации. Анализ точности совпадения распознанного изображения.
дипломная работа [2,7 M], добавлен 13.02.2013Выбор методов обработки и сегментации изображений. Математические основы примененных фильтров. Гистограмма яркости изображения. Программная реализация комплексного метода обработки изображений. Тестирование разработанного программного обеспечения.
курсовая работа [1,3 M], добавлен 18.01.2017Современные системы текстурного анализа изображений. Примеры текстурной сегментации одноканальных изображений. Использование признаков, полученных на основе гистограммы яркостей второго порядка, для классификации спектрозональных аэрофотоснимков.
реферат [573,5 K], добавлен 15.01.2017