Реферат: Фильтрация шумов в растровых изображениях методами усредняющего, порогового и медианного фильтров

Белорусский Государственный Университет

Информатики и РадиоэлектроникиКонтрольная работа

по

МАГИ

Выполнил студент

группы 500501

Балахонов Е.В.

Задание.

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

            Програма написана на языке Object Pascal и выполняется в среде Win32. Общий вид программы показан на рис. № 1.

/>

Рис. № 1. Общий вид главного окна программы.

/>

Рис. № 2. Общий вид главного окна программы c

загруженным исходным изображением.

1. Усредняющий фильтp.

Алгоритмработы усредняющего фильтра заключается в замене значения яркости в

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

            Реализация фильтрапредставлена в виде процедуры:

  ProcedureAverageFilter(Value:Integer);

 Даннаяпроцедура осуществляет алгоритм усредняющего фильтра применительно к объекту TBitmap. В него предварительно должна быть загруженоизображение (Рис. № 2). Результат работы усредняющего филтра можно увидеть нарис. № 3. Параметр Value – порог при которомпроизводятся манипуляции с пикселом.

Procedure TMainForm.AverageFilter;

var

 PrevisionLine:pByteArray;

 CurrentLine:pByteArray;

 NextLine:pByteArray;

 I,J:Integer;

 Summ:Integer;

begin

 ifImage1.Picture.Bitmap.PixelFormat = pf8bit then

 begin

  for I := 0 toImage1.Picture.Bitmap.Height — 1 do

  begin

   CurrentLine :=Image1.Picture.Bitmap.ScanLine[I];

   for J := 0 toImage1.Picture.Bitmap.Width — 1 do

   begin

    Summ := 0;

    if I > 0 then

    begin

     PrevisionLine :=Image1.Picture.Bitmap.ScanLine[I — 1];

     if J > 0 then

     begin

      Summ := Summ +PrevisionLine^[J — 1];

     end;

     Summ := Summ +PrevisionLine^[J];

     if J + 1 <Image1.Picture.Bitmap.Width then

     begin

      Summ := Summ +PrevisionLine^[J + 1];

     end;

    end;

    if J > 0 then

    begin

     Summ := Summ +CurrentLine^[J — 1];

    end;

    Summ := Summ +CurrentLine^[J];

    if J + 1 <Image1.Picture.Bitmap.Width then

    begin

     Summ := Summ +CurrentLine^[J + 1];

    end;

    if I + 1 <Image1.Picture.Bitmap.Height then

    begin

     NextLine :=Image1.Picture.Bitmap.ScanLine[I + 1];

     if J > 0 then

     begin

      Summ := Summ +NextLine^[J — 1];

     end;

     Summ := Summ +NextLine^[J];

     if J + 1 <Image1.Picture.Bitmap.Width then

     begin

      Summ := Summ +NextLine^[J + 1];

     end;

    end;

    if (Summ div 9)<= Value then

     CurrentLine^[J] :=Summ div 9;

   end;

  end;

  Image1.Visible :=False;

  Image1.Visible :=True;

  N4.Enabled := True;

 end

 else

 MessageBox(Handle,'Такой формат файла пока не подерживается...',

                   'Слабоват я пока...',MB_OKor MB_ICONSTOP or MB_APPLMODAL);

end;

/>

Рис. № 3. Результат работы усредняющего фильтра.

2. Пороговый фильтр.

Пороговыйфильтр является модификацией усредняющего, и отличие заключается

том, что замена значения яркостина среднее производится толь-ко в том случае, если разность между значениемяркости и полученным сред-ним превышает установленный порог. Выбор порогаосуществляется в специальном диалоговом окне (Рис. 4). Для произведенияфильтрации используется процедура AverageFilter,показанная в пункте 1.

/>

Рис. № 4.Выбор коэффициента усреднения пороговогофильтра.

/>

Рис. № 5. Результат работы порогового фильтра.

3. Медианный фильтр.

Одномерныймедианный фильтр пред-ставляет собой скользящее окно охватывающее нечетноечисло элементов изо-бражения. Центральный элемент заменяется медианой элементовизображения в окне. Медианой дискретной последовательности М элементов принечетном 1 называют элемент, для которого существует (М-1)/2 элементе меньшихили равных ему по величине и (М-1)/2 элементов больших или равных ему пове-личине.

Медианныйфильтр в одних случаях обеспечивает подавление шума, а в других — вызываетнежелательное подавление сигнала. Медианный фильтр не влияет на пилообразные иступенчатые функции, что обычно является полез-ным свойством, однако онподавляет импульсные сигналы, длительность которых составляет менее половиныширины окна. Фильтр также вызывает уплощение вершины треугольной функции.

Возможныразличные стратегии применения медианного фильтра для подавления шумов. Одна изних рекомендует начинать с медианного фильтра, окно которого охватывает триэлемента изображения. Если ослабление сигнала незначительно, то окнорасширяется до пяти элементов. Так поступают до тех пор, пока медианнаяфильтрация начнет приносить больше вреда, чем пользы. Другая возможностьсостоит в каскадной медианной фильтрации сигнала с использованием фиксированнойили изменяемой ширины окна. В общем случае те области, которые остаются безизменения после однократной обработки, не меняются и после повторной обработки.Области, в которых длительность им-пульсных сигналов составляет менее половиныширины окна, будут подвер-гаться изменениям после каждого цикла обработки.Концепцию медианного фильтра можно легко обобщить на два измерения, применяяокно прямоугольной или близкой к круговой формы.

Для реализациимедианного фильтра используется следующий код:

procedureTMainForm.N16Click(Sender: TObject);

var

 PixelArray:array ofByte;

 Value:Byte;

 CurrentLine:pByteArray;

 BoxCurrentLine:pByteArray;

 Vert,Hor:Integer;

 VertB,HorB:Integer;

 Counter:Integer;

 Temp:Byte;

begin

 ValueForm.Caption := 'Размер окна фильтра n X n';

 ValueForm.TrackBar1.Min:= 3;

 ValueForm.TrackBar1.Max:= 9;

 ValueForm.TrackBar1.Frequency:= 2;

 ValueForm.Edit1.ReadOnly:= True;

 ifValueForm.Execute(Value) then

 begin

 SetLength(PixelArray,Value*Value);

  ifImage1.Picture.Bitmap.PixelFormat = pf8bit then

  begin

   for Vert := 0 toImage1.Picture.Bitmap.Height — 1 do

   begin

    CurrentLine :=Image1.Picture.Bitmap.ScanLine[Vert];

    for Hor := 0 toImage1.Picture.Bitmap.Width — 1 do

    begin

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

    Counter := 0;

     for VertB := (Vert- (Value div 2)) to (Vert + (Value div 2)) do

     begin

      if (VertB >=0) and (VertB < Image1.Picture.Bitmap.Height) then

       BoxCurrentLine:= Image1.Picture.Bitmap.ScanLine[VertB];

      for HorB := (Hor- (Value div 2)) to (Hor + (Value div 2)) do

      begin

       if (HorB >=0) and (VertB >= 0) and

          (HorB <Image1.Picture.Bitmap.Width) and

          (VertB <Image1.Picture.Bitmap.Height) then

        PixelArray[Counter]:= BoxCurrentLine^[HorB]

       else

       PixelArray[Counter] := 0;

       Inc(Counter);

      end;

    end;

    // Сортируем массив

    forVertB := 0 to Value*Value — 1 do

     begin

      for HorB := VertBto Value*Value — 1 do

      begin

       ifPixelArray[VertB] > PixelArray[HorB] then

       begin

        Temp :=PixelArray[VertB];

        PixelArray[VertB]:= PixelArray[HorB];

       PixelArray[HorB] := Temp;

       end;

      end;

     end;

     // Берем то чтопосередине и присваиваем текущему пикселю

    CurrentLine^[Hor]:= PixelArray[((Value*Value) div 2) + 1];

    end;

   end;

   Image1.Visible :=False;

   Image1.Visible :=True;

   N4.Enabled := True;

  end

 else

  MessageBox(Handle,'Такой формат файла пока не подерживается...',

                     'Слабоват я пока...',MB_OKor MB_ICONSTOP or  MB_APPLMODAL);

 end;

end;

Результатработы фильтра можно увидеть на рис. № 6.

/>

Рис. № 6. Начало работы медианного фильтра – запрос наразмер окна фильтра.

/>

Рис. № 7.Результат работы медианного фильтра с окном 3на 3.

4. Заполнение объекта другим цветом.

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

procedureTMainForm.Image1MouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState;X, Y: Integer);

var

 TargetPixel:Byte;

 ChangeCount:Integer;

 CurrentLine:pByteArray;

 PrevLine:pByteArray;

 NextLine:pByteArray;

 YOffset,XOffset:Integer;

begin

 ifImage1.Picture.Bitmap.PixelFormat = pf8bit then

 begin

 // Запоминаем значение пиксела на котором щелкнули мышкой

 TargetPixel:= pByteArray(Image1.Picture.Bitmap.ScanLine[Y])^[X];

  YOffset := 0;

 // Пока число замен не станет равным 0 двигаемся вверх

 repeat

   ChangeCount := 0;

   if Y — YOffset <0 then

    Break;

   // Берем линию

   CurrentLine :=Image1.Picture.Bitmap.ScanLine[Y — YOffset];

   PrevLine :=Image1.Picture.Bitmap.ScanLine[Y — YOffset — 1];

   if PrevLine[X]<> TargetPixel then

    Break;

  XOffset := 0;

  // Заполняем влево ее пока не дойдем до границы объекта

  ifX — 1 >= 0 then

   while CurrentLine^[X- XOffset — 1] = TargetPixel do

   begin

    CurrentLine^[X — XOffset] := 255;

    Inc(XOffset);

    Inc(ChangeCount);

    if X — XOffset — 1< 0 then

     Break;

   end;

   XOffset := 0;

   // Заполняем вправо еепока не дойдем до границы объекта

  ifX + 1 < Image1.Picture.Bitmap.Width — 1 then

   while CurrentLine^[X+ XOffset + 1] = TargetPixel do

   begin

    CurrentLine^[X +XOffset] := 255;

    Inc(XOffset);

    Inc(ChangeCount);

    if X + XOffset + 1> Image1.Picture.Bitmap.Width — 1 then

     Break;

   end;

   Inc(YOffset);

  until ChangeCount =0;

  YOffset := 1;

  // Пока число замен нестанет равным 0 двигаемся вниз

 repeat

   ChangeCount := 0;

   if Y + YOffset >Image1.Picture.Bitmap.Width — 1 then

    Break;

   // Берем линию

   CurrentLine :=Image1.Picture.Bitmap.ScanLine[Y + YOffset];

   NextLine :=Image1.Picture.Bitmap.ScanLine[Y + YOffset + 1];

   if NextLine[X]<> TargetPixel then

    Break;

  XOffset := 0;

  // Заполняем влево ее пока не дойдем до границы объекта

  ifX — 1 >= 0 then

   while CurrentLine^[X- XOffset — 1] = TargetPixel do

   begin

    CurrentLine^[X — XOffset] := 255;

    Inc(XOffset);

    Inc(ChangeCount);

    if X — XOffset — 1< 0 then

     Break;

   end;

   XOffset := 0;

   // Заполняем вправо еепока не дойдем до границы объекта

  ifX + 1 < Image1.Picture.Bitmap.Width — 1 then

   while CurrentLine^[X+ XOffset + 1] = TargetPixel do

   begin

    CurrentLine^[X +XOffset] := 255;

    Inc(XOffset);

    Inc(ChangeCount);

    if X + XOffset + 1> Image1.Picture.Bitmap.Width — 1 then

     Break;

   end;

   Inc(YOffset);

  until ChangeCount =0;

  Image1.Visible :=False;

  Image1.Visible :=True;

 end;

end;

Результаты работы программы можноувидеть на рис. № 8 и № 9.

/>

Рис. № 8. Исходное изображение для заполнения.

/>

Рис. № 9. Результат заполнения.

5. Инверсия.

Ну и напоследок сделаем инверсиюнашего изображения (Рис. 10, 11):

procedureTMainForm.N7Click(Sender: TObject);

var

 Line:pByteArray;

 I,J:Integer;

 Bits:Byte;

begin

 Bits := 1;

 for I :=0 toImage1.Picture.Bitmap.Height — 1 do

 begin

  Line :=Image1.Picture.Bitmap.ScanLine[I];

  caseImage1.Picture.Bitmap.PixelFormat of

   pf4bit:Bits := 1;

   pf8bit:Bits := 1;

   pf15bit:Bits := 2;

   pf16bit:Bits := 2;

   pf24bit:Bits := 3;

   pf32bit:Bits := 4;

  end;

  for J :=0 toImage1.Picture.Bitmap.Width * Bits — 1 do

   Line^[J] := 255 — Line^[J];

 end;

 Image1.Visible :=False;

 Image1.Visible :=True;

 N4.Enabled := True;

end;

/>

Рис. № 10. Исходное изображение для инверсии.

/>

Рис. № 11. Результат инверсии изображения.

еще рефераты
Еще работы по информатике, программированию