Помощь в написании студенческих работ
Антистрессовый сервис

Работа с BMP-изображениями

Лабораторная работаПомощь в написанииУзнать стоимостьмоей работы

На гистограмме для изображения с примененным фильтром сглаживания мы видим, что относительно оригинала, количество пикселей с наиболее часто встречающейся яркостью канала в изображении растет. То есть, происходит рост гистограммы и ее сужение. А при применении фильтра подчеркивания границ, гистограмма расширяется и становится ниже. Вывод В результате выполнения лабораторной работы было… Читать ещё >

Работа с BMP-изображениями (реферат, курсовая, диплом, контрольная)

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

Федеральное государственное автономное образовательное учреждение высшего профессионального образования

" САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ"

Работа с 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. Программирование на С#. Методические указания к лабораторным работам. А. Ю. Демин, В. А. Дорофеев.

Показать весь текст
Заполнить форму текущей работой