Работа с BMP-изображениями
Загрузка интерфейса изображением формата хранения растровых изображений BMP. Программа осуществления отражения изображения по вертикали и горизонтали. Применение к изображению черно-белого, сглаживающего, подчеркивания границ и медианного фильтров.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | лабораторная работа |
Язык | русский |
Дата добавления | 26.04.2015 |
Размер файла | 713,6 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное автономное образовательное учреждение высшего профессионального образования
"САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ"
Работа с BMP - изображениями
по курсу: Основы мультимедиатехнологий
Санкт-Петербург 2015
1. Цель работы
Написать программу для обработки изображения, выполняющую функции:
1. загрузить интерфейс изображением формата BMP;
2. осуществить отражение изображение по вертикали и горизонтали;
3. применить к изображению черно-белый фильтр;
4. применить сглаживающий фильтр и фильтр подчеркивания границ;
5. а также один фильтр по желанию (Медианный фильтр).
интерфейс формат изображение фильтр
2. Формализация
Для выполнения задания воспользуемся средой разработки MS Visual C#.
BMP (от англ. Bitmap Picture) -- формат хранения растровых изображений.
При открытии изображения размер поля для отображения подбирается таким образом, чтобы картинка не была обрезана и растянута, т.е. были соблюдены пропорции. Так же на этом этапе данные о битовой карте изображения помещаем в 4 переменные:
bmp1 - отвечает за отображение исходного изображения,
bmp2 - отвечает за отображение результирующего изображения,
bmp3 - вспомогательная карта для более корректной обработки изображения.
bmp4 - вспомогательная карта для более корректной обработки изображения.
Зачем нужны 2 вспомогательные карты?
На bmp3 не применяются удаление/восстановление цветовых каналов, а так же черно-белые режимы. Переменная bmp3 необходима нам для восстановления цветовых каналов, в случае снятия галочек с определенных элементов с сохранением использованных фильтров
На bmp4 не применяются черно-белые режимы. Переменная bmp4 служит для корректной работы удаления/восстановления каналов и включении/выключении черно-белых режимов.
Сглаживающий фильтр
Назначение: Сглаживания - технология, используемая для устранения шумов или "зубчатости", возникающего на краях объектов выводимых на изображении.
Основывается на следующем принципе: Обрабатывается рабочее окно изображения двумерной матрицей (2n+1)x(2n+1) ("+1" - потому что матрица не должна быть размером менее 3х3), n - целое положительное число, определяемое коэффициент усиления сглаживания (В нашем случае n=1, то есть матрица сглаживания 3х3). Находится среднее значение матрицы по каждому цветовому каналу в отдельности, исключая значение цветового канала центрального пикселя, по формуле:
(1)
Где, i - индекс строки матрицы,
j - индекс столбца матрицы,
C - значение цветового RGB-канала,
n - количество элементов как в столбце, так и в строке матрицы.
Полученное значение и будет новым значением цветового канала центрального пикселя матрицы (для матрицы 3х3 это будет элемент P1,1, для матрицы 5х5 - Р2,2 и т.д.)
Примечание: в нашем варианте пиксели, находящиеся по краям изображения, не обрабатываются. Чтобы обойти данный эффект можно:
1) При искусственном зашумлении границы изображения преднамеренно не зашумлять.
2) Обрабатывать каким-то образом частный случай крайних точек (например, для угла изображения при апертуре 3 суммировать не 9 точек, а 4, и результат отправлять в этот самый угол или значения крайних точек дублировать до заполнения квадратной матрицы нужных размеров).
Подчеркивание границ
Назначение: подчеркивание границ служит для отделения участков различного тонадруг от друга темной или светлой линией.
Основывается на следующем принципе: Обрабатывается рабочее окно изображения двумерной матрицей (2n+1)x(2n+1) ("+1" - потому что матрица не должна быть размером менее 3х3), n - целое положительное число, определяемое коэффициент усиления подчеркивания (В нашем случае n=1, то есть матрица подчеркивания 3х3). Находится среднее значение матрицы по каждому цветовому каналу в отдельности по формуле:
(2)
Где, i - индекс строки матрицы,
j - индекс столбца матрицы,
C - значение цветового RGB-канала,
n - количество элементов как в столбце, так и в строке матрицы.
К значению центрального пикселя прибавляем разность среднего значения соседних пикселей и центрального пикселя:
(3)
Где, NewPix - новое значение центрального пикселя,
Pix - старое значение центрального пикселя,
F - среднее значение соседних пикселей, вычисленное по формуле (2).
Примечание: в нашем варианте пиксели, находящиеся по краям изображения, не обрабатываются. Чтобы обойти данный эффект можно обрабатывать каким-то образом частный случай крайних точек (например, для угла изображения при апертуре 3 брать не 9 точек, а 4, и результат отправлять в этот самый угол или значения крайних точек дублировать до заполнения квадратной матрицы нужных размеров).
Отражение изображения
Основывается на следующем принципе: При отражении по вертикали меняем местами левые и правые пиксели, при отражении по горизонтали - верхние и нижние.
Нам необходим буфер для хранения одного пикселя, пока другой пиксель не поставим на место первого.
Изображение делится на две равные части: верхнюю и нижнюю (отражение по горизонтали), левую и правую (отражение по вертикали).
Алгоритм отражения:
1) Верхний (левый) пиксель заносим в буфер,
2) нижний (правый) пиксель переносим на симметричное верхнее (левое) место (откуда был взят пиксель в буфер),
3) пиксель из буфера помещаем на нижнее (правое) место (откуда был перенесен пиксель на втором шаге).
Примечание: Как уже было сказано выше, изображение делится на 2 равные части. Если у нас размер изображения - нечетное число, то integer(целое число) разделить на константу 2 будет в результате целое число без остатка (остаток отброшен). Таким образом, средняя полоска пикселей (остаток от деления) будет отброшен, при отражении это полосу пикселей трогать не будем, чего нам и не требуется.
Черно-белый режим
Цветное изображение преобразуется в монохромное(черно-белое).
Монохромное изображение - выполненное в одном цвете; излучающее один цвет или цвета, различающиеся по яркости, но не по спектру(в нашем случае черно-белое).
Нами реализовано 2 способа представления черно-белого изображения:
1 способ (Черно-белый1): Многим известно, что цвет можно задать тройкой RGB. Значение каждого оттенка занимает байт, а значит лежит в диапазоне от 0 до 255 включительно. (R=0,G=0,B=0 -- черный, R=255,G=255,B=255 -- белый).
Определим среднее значение всех оттенков по формуле:
(4)
Где R - (Red) Красный канал
G - (Green)Зеленый канал
B - (Blue) Синий канал
Зададим некоторый порог P из диапазона 0 -- 255 (Р=100), и укажем правило, что если среднее значение всех оттенков К <= порога P, то наш пиксель в монохромном изображении будет черный, в противном случае пиксель будет белым.
2 способ (Черно-белый2): отображение черно-белого изображения с оттеками серого разной яркости ("темно- и светло- серый")
Для этого необходимо и достаточно определить среднее значение оттенков по формуле(4)
Это значение заносим в каждый канал пикселя.
Примечание: При включении/выключении этих режимов сохраняются использованные фильтры, удаленные/восстановленные цветовые каналы.
Медианная фильтрация
Назначение: Медианный фильтр -- один из видов цифровых фильтров, широко используемый в цифровой обработке сигналов и изображений для уменьшения уровня шума.
Основывается на следующем принципе: Обрабатываются данные вспомогательной битовой карты изображения(bmp3) двумерной матрицей (2n+1)x(2n+1) ("+1" - потому что матрица не должна быть размером менее 3х3), n - целое положительное число, определяемое коэффициент усиления подчеркивания (В нашем случае n=1, то есть матрица 3х3). Элементы матрицы сортируются в порядке возрастания. Значение находящееся в центре матрицы помещается в битовую карту обрабатываемого изображения (bmp2) по тем же координатам, где находился центр матрицы в bmp3.
Примечание: в нашем варианте пиксели, находящиеся по краям изображения, не обрабатываются. Чтобы обойти данный эффект можно обрабатывать каким-то образом частный случай крайних точек (например, для угла изображения при апертуре 3 брать не 9 точек, а 4, и результат отправлять в этот самый угол или значения крайних точек дублировать до заполнения квадратной матрицы нужных размеров).
3. Блок-схема
4. Листинг программы
//отражение по вертикали
private void button6_Click(object sender, EventArgs e)
{
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height / 2; j++)
{
//запомниаем текущий пиксель обрабатываемого изображения
int bufR = bmp2.GetPixel(i, j).R;
int bufG = bmp2.GetPixel(i, j).G;
int bufB = bmp2.GetPixel(i, j).B;
//присваиваем цветам пикселя обрабатываемого изодражения новые значения
bmp2.SetPixel(i, j, Color.FromArgb(bmp2.GetPixel(i, bmp2.Height - 1 - j).R, bmp2.GetPixel(i, bmp2.Height - 1 - j).G, bmp2.GetPixel(i, bmp2.Height - 1 - j).B));
bmp2.SetPixel(i, bmp2.Height - 1 - j, Color.FromArgb(bufR, bufG, bufB));
//запомниаем текущий пиксель вспомогательной цветовой карты
bufR = bmp3.GetPixel(i, j).R;
bufG = bmp3.GetPixel(i, j).G;
bufB = bmp3.GetPixel(i, j).B;
//присваиваем цветам пикселя вспомогательной цветовой карты новые значения
bmp3.SetPixel(i, j, Color.FromArgb(bmp3.GetPixel(i, bmp3.Height - 1 - j).R, bmp3.GetPixel(i, bmp3.Height - 1 - j).G, bmp3.GetPixel(i, bmp3.Height - 1 - j).B));
bmp3.SetPixel(i, bmp3.Height - 1 - j, Color.FromArgb(bufR, bufG, bufB));
//запомниаем текущий пиксель вспомогательной цветовой карты
bufR = bmp4.GetPixel(i, j).R;
bufG = bmp4.GetPixel(i, j).G;
bufB = bmp4.GetPixel(i, j).B;
//присваиваем цветам пикселя вспомогательной цветовой карты новые значения
bmp4.SetPixel(i, j, Color.FromArgb(bmp4.GetPixel(i, bmp4.Height - 1 - j).R, bmp4.GetPixel(i, bmp3.Height - 1 - j).G, bmp4.GetPixel(i, bmp4.Height - 1 - j).B));
bmp4.SetPixel(i, bmp4.Height - 1 - j, Color.FromArgb(bufR, bufG, bufB));
}
}
pictureBox2.Image = bmp2;
}
//отражение по горизонтали
//происходит так же, как и отражение по вертикали
private void button7_Click(object sender, EventArgs e)
{
for (int i = 0; i < bmp2.Width / 2; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
int bufferR = bmp2.GetPixel(i, j).R;
int bufferG = bmp2.GetPixel(i, j).G;
int bufferB = bmp2.GetPixel(i, j).B;
bmp2.SetPixel(i, j, Color.FromArgb(bmp2.GetPixel(bmp2.Width - 1 - i, j).R, bmp2.GetPixel(bmp2.Width - 1 - i, j).G, bmp2.GetPixel(bmp2.Width - 1 - i, j).B));
bmp2.SetPixel(bmp2.Width - 1 - i, j, Color.FromArgb(bufferR, bufferG, bufferB));
bufferR = bmp3.GetPixel(i, j).R;
bufferG = bmp3.GetPixel(i, j).G;
bufferB = bmp3.GetPixel(i, j).B;
bmp3.SetPixel(i, j, Color.FromArgb(bmp3.GetPixel(bmp2.Width - 1 - i, j).R, bmp3.GetPixel(bmp3.Width - 1 - i, j).G, bmp3.GetPixel(bmp3.Width - 1 - i, j).B));
bmp3.SetPixel(bmp3.Width - 1 - i, j, Color.FromArgb(bufferR, bufferG, bufferB));
bufferR = bmp4.GetPixel(i, j).R;
bufferG = bmp4.GetPixel(i, j).G;
bufferB = bmp4.GetPixel(i, j).B;
bmp4.SetPixel(i, j, Color.FromArgb(bmp4.GetPixel(bmp4.Width - 1 - i, j).R, bmp4.GetPixel(bmp4.Width - 1 - i, j).G, bmp4.GetPixel(bmp4.Width - 1 - i, j).B));
bmp4.SetPixel(bmp4.Width - 1 - i, j, Color.FromArgb(bufferR, bufferG, bufferB));
}
}
pictureBox2.Image = bmp2;
}
//сглаживание
private void button10_Click(object sender, EventArgs e)
{
//инициализируем переменные для хранения цветов соседних пикселей
//(верхнего, нижнего, левого, правого)
int RedC, RedL, RedR, RedU, RedD, RedLU, RedRU, RedLD, RedRD, NewRed,
GreenC, GreenL, GreenR, GreenU, GreenD, GreenLU, GreenRU, GreenLD, GreenRD, NewGreen,
BlueC, BlueL, BlueR, BlueU, BlueD, BlueLU, BlueRU, BlueLD, BlueRD, NewBlue;
//в каждом пикселе (если он не крайний) для каждого цвета
//находим среднее значение глубины
for (int i = 0; i < bmp2.Width; i++)
for (int j = 0; j < bmp2.Height; j++)
{
if ((i != 0) && (j != 0) && (i != bmp2.Width - 1) && (j != bmp2.Height - 1))
{
//нахождение значений соседних пикселей
RedC = bmp2.GetPixel(i , j ).R;
RedL = bmp2.GetPixel(i , j - 1).R;
RedR = bmp2.GetPixel(i , j + 1).R;
RedU = bmp2.GetPixel(i - 1, j ).R;
RedD = bmp2.GetPixel(i + 1, j ).R;
RedLU = bmp2.GetPixel(i - 1, j - 1).R;
RedRU = bmp2.GetPixel(i - 1, j + 1).R;
RedLD = bmp2.GetPixel(i + 1, j - 1).R;
RedRD = bmp2.GetPixel(i + 1, j + 1).R;
//нахождение среднего значения
NewRed = (RedC + RedL + RedR + RedU + RedD + RedLU + RedRU + RedLD + RedRD) / 9;
GreenC = bmp2.GetPixel(i , j ).G;
GreenL = bmp2.GetPixel(i , j - 1).G;
GreenR = bmp2.GetPixel(i , j + 1).G;
GreenU = bmp2.GetPixel(i - 1, j ).G;
GreenD = bmp2.GetPixel(i + 1, j ).G;
GreenLU = bmp2.GetPixel(i - 1, j - 1).G;
GreenRU = bmp2.GetPixel(i - 1, j + 1).G;
GreenLD = bmp2.GetPixel(i + 1, j - 1).G;
GreenRD = bmp2.GetPixel(i + 1, j + 1).G;
NewGreen = (GreenC + GreenL + GreenR + GreenU + GreenD + GreenLU + GreenRU + GreenLD + GreenRD) / 9;
BlueC = bmp2.GetPixel(i , j ).B;
BlueL = bmp2.GetPixel(i , j - 1).B;
BlueR = bmp2.GetPixel(i , j + 1).B;
BlueU = bmp2.GetPixel(i - 1, j ).B;
BlueD = bmp2.GetPixel(i + 1, j ).B;
BlueLU = bmp2.GetPixel(i - 1, j - 1).B;
BlueRU = bmp2.GetPixel(i - 1, j + 1).B;
BlueLD = bmp2.GetPixel(i + 1, j - 1).B;
BlueRD = bmp2.GetPixel(i + 1, j + 1).B;
NewBlue = (BlueC + BlueL + BlueR + BlueU + BlueD + BlueLU + BlueRU + BlueLD + BlueRD) / 9;
//присваиваем цветам пикселя новые значения
bmp2.SetPixel(i, j, Color.FromArgb(NewRed, NewGreen, NewBlue));
//тоже самое проделываем для вспомогательной цветовой карты
RedC = bmp3.GetPixel(i , j ).R;
RedL = bmp3.GetPixel(i , j - 1).R;
RedR = bmp3.GetPixel(i , j + 1).R;
RedU = bmp3.GetPixel(i - 1, j ).R;
RedD = bmp3.GetPixel(i + 1, j ).R;
RedLU = bmp3.GetPixel(i - 1, j - 1).R;
RedRU = bmp3.GetPixel(i - 1, j + 1).R;
RedLD = bmp3.GetPixel(i + 1, j - 1).R;
RedRD = bmp3.GetPixel(i + 1, j + 1).R;
NewRed = (RedC + RedL + RedR + RedU + RedD + RedLU + RedRU + RedLD + RedRD) / 9;
GreenC = bmp3.GetPixel(i , j ).G;
GreenL = bmp3.GetPixel(i , j - 1).G;
GreenR = bmp3.GetPixel(i , j + 1).G;
GreenU = bmp3.GetPixel(i - 1, j ).G;
GreenD = bmp3.GetPixel(i + 1, j ).G;
GreenLU = bmp3.GetPixel(i - 1, j - 1).G;
GreenRU = bmp3.GetPixel(i - 1, j + 1).G;
GreenLD = bmp3.GetPixel(i + 1, j - 1).G;
GreenRD = bmp3.GetPixel(i + 1, j + 1).G;
NewGreen = (GreenC + GreenL + GreenR + GreenU + GreenD + GreenLU + GreenRU + GreenLD + GreenRD) / 9;
BlueC = bmp3.GetPixel(i , j ).B;
BlueL = bmp3.GetPixel(i , j - 1).B;
BlueR = bmp3.GetPixel(i , j + 1).B;
BlueU = bmp3.GetPixel(i - 1, j ).B;
BlueD = bmp3.GetPixel(i + 1, j ).B;
BlueLU = bmp3.GetPixel(i - 1, j - 1).B;
BlueRU = bmp3.GetPixel(i - 1, j + 1).B;
BlueLD = bmp3.GetPixel(i + 1, j - 1).B;
BlueRD = bmp3.GetPixel(i + 1, j + 1).B;
NewBlue = (BlueC + BlueL + BlueR + BlueU + BlueD + BlueLU + BlueRU + BlueLD + BlueRD) / 9;
bmp3.SetPixel(i, j, Color.FromArgb(NewRed, NewGreen, NewBlue));
//тоже самое проделываем для вспомогательной цветовой карты
RedC = bmp4.GetPixel(i, j).R;
RedL = bmp4.GetPixel(i, j - 1).R;
RedR = bmp4.GetPixel(i, j + 1).R;
RedU = bmp4.GetPixel(i - 1, j).R;
RedD = bmp4.GetPixel(i + 1, j).R;
RedLU = bmp4.GetPixel(i - 1, j - 1).R;
RedRU = bmp4.GetPixel(i - 1, j + 1).R;
RedLD = bmp4.GetPixel(i + 1, j - 1).R;
RedRD = bmp4.GetPixel(i + 1, j + 1).R;
NewRed = (RedC + RedL + RedR + RedU + RedD + RedLU + RedRU + RedLD + RedRD) / 9;
GreenC = bmp4.GetPixel(i, j).G;
GreenL = bmp4.GetPixel(i, j - 1).G;
GreenR = bmp4.GetPixel(i, j + 1).G;
GreenU = bmp4.GetPixel(i - 1, j).G;
GreenD = bmp4.GetPixel(i + 1, j).G;
GreenLU = bmp4.GetPixel(i - 1, j - 1).G;
GreenRU = bmp4.GetPixel(i - 1, j + 1).G;
GreenLD = bmp4.GetPixel(i + 1, j - 1).G;
GreenRD = bmp4.GetPixel(i + 1, j + 1).G;
NewGreen = (GreenC + GreenL + GreenR + GreenU + GreenD + GreenLU + GreenRU + GreenLD + GreenRD) / 9;
BlueC = bmp4.GetPixel(i, j).B;
BlueL = bmp4.GetPixel(i, j - 1).B;
BlueR = bmp4.GetPixel(i, j + 1).B;
BlueU = bmp4.GetPixel(i - 1, j).B;
BlueD = bmp4.GetPixel(i + 1, j).B;
BlueLU = bmp4.GetPixel(i - 1, j - 1).B;
BlueRU = bmp4.GetPixel(i - 1, j + 1).B;
BlueLD = bmp4.GetPixel(i + 1, j - 1).B;
BlueRD = bmp4.GetPixel(i + 1, j + 1).B;
NewBlue = (BlueC + BlueL + BlueR + BlueU + BlueD + BlueLU + BlueRU + BlueLD + BlueRD) / 9;
bmp4.SetPixel(i, j, Color.FromArgb(NewRed, NewGreen, NewBlue));
}
}
pictureBox2.Image = bmp2;
}
//подчеркивание
private void button11_Click(object sender, EventArgs e)
{
//инициализируем переменные для хранения цветов соседних пикселей
//(верхнего, нижнего, левого, правого)
int RedC, RedL, RedR, RedU, RedD, RedLU, RedRU, RedLD, RedRD, NewRed,
GreenC, GreenL, GreenR, GreenU, GreenD, GreenLU, GreenRU, GreenLD, GreenRD, NewGreen,
BlueC, BlueL, BlueR, BlueU, BlueD, BlueLU, BlueRU, BlueLD, BlueRD, NewBlue;
//коэффициент усиления подчеркивания границ
int k = 2;
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
if ((i != 0) && (j != 0) && (i != bmp2.Width - 1) && (j != bmp2.Height - 1))
{
//нахождение значений соседних пикселей
RedC = bmp2.GetPixel(i , j ).R;
RedL = bmp2.GetPixel(i , j - 1).R;
RedR = bmp2.GetPixel(i , j + 1).R;
RedU = bmp2.GetPixel(i - 1, j ).R;
RedD = bmp2.GetPixel(i + 1, j ).R;
RedLU = bmp2.GetPixel(i - 1, j - 1).R;
RedRU = bmp2.GetPixel(i - 1, j + 1).R;
RedLD = bmp2.GetPixel(i + 1, j - 1).R;
RedRD = bmp2.GetPixel(i + 1, j + 1).R;
//нахождение среднего значения
int modRed = (RedC + (RedC - (RedU + RedD + RedL + RedR + RedLU + RedRU + RedLD + RedRD) / 8) * k);
NewRed = modRed < 0 ? RedC : modRed > 255 ? RedC : modRed;
GreenC = bmp2.GetPixel(i , j ).G;
GreenL = bmp2.GetPixel(i , j - 1).G;
GreenR = bmp2.GetPixel(i , j + 1).G;
GreenU = bmp2.GetPixel(i - 1, j ).G;
GreenD = bmp2.GetPixel(i + 1, j ).G;
GreenLU = bmp2.GetPixel(i - 1, j - 1).G;
GreenRU = bmp2.GetPixel(i - 1, j + 1).G;
GreenLD = bmp2.GetPixel(i + 1, j - 1).G;
GreenRD = bmp2.GetPixel(i + 1, j + 1).G;
int modGreen = (GreenC + (GreenC - (GreenU + GreenD + GreenL + GreenR + GreenLU + GreenRU + GreenLD + GreenRD) / 8) * k);
NewGreen = modGreen < 0 ? GreenC : modGreen > 255 ? GreenC : modGreen;
BlueC = bmp2.GetPixel(i , j ).B;
BlueL = bmp2.GetPixel(i , j - 1).B;
BlueR = bmp2.GetPixel(i , j + 1).B;
BlueU = bmp2.GetPixel(i - 1, j ).B;
BlueD = bmp2.GetPixel(i + 1, j ).B;
BlueLU = bmp2.GetPixel(i - 1, j - 1).B;
BlueRU = bmp2.GetPixel(i - 1, j + 1).B;
BlueLD = bmp2.GetPixel(i + 1, j - 1).B;
BlueRD = bmp2.GetPixel(i + 1, j + 1).B;
int modBlue = (BlueC + (BlueC - (BlueU + BlueD + BlueL + BlueR + BlueLU + BlueRU + BlueLD + BlueRD) / 8) * k);
NewBlue = modBlue < 0 ? BlueC : modBlue > 255 ? BlueC : modBlue;
//присваиваем цветам пикселя новые значения
bmp2.SetPixel(i, j, Color.FromArgb(NewRed, NewGreen, NewBlue));
//тоже самое проделываем для вспомогательной цветовой карты
RedC = bmp3.GetPixel(i , j ).R;
RedL = bmp3.GetPixel(i , j - 1).R;
RedR = bmp3.GetPixel(i , j + 1).R;
RedU = bmp3.GetPixel(i - 1, j ).R;
RedD = bmp3.GetPixel(i + 1, j ).R;
RedLU = bmp3.GetPixel(i - 1, j - 1).R;
RedRU = bmp3.GetPixel(i - 1, j + 1).R;
RedLD = bmp3.GetPixel(i + 1, j - 1).R;
RedRD = bmp3.GetPixel(i + 1, j + 1).R;
modRed = (RedC + (RedC - (RedU + RedD + RedL + RedR + RedLU + RedRU + RedLD + RedRD) / 8) * k);
NewRed = modRed < 0 ? RedC : modRed > 255 ? RedC : modRed;
GreenC = bmp3.GetPixel(i , j ).G;
GreenL = bmp3.GetPixel(i , j - 1).G;
GreenR = bmp3.GetPixel(i , j + 1).G;
GreenU = bmp3.GetPixel(i - 1, j ).G;
GreenD = bmp3.GetPixel(i + 1, j ).G;
GreenLU = bmp3.GetPixel(i - 1, j - 1).G;
GreenRU = bmp3.GetPixel(i - 1, j + 1).G;
GreenLD = bmp3.GetPixel(i + 1, j - 1).G;
GreenRD = bmp3.GetPixel(i + 1, j + 1).G;
modGreen = (GreenC + (GreenC - (GreenU + GreenD + GreenL + GreenR + GreenLU + GreenRU + GreenLD + GreenRD) / 8) * k);
NewGreen = modGreen < 0 ? GreenC : modGreen > 255 ? GreenC : modGreen;
BlueC = bmp3.GetPixel(i , j ).B;
BlueL = bmp3.GetPixel(i , j - 1).B;
BlueR = bmp3.GetPixel(i , j + 1).B;
BlueU = bmp3.GetPixel(i - 1, j ).B;
BlueD = bmp3.GetPixel(i + 1, j ).B;
BlueLU = bmp3.GetPixel(i - 1, j - 1).B;
BlueRU = bmp3.GetPixel(i - 1, j + 1).B;
BlueLD = bmp3.GetPixel(i + 1, j - 1).B;
BlueRD = bmp3.GetPixel(i + 1, j + 1).B;
modBlue = (BlueC + (BlueC - (BlueU + BlueD + BlueL + BlueR + BlueLU + BlueRU + BlueLD + BlueRD) / 8) * k);
NewBlue = modBlue < 0 ? BlueC : modBlue > 255 ? BlueC : modBlue;
bmp3.SetPixel(i, j, Color.FromArgb(NewRed, NewGreen, NewBlue));
//тоже самое проделываем для вспомогательной цветовой карты
RedC = bmp4.GetPixel(i, j).R;
RedL = bmp4.GetPixel(i, j - 1).R;
RedR = bmp4.GetPixel(i, j + 1).R;
RedU = bmp4.GetPixel(i - 1, j).R;
RedD = bmp4.GetPixel(i + 1, j).R;
RedLU = bmp4.GetPixel(i - 1, j - 1).R;
RedRU = bmp4.GetPixel(i - 1, j + 1).R;
RedLD = bmp4.GetPixel(i + 1, j - 1).R;
RedRD = bmp4.GetPixel(i + 1, j + 1).R;
modRed = (RedC + (RedC - (RedU + RedD + RedL + RedR + RedLU + RedRU + RedLD + RedRD) / 8) * k);
NewRed = modRed < 0 ? RedC : modRed > 255 ? RedC : modRed;
GreenC = bmp4.GetPixel(i, j).G;
GreenL = bmp4.GetPixel(i, j - 1).G;
GreenR = bmp4.GetPixel(i, j + 1).G;
GreenU = bmp4.GetPixel(i - 1, j).G;
GreenD = bmp4.GetPixel(i + 1, j).G;
GreenLU = bmp4.GetPixel(i - 1, j - 1).G;
GreenRU = bmp4.GetPixel(i - 1, j + 1).G;
GreenLD = bmp4.GetPixel(i + 1, j - 1).G;
GreenRD = bmp4.GetPixel(i + 1, j + 1).G;
modGreen = (GreenC + (GreenC - (GreenU + GreenD + GreenL + GreenR + GreenLU + GreenRU + GreenLD + GreenRD) / 8) * k);
NewGreen = modGreen < 0 ? GreenC : modGreen > 255 ? GreenC : modGreen;
BlueC = bmp4.GetPixel(i, j).B;
BlueL = bmp4.GetPixel(i, j - 1).B;
BlueR = bmp4.GetPixel(i, j + 1).B;
BlueU = bmp4.GetPixel(i - 1, j).B;
BlueD = bmp4.GetPixel(i + 1, j).B;
BlueLU = bmp4.GetPixel(i - 1, j - 1).B;
BlueRU = bmp4.GetPixel(i - 1, j + 1).B;
BlueLD = bmp4.GetPixel(i + 1, j - 1).B;
BlueRD = bmp4.GetPixel(i + 1, j + 1).B;
modBlue = (BlueC + (BlueC - (BlueU + BlueD + BlueL + BlueR + BlueLU + BlueRU + BlueLD + BlueRD) / 8) * k);
NewBlue = modBlue < 0 ? BlueC : modBlue > 255 ? BlueC : modBlue;
bmp4.SetPixel(i, j, Color.FromArgb(NewRed, NewGreen, NewBlue));
}
}
}
pictureBox2.Image = bmp2;
}
//медианная фильтрация
private void button9_Click(object sender, EventArgs e)
{
int[] massR = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] massG = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] massB = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//для избавления от помех, находим среднее значение цвета в матрице 3х3 вспомогательной карты и присваиваем значение пикселю обрабатывааемого изображения
for (int i = 1; i < bmp2.Width - 1; i++)
{
for (int j = 1; j < bmp2.Height - 1; j++)
{
int p = 0;
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
massR[p] = bmp3.GetPixel(i + x, j + y).R;
massG[p] = bmp3.GetPixel(i + x, j + y).G;
massB[p] = bmp3.GetPixel(i + x, j + y).B;
p++;
}
}
for (int x = 0; x <= 8; x++)
{
for (int y = 0; y <= 7; y++)
{
if (massR[y] > massR[y + 1])
{
int buf = massR[y];
massR[y] = massR[y + 1];
massR[y + 1] = buf;
}
if (massG[y] > massG[y + 1])
{
int buf = massG[y];
massG[y] = massG[y + 1];
massG[y + 1] = buf;
}
if (massB[y] > massB[y + 1])
{
int buf = massB[y];
massB[y] = massB[y + 1];
massB[y + 1] = buf;
}
}
}
int n = 4;
bmp2.SetPixel(i, j, Color.FromArgb(massR[n], massG[n], massB[n]));
bmp4.SetPixel(i, j, Color.FromArgb(massR[n], massG[n], massB[n]));
}
}
pictureBox2.Image = bmp2;
//затем копируем карту обрабатываемого изображения во вспомогательную карту
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
bmp3.SetPixel(i, j, Color.FromArgb(bmp2.GetPixel(i, j).R, bmp2.GetPixel(i, j).G, bmp2.GetPixel(i, j).B));
}
}
}
//Черно-белый1
//входные данные - координаты пикселя
//изменяется цветовая схема только обрабатываемого изображения, что бы сохранить информацию о истинных значениях цветов во вспомогательной карте
private void BlackWhite(int i, int j)
{
//найти среднее значение яркости трех цветов пикселя - R,G,B
int NewColor = (bmp2.GetPixel(i, j).R + bmp2.GetPixel(i, j).G + bmp2.GetPixel(i, j).B) / 3;
//присвоить R,G,B цветам пикселя среднее значение
if (NewColor <= 100)
NewColor = 0;
else
NewColor = 255;
bmp2.SetPixel(i, j, Color.FromArgb(NewColor, NewColor, NewColor));
}
//переключатель черно-белого1
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
//если стоит галочка, переводим изображение в черно-белый режим
if (checkBox4.Checked == true)
{
//изменить цвета в карте изображения
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
BlackWhite(i, j);
}
}
}
//если галочка снята, то возвращяем истинные значения цветов из вспомогательной карты, проверяя состояние галочек для удаления цветового канала
else
{
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
//сначала присваиваем переменным значения цветов вспомогательной карты
int red = bmp3.GetPixel(i, j).R,
green = bmp3.GetPixel(i, j).G,
blue = bmp3.GetPixel(i, j).B;
//затем проверяем состояние галочек для удаления цветовых каналов,
//если галочка стоит, цветовому каналу присваиваем значение ноль
if (checkBox1.Checked == true)
{
red = 0;
}
if (checkBox2.Checked == true)
{
green = 0;
}
if (checkBox3.Checked == true)
{
blue = 0;
}
//карте обрабатываемого изображения присваиваем новые значения цветовых каналов
bmp2.SetPixel(i, j, Color.FromArgb(red, green, blue));
if (checkBox5.Checked == true)
GreyBox(i, j);
}
}
}
this.pictureBox2.Image = bmp2;
}
//Черно-белый1
//входные данные - координаты пикселя
//изменяется цветовая схема только обрабатываемого изображения, что бы сохранить информацию о истинных значениях цветов во вспомогательной карте
private void GreyBox(int i, int j)
{
//найти среднее значение яркости трех цветов пикселя - R,G,B
int NewColor = (bmp2.GetPixel(i, j).R + bmp2.GetPixel(i, j).G + bmp2.GetPixel(i, j).B) / 3;
//присвоить R,G,B цветам пикселя среднее значение
bmp2.SetPixel(i, j, Color.FromArgb(NewColor, NewColor, NewColor));
}
//переключатель черно-белого2
private void checkBox5_CheckedChanged(object sender, EventArgs e)
{
//если стоит галочка, переводим изображение в черно-белый режим
if (checkBox5.Checked == true)
{
//изменить цвета в карте изображения
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
GreyBox(i, j);
}
}
}
//если галочка снята, то возвращяем истинные значения цветов из вспомогательной карты, проверяя состояние галочек для удаления цветового канала
else
{
for (int i = 0; i < bmp2.Width; i++)
{
for (int j = 0; j < bmp2.Height; j++)
{
//сначала присваиваем переменным значения цветов вспомогательной карты
int red = bmp3.GetPixel(i, j).R,
green = bmp3.GetPixel(i, j).G,
blue = bmp3.GetPixel(i, j).B;
//затем проверяем состояние галочек для удаления цветовых каналов,
//если галочка стоит, цветовому каналу присваиваем значение ноль
if (checkBox1.Checked == true)
{
red = 0;
}
if (checkBox2.Checked == true)
{
green = 0;
}
if (checkBox3.Checked == true)
{
blue = 0;
}
//карте обрабатываемого изображения присваиваем новые значения цветовых каналов
bmp2.SetPixel(i, j, Color.FromArgb(red, green, blue));
if (checkBox4.Checked == true)
BlackWhite(i, j);
}
}
}
this.pictureBox2.Image = bmp2;
}
}
}
5. Результаты работы программы
Отражение горизонтали
Черно-белый фильтр
Подчеркивание границ
Сглаживание
Медианная фильтрация
Вывод
В результате выполнения лабораторной работы было разработано приложение, с помощью которого можно модифицировать изображение, путем изменения bitmap изображения. Также были реализованы несколько фильтров для изменения изображения: черно-белый фильтр, сглаживающий фильтр, подчеркивание границ и медианная фильтрация.
После применения каждого из фильтров, для каждого канала изображения были построены гистограммы, по которым можно оценивать общие изменения количества пикселей определенной яркости.
Например, при применении черно-белого фильтра, гистограммы для каждого из цветов одинаковы, так как мы в каждом пикселе, каждому каналу присваиваем среднее значение трех каналов пикселя.
На гистограмме для изображения с примененным фильтром сглаживания мы видим, что относительно оригинала, количество пикселей с наиболее часто встречающейся яркостью канала в изображении растет. То есть, происходит рост гистограммы и ее сужение. А при применении фильтра подчеркивания границ, гистограмма расширяется и становится ниже.
Фильтр медианной фильтрации предназначен, для того, чтобы устранять помехи изображения. Если сравнить гистограмму изображения с помехами с гистограммой этого же изображения, только, с примененным медианным фильтром, то можно увидеть, что вероятность появления помехи в изображении резко уменьшается.
Литература
1. Гербердт Шилдт. Полный справочник по С#;
2. Программирование на С#. Методические указания к лабораторным работам. А.Ю. Демин, В.А. Дорофеев.
Размещено на Allbest.ru
Подобные документы
Общая информация о графическом формате. Описание формата Microsoft Windows Bitmap. Структура файла DDВ исходного формата ВМР. Преобразования графических файлов. Просмотр и редактирование растровых изображений. Создание многодокументного приложения.
дипломная работа [1,5 M], добавлен 06.06.2010Работа с бинарными изображениями, методы их преобразования в полутоновые. Сущность бинаризации изображений и роль правильного выбора порога квантования. Применение полноцветных, полутоновых и бинарных изображений, способы построения гистограмм.
лабораторная работа [1,3 M], добавлен 30.09.2009Информация о графических форматах. Хранение изображения в программе. Очередь как вспомогательная структура данных. Загрузка изображения из двоичного файла. Операции с изображением. Уменьшение разрешающей способности. Увеличение размера изображения.
курсовая работа [1,1 M], добавлен 29.06.2013Типы изображений (черно-белые, полутоновые, цветные) и их форматы. Устройства, создающие цифровые изображения, и их параметры. Применение и характеристики методов сжатия изображений. Поиск по содержимому в базах данных изображений. Структуры баз данных.
презентация [360,4 K], добавлен 11.10.2013Задача зеркального отражения изображения как одна из подзадач многих программ. Анализ создания программы, выполняющей зеркальное отображение изображения, который хранится в файле формата .pcx (256 цветов). Проектирование пользовательского интерфейса.
курсовая работа [625,6 K], добавлен 17.05.2013Анализ влияния сглаживающего шума на различные категории томографических изображений. Разработка программного обеспечения для снижения помех и увеличения четкости очертаний крупных объектов. Метод рисования прямоугольников, ограничивающих все контуры.
практическая работа [1006,7 K], добавлен 28.09.2019Редактирование различных растровых изображений. Версии Adobe PhotoShop. Расширенная версия программы Adobe Photoshop Extended. Работа с файлами. Сложности использования PhotoShop. Простое редактирование фотографий. Разнообразие фильтров и рамок.
контрольная работа [4,9 M], добавлен 08.01.2014Методы обработки растровых изображений (кластеризация, пороговая и интерактивная сегментация). Разработка программного модуля для системы мониторинга биосферы и дистанционного зондирования. Создание пользовательского интерфейса программного модуля.
курсовая работа [2,2 M], добавлен 29.04.2015Разработка приложения, целью которого ставится преобразование черно-белых полутоновых изображений в цветные. Обзор методики обработки изображения, способов преобразования изображения с помощью нейронной сети. Описания кластеризации цветового пространства.
дипломная работа [6,3 M], добавлен 17.06.2012Компьютерная графика. Пиксели, разрешение, размер изображения. Типы изображений. Черно-белые штриховые и полутоновые изображения. Индексированные цвета. Полноцветные изображения. Форматы файлов. Цвет и его модели. Цветовые модели: RGB, CMYK, HSB.
реферат [18,1 K], добавлен 20.02.2009