
- •1 Постановка задачи
- •2 Описание реализуемых методов и алгоритмов
- •3 Описание программной реализации
- •В ходе работы были выполнены следующие задачи:
- •Реализована обработка дискретного изображения и расчет его характеристик как:
- •Реализованы зашумление изображения и алгоритмы фильтрации при помощи:
- •Реализованы методы обнаружения границ на изображении при помощи операторов Превитта, Кирша и Лапласса.
- •Реализовано описание контура объекта цепным кодированием.
- •А.4.2.1 Требования к программному обеспечению
А.4.2.1 Требования к программному обеспечению
К программному обеспечению предъявляется следующие требования:
обеспечение функционирования создаваемой программы в пользовательском режиме;
реализовать программу в виде отдельных процедур и функций;
Программным обеспечением для проектирования программы эмуляции является среда Embarcadero RAD Studio Delphi 2011. Требуемая операционная система: Microsoft Windows XP, Vista, Seven.
А.4.2.2 Требования к техническому обеспечению
Для нормального функционирования программы предъявляются следующие требования:
процессор не ниже Intel Core 2 Duo 2,66 Мгц и выше;
видеокарта;
1 Гб оперативной памяти;
5 Mb дискового пространства;
SVGA монитор;
клавиатура;
мышь.
А.4.2.3 Требования к организационному обеспечению
В программную документацию должны входить:
1) пояснительная записка;
2) приложения:
а) техническое задание
б) руководство пользователя;
в) экранные формы;
г) листинги основных блоков программы.
Приложение Б
РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ
Б.1 Комплект поставки ПО
В комплект поставки входят следующие файлы:
Kurs.exe – исполняемый файл программного продукта;
ЦепКодирование.bmp – рисунок для цепного кодирования;
Рисунок.bmp – рисунок для обработки;
Б.2 Описание интерфейса
При запуске программы открывается главное окно выбора операций обработки изображения (см. рис. В.1). Главное окно содержит меню. В пункте меню «Файл» вы можете выбрать такие функции как открыть файл, сохранить, закрыть все окна или выйти из программы (см. рис. Б.1).
Рисунок Б.1 – Подпункты меню «Файл»
В пункте «Изображение» исходную картинку можно преобразовать в полутоновое (оттенки серого) или вырезать ранее выделенный фрагмент изображения, при этом открывается новое дочернее окошко с вырезанным фрагментом. Внешний вид подпункта меню «Изображение» представлен на рисунке Б.2.
Рисунок Б.2 – Подпункты меню «Изображение»
При нажатии в меню на «Поворот» появляется список возможных поворотов текущего изображения. Список представлен на рисунке Б.3. Пример поворота изображения представлен на рисунке Б.4.
Рисунок Б.3 – Список возможных поворотов
Рисунок Б.4 – Поворот изображения на 90 градусов
В пункте меню «Фильтрация» можно выбрать подпункт гистограмма, аддитивный или импульсный шум, или же один из видов фильтра. Список представлен на рисунках Б.5 и Б.6. На рисунке В.2 представлен пример построенной гистограммы.
Рисунок Б.5 – Виды шума на изображении
Рисунок Б.6 – Виды фильтров
При нажатии на пункте меню «Сегментация» появляется список видов сегментации изображения (см. рис. Б.7). Примеры сегментации приведены на рисунке В.7.
Рисунок Б.7 – Список видов сегментации изображения
В пункте меню «Обнаружение границ» можно выбрать один из способов обнаружения границ на изображении (см. рис. Б.8). Пример обнаружения границ представлен на рисунке В.9.
Рисунок Б.8 – Список способов обнаружения границ на изображении
В пункте меню «Цепное кодирование» реализовано описание границ объектов на изображении с использованием кода Фримена.
Рисунок Б.9 – Пункт меню «Цепное кодирование»
В статусной строке главного окна программы отображаются текущие координаты указателя мыши, яркость пиксела находящегося под курсором, а также расстояние между двумя пикселами изображения с помощью трех функций, т.е. D1, D2, D3 (см. рис. В.4).
Приложение В
ЭКРАННЫЕ ФОРМЫ
Рисунок В.1 – Главное окно программы
Рисунок В.2 – Гистограмма изображения
Рисунок В.3 –Аддитивный шум
Рисунок В.4 – Аддитивный шум (Фильтрация 3 – осреднение скользящим окном, Фильтрация 4 – свёртка с маской, Фильтрация 5 – медианный, Фильтрация 6 – Гаусса, Фильтрация 7 – Сигма-фильтр)
Рисунок В.5 – Импульсный шум
Рисунок В.6 – Импульсный шум (Фильтрация 3 – осреднение скользящим окном, Фильтрация 4 – свёртка с маской, Фильтрация 5 – медианный, Фильтрация 6 – Гаусса, Фильтрация 7 – Сигма-фильтр)
Рисунок В.7 – Примеры сегментации изображения алгоритмом водораздела и пороговой сегментацией
Рисунок В.8 – Цепное кодирование (Код Фримена)
Рисунок В.9 – Алгоритмы обнаружения границ на изображении (оператор Превитта, оператор Кирша, оператор Лапласса)
Приложение Г
ЛИСТИНГ ОСНОВНЫХ БЛОКОВ ПРОГРАММЫ
Г.1 Модуль 1 (Исходный код Main.pas)
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, ExtDlgs, ExtCtrls, Math, Child, ComCtrls;
type
TForm_Main = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N901: TMenuItem;
N1801: TMenuItem;
N2601: TMenuItem;
N10: TMenuItem;
Cascade1: TMenuItem;
Tile1: TMenuItem;
OpenPictureDialog1: TOpenPictureDialog;
SavePictureDialog1: TSavePictureDialog;
N11: TMenuItem;
N12: TMenuItem;
N13: TMenuItem;
N14: TMenuItem;
N15: TMenuItem;
N16: TMenuItem;
N17: TMenuItem;
N18: TMenuItem;
N19: TMenuItem;
N20: TMenuItem;
N21: TMenuItem;
N22: TMenuItem;
N23: TMenuItem;
StatusBar1: TStatusBar;
tuvtynfwbz1: TMenuItem;
N24: TMenuItem;
N25: TMenuItem;
N26: TMenuItem;
N27: TMenuItem;
N28: TMenuItem;
N29: TMenuItem;
N30: TMenuItem;
A1: TMenuItem;
procedure N2Click(Sender: TObject);
procedure N4Click(Sender: TObject);
procedure Cascade1Click(Sender: TObject);
procedure Tile1Click(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure N8Click(Sender: TObject);
procedure N901Click(Sender: TObject);
procedure N1801Click(Sender: TObject);
procedure N2601Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Gray(FCh,tCh: TForm_Child);
procedure N12Click(Sender: TObject);
procedure N15Click(Sender: TObject);
procedure N16Click(Sender: TObject);
procedure N19Click(Sender: TObject);
procedure N20Click(Sender: TObject);
procedure N21Click(Sender: TObject);
procedure N22Click(Sender: TObject);
procedure N23Click(Sender: TObject);
procedure N24Click(Sender: TObject);
procedure N25Click(Sender: TObject);
procedure N27Click(Sender: TObject);
procedure N28Click(Sender: TObject);
procedure N29Click(Sender: TObject);
procedure A1Click(Sender: TObject);
private
Mass: array [0..255] of integer;
moda: integer;
public
end;
var
Form_Main: TForm_Main;
MyRect,MyRect2: TRect;
implementation
uses Gist,Kod;
{$R *.dfm}
//открыть изображение
procedure TForm_Main.N2Click(Sender: TObject);
var FChild: TForm_Child;
begin
if (OpenPictureDialog1.Execute=true) and (FileExists(OpenPictureDialog1.FileName)=true) then
begin
FChild:=TForm_Child.Create(Application);
FChild.Caption:=OpenPictureDialog1.FileName;
FChild.Image1.Picture.Bitmap.LoadFromFile(OpenPictureDialog1.FileName);
FChild.Image1.Width:=FChild.Image1.Picture.Bitmap.Width;
FChild.Image1.Height:=FChild.Image1.Picture.Bitmap.Height;
FChild.ClientWidth:=FChild.Image1.Picture.Bitmap.Width;
FChild.ClientHeight:=FChild.Image1.Picture.Bitmap.Height;
end;
end;
//сохранить
procedure TForm_Main.N3Click(Sender: TObject);
var tempChild: TForm_Child;
begin
if (SavePictureDialog1.Execute=true) then
begin
tempChild:=Tform_Child(ActiveMDIChild);
tempChild.Image1.Picture.Bitmap.SaveToFile(SavePictureDialog1.FileName+'.bmp');
end;
end;
//преобразование в полутоновое
procedure TForm_Main.Gray(FCh,tCh: TForm_Child);
var
i,j: integer;
color: TColor;
Gray: byte;
begin
for i:=0 to 255 do Mass[i]:=0;
for i:=0 to (tCh.Image1.Picture.Width-1) do
for j:=0 to (tCh.Image1.Picture.Height-1) do
begin
color:=tCh.Image1.Canvas.Pixels[i,j];
Gray:=Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
FCh.Image1.Canvas.Pixels[i,j]:=RGB(Gray,Gray,Gray);
Mass[Gray]:=Mass[Gray]+1;
end;
end;
//полутоновое
procedure TForm_Main.N7Click(Sender: TObject);
var
FChild,tempChild: TForm_Child;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Новое окно '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
Gray(FChild,tempChild);
end;
end;
end;
//вырезать
procedure TForm_Main.N8Click(Sender: TObject);
var
FChild,tempChild: TForm_Child;
sizeX,sizeY,sx1,sy1: integer;
i,j: integer;
LFrom,LTo: TColor;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
if (StrToInt(tempChild.EditSelect.Text)=1) then
begin
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Вырезано '+IntToStr(MDIChildCount);
FChild.ClientHeight:=MyRect.Bottom-MyRect.Top;
FChild.ClientWidth:=MyRect.Right-MyRect.Left;
FChild.Image1.Width:=FChild.ClientWidth;
FChild.Image1.Height:=FChild.ClientHeight;
MyRect2:=Rect(0,0,FChild.ClientWidth,FChild.ClientHeight);
FChild.Image1.Canvas.CopyRect(MyRect2,tempChild.Image1.Canvas,MyRect);
tempChild.Image1.canvas.Pen.Width := 1;
tempChild.Image1.canvas.Pen.Color:=clBlack;
tempChild.Image1.canvas.Pen.Mode := pmBlack;
tempChild.Image1.canvas.Pen.Style:=psSolid;
tempChild.Image1.canvas.Brush.Style:=bsSolid;
tempChild.Image1.canvas.Brush.Color:=clBlack;
tempChild.Image1.Canvas.Rectangle(x1,y1,lx,ly);
end;
end;
end;
end;
//поворот 90
procedure TForm_Main.N901Click(Sender: TObject);
var
FChild,tempChild: TForm_Child;
sizeX,sizeY: integer;
i,j: integer;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Поворот '+IntToStr(MDIChildCount+1);
FChild.ClientHeight:=tempChild.ClientWidth;
FChild.ClientWidth:=tempChild.ClientHeight;
FChild.Image1.Width:=tempChild.Image1.Height;
FChild.Image1.Height:=tempChild.Image1.Width;
end;
for i:=0 to (tempChild.Image1.Picture.Width) do
for j:=0 to (tempChild.Image1.Picture.Height) do
FChild.Image1.Canvas.Pixels[FChild.Image1.Width-j,i]:=tempChild.Image1.Canvas.Pixels[i,j];
end;
end;
//поворот 180
procedure TForm_Main.N1801Click(Sender: TObject);
var
FChild,tempChild: TForm_Child;
sizeX,sizeY: integer;
i,j: integer;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Поворот '+IntToStr(MDIChildCount+1);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
end;
for i:=0 to (tempChild.Image1.Picture.Width) do
for j:=0 to (tempChild.Image1.Picture.Height) do
FChild.Image1.Canvas.Pixels[FChild.Image1.Width-i,FChild.Image1.Height-j]:=tempChild.Image1.Canvas.Pixels[i,j];
end;
end;
//поворот 270
procedure TForm_Main.N2601Click(Sender: TObject);
var
FChild,tempChild: TForm_Child;
sizeX,sizeY: integer;
i,j: integer;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Поворот '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientWidth;
FChild.ClientWidth:=tempChild.ClientHeight;
FChild.Image1.Width:=tempChild.Image1.Height;
FChild.Image1.Height:=tempChild.Image1.Width;
end;
for i:=0 to (tempChild.Image1.Picture.Width) do
for j:=0 to (tempChild.Image1.Picture.Height) do
FChild.Image1.Canvas.Pixels[j,FChild.Image1.Height-i]:=tempChild.Image1.Canvas.Pixels[i,j];
end;
end;
//закрыть все окна
procedure TForm_Main.N4Click(Sender: TObject);
var i: integer;
begin
for i:=0 to MDIChildCount-1 do MDIChildren[i].Close;
end;
procedure TForm_Main.Button1Click(Sender: TObject);
begin
form_gist.Show;
end;
procedure TForm_Main.Cascade1Click(Sender: TObject);
begin
Cascade;
end;
procedure TForm_Main.Tile1Click(Sender: TObject);
begin
Tile;
end;
//гистограмма
procedure TForm_Main.N12Click(Sender: TObject);
var
tempChild: TForm_Child;
sizeX,sizeY,N: integer;
i,j,mx: integer;
Mat,Disp,Sigma: real;
color: TColor;
Gray: byte;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
sizeX:=tempChild.Image1.Picture.Bitmap.Width;
sizeY:=tempChild.Image1.Picture.Bitmap.Height;
for i:=0 to 255 do Mass[i]:=0;
Mat:=0; Disp:=0; mx:=0;
N:=tempChild.Image1.Width*tempChild.Image1.Height;
for i:=0 to (tempChild.Image1.Picture.Width-1) do
for j:=0 to (tempChild.Image1.Picture.Height-1) do
begin
color:=tempChild.Image1.Canvas.Pixels[i,j];
Gray:=Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
Mass[Gray]:=Mass[Gray]+1;
if (Mass[Gray]>mx) then mx:=Mass[Gray];
end;
Form_Gist.Chart1.Series[0].Clear();
for i:=0 to 255 do Form_Gist.Chart1.Series[0].AddXY(i,Mass[i],'',clBlue);
//мат.ожидание
for i:=0 to 255 do Mat:=Mat+Mass[i]*i;
Mat:=Mat/N;
Form_Gist.Label1.Caption:='Мат. ожидание = '+FloatToStr(Mat);
//дисперсия
for i:=0 to 255 do Disp:=Disp+Mass[i]*power((i-Mat),2);
Form_Gist.Label2.Caption:='Дисперсия = '+FloatToStr(Disp);
//СКО
Sigma:=sqrt(Disp);
Form_Gist.Label3.Caption:='СКО = '+FloatToStr(Sigma);
Form_Gist.ShowModal;
end;
end;
end;
//аддитивный шум
procedure TForm_Main.N15Click(Sender: TObject);
var
temp,i,j,ur: integer;
tempChild: TForm_Child;
begin
ur:=StrToInt(InputBox('Аддитивный шум', 'Введите уровень шума','20'));
N7Click(Sender);
tempChild:=Tform_Child(ActiveMDIChild);
for i:=0 to (tempChild.Image1.Picture.Width-1) do
for j:=0 to (tempChild.Image1.Picture.Height-1) do
begin
temp:=GetRValue(tempChild.Image1.Canvas.Pixels[i,j])+round(random(ur)-ur/2);
tempChild.Image1.Canvas.Pixels[i,j]:=RGB(temp,temp,temp);
end;
end;
//импульсный шум
procedure TForm_Main.N16Click(Sender: TObject);
var
i,h,w,temp2: integer;
temp: real;
tempChild: TForm_Child;
begin
temp:=StrToFloat(InputBox('Импульсный шум', 'Введите парамер шума','0,1'));
N7Click(Sender);
tempChild:=Tform_Child(ActiveMDIChild);
temp2:=round(temp*(tempChild.Image1.Picture.Height*tempChild.Image1.Picture.Width));
for i:=0 to temp2 do
begin
h:=random(tempChild.Image1.Picture.Height+1);
w:=random(tempChild.Image1.Picture.Width+1);
tempChild.Image1.Canvas.Pixels[w,h]:=RGB(255,255,255);
end;
end;
//осреднение скользящим окном
procedure TForm_Main.N19Click(Sender: TObject);
var
temp,i,j,k,l: integer;
maska: array [0..2,0..2] of integer;
FChild,tempChild: TForm_Child;
begin
maska[0,0]:=1; maska[0,1]:=1; maska[0,2]:=1;
maska[1,0]:=1; maska[1,1]:=1; maska[1,2]:=1;
maska[2,0]:=1; maska[2,1]:=1; maska[2,2]:=1;
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Фильтрация '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=0 to (tempChild.Image1.Picture.Width-1) do
for j:=0 to (tempChild.Image1.Picture.Height-1) do
begin
temp:=0;
for k:=0 to 2 do
for l:=0 to 2 do temp:=temp+maska[k,l]*GetRValue(tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1]);
temp:=round(temp/9);
FChild.Image1.Canvas.Pixels[i,j]:=RGB(temp,temp,temp);
end;
end;
end;
end;
//свертка с маской
procedure TForm_Main.N20Click(Sender: TObject);
var
temp,i,j,k,l: integer;
maska: array [0..2,0..2] of integer;
FChild,tempChild: TForm_Child;
begin
maska[0,0]:=1; maska[0,1]:=2; maska[0,2]:=1;
maska[1,0]:=2; maska[1,1]:=4; maska[1,2]:=2;
maska[2,0]:=1; maska[2,1]:=2; maska[2,2]:=1;
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Фильтрация '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=0 to (tempChild.Image1.Picture.Width-1) do
for j:=0 to (tempChild.Image1.Picture.Height-1) do
begin
temp:=0;
for k:=0 to 2 do
for l:=0 to 2 do temp:=temp+maska[k,l]*GetRValue(tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1]);
temp:=round(temp/16);
FChild.Image1.Canvas.Pixels[i,j]:=RGB(temp,temp,temp);
end;
end;
end;
end;
//медианный
procedure TForm_Main.N21Click(Sender: TObject);
var
temp,i,j,k,l: integer;
mediana: array [0..8] of integer;
FChild,tempChild: TForm_Child;
begin
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Фильтрация '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=1 to (tempChild.Image1.Picture.Width-2) do
for j:=1 to (tempChild.Image1.Picture.Height-2) do
begin
mediana[0]:=GetRValue(tempChild.Image1.Canvas.Pixels[i-1,j-1]);
mediana[1]:=GetRValue(tempChild.Image1.Canvas.Pixels[i,j-1]);
mediana[2]:=GetRValue(tempChild.Image1.Canvas.Pixels[i+1,j-1]);
mediana[3]:=GetRValue(tempChild.Image1.Canvas.Pixels[i-1,j]);
mediana[4]:=GetRValue(tempChild.Image1.Canvas.Pixels[i,j]);
mediana[5]:=GetRValue(tempChild.Image1.Canvas.Pixels[i+1,j]);
mediana[6]:=GetRValue(tempChild.Image1.Canvas.Pixels[i-1,j+1]);
mediana[7]:=GetRValue(tempChild.Image1.Canvas.Pixels[i,j+1]);
mediana[8]:=GetRValue(tempChild.Image1.Canvas.Pixels[i+1,j+1]);
//отсортировать
temp:=1;
while (temp<>0) do
begin
temp:=0;
for k:=0 to 8 do
if (mediana[k]>mediana[k+1]) then
begin
temp:=mediana[k];
mediana[k]:=mediana[k+1];
mediana[k+1]:=temp
end;
end;
FChild.Image1.Canvas.Pixels[i,j]:=RGB(mediana[4],mediana[4],mediana[4]);
end;
end;
end;
end;
//фильтр Гаусса
procedure TForm_Main.N22Click(Sender: TObject);
var
i,j,k,l: integer;
maska: array [0..2,0..2] of real;
temp,t,sum: real;
FChild,tempChild: TForm_Child;
begin
t:=StrToInt(InputBox('Ввод параметров','Введите параметр T:','1'));
sum:=0;
maska[0,0]:=1; maska[0,1]:=2; maska[0,2]:=1;
maska[1,0]:=2; maska[1,1]:=4; maska[1,2]:=2;
maska[2,0]:=1; maska[2,1]:=2; maska[2,2]:=1;
for k:=0 to 2 do
for l:=0 to 2 do
begin
maska[k,l]:=exp(-maska[k,l]/power(t,2));
sum:=sum+maska[k,l];
end;
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Фильтрация '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=0 to (tempChild.Image1.Picture.Width-1) do
for j:=0 to (tempChild.Image1.Picture.Height-1) do
begin
temp:=0;
for k:=0 to 2 do
for l:=0 to 2 do temp:=temp+maska[k,l]*GetRValue(tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1]);
temp:=temp/sum;
FChild.Image1.Canvas.Pixels[i,j]:=RGB(round(temp),round(temp),round(temp));
end;
end;
end;
end;
//сигма-фильтр
procedure TForm_Main.N23Click(Sender: TObject);
var
i,j,k,l,temp,temp2: integer;
kol,col1,col2,c: integer;
sum1,sum2,sigma: real;
FChild,tempChild: TForm_Child;
begin
c:=StrToInt(InputBox('Ввод параметров','Введите параметр С:','1'));
if not (ActiveMDIChild=Nil) then
begin
if ActiveMDIChild is TForm_Child then
begin
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Фильтрация '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=0 to 255 do sum1:=sum1+Mass[i]*i;
sum1:=sum1/(tempChild.Image1.Width*tempChild.Image1.Height);
for i:=0 to 255 do sum2:=sum2+Mass[i]*power((i-sum1),2);
sum2:=sum2/(tempChild.Image1.Width*tempChild.Image1.Height);
sigma:=sqrt(sum2);
for i:=0 to (tempChild.Image1.Picture.Width-1) do
for j:=0 to (tempChild.Image1.Picture.Height-1) do
begin
col1:=GetRValue(tempChild.Image1.Canvas.Pixels[i,j]);
temp:=0;
temp2:=0;
for k:=0 to 2 do
for l:=0 to 2 do
begin
col2:=GetRValue(tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1]);
if (abs(col2-col1)<c*sigma) then
begin
temp2:=temp2+col2;
temp:=temp+1;
end;
end;
temp2:=round(temp2/temp);
FChild.Image1.Canvas.Pixels[i,j]:=RGB(temp2,temp2,temp2);
end;
end;
end;
end;
//оператор Лапласса
procedure TForm_Main.N29Click(Sender: TObject);
var
i,j,k,l,temp,temp2: integer;
color: TColor;
maska,maska2: array [0..2,0..2] of integer;
FChild,tempChild: TForm_Child;
begin
maska[0,0]:=-1; maska[0,1]:=-1; maska[0,2]:=-1;
maska[1,0]:=-1; maska[1,1]:=8; maska[1,2]:=-1;
maska[2,0]:=-1; maska[2,1]:=-1; maska[2,2]:=-1;
maska2[0,0]:=0; maska2[0,1]:=-1; maska2[0,2]:=0;
maska2[1,0]:=-1; maska2[1,1]:=4; maska2[1,2]:=-1;
maska2[2,0]:=0; maska2[2,1]:=-1; maska2[2,2]:=0;
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Оператор Лапласса '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=1 to (tempChild.Image1.Picture.Width-2) do
for j:=1 to (tempChild.Image1.Picture.Height-2) do
begin
temp:=0; temp2:=0;
for k:=0 to 2 do
for l:=0 to 2 do
begin
color:=tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1];
temp:=temp+maska[k,l]*Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
temp2:=temp2+maska2[k,l]*Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
end;
temp:=round(temp/8);
temp2:=round(temp2/4);
temp:=round(sqrt(power(temp,2)+power(temp2,2)));
FChild.Image1.Canvas.Pixels[i,j]:=RGB(255-temp,255-temp,255-temp);
end;
end;
//оператор Превитта
procedure TForm_Main.N27Click(Sender: TObject);
var
i,j,k,l,temp,temp2: integer;
color: TColor;
maska: array [0..2,0..2] of integer;
FChild,tempChild: TForm_Child;
begin
maska[0,0]:=1; maska[0,1]:=0; maska[0,2]:=-1;
maska[1,0]:=1; maska[1,1]:=0; maska[1,2]:=-1;
maska[2,0]:=1; maska[2,1]:=0; maska[2,2]:=-1;
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Оператор Превитта '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=1 to (tempChild.Image1.Picture.Width-2) do
for j:=1 to (tempChild.Image1.Picture.Height-2) do
begin
temp:=0; temp2:=0;
for k:=0 to 2 do
for l:=0 to 2 do
begin
color:=tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1];
temp:=temp+maska[k,l]*Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
temp2:=temp2+maska[l,k]*Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
end;
temp:=round(temp/3);
temp2:=round(temp2/3);
temp:=round(sqrt(power(temp,2)+power(temp2,2)));
FChild.Image1.Canvas.Pixels[i,j]:=RGB(255-temp,255-temp,255-temp);
end;
end;
//оператор Кирша
procedure TForm_Main.N28Click(Sender: TObject);
var
i,j,k,l,temp,temp2: integer;
color: TColor;
maska: array [0..2,0..2] of integer;
FChild,tempChild: TForm_Child;
begin
maska[0,0]:=5; maska[0,1]:=5; maska[0,2]:=5;
maska[1,0]:=-3; maska[1,1]:=0; maska[1,2]:=-3;
maska[2,0]:=-3; maska[2,1]:=-3; maska[2,2]:=-3;
tempChild:=Tform_Child(ActiveMDIChild);
FChild:=TForm_Child.Create(Application);
FChild.Caption:='Оператор Кирша '+IntToStr(MDIChildCount);
FChild.ClientHeight:=tempChild.ClientHeight;
FChild.ClientWidth:=tempChild.ClientWidth;
FChild.Image1.Width:=tempChild.Image1.Width;
FChild.Image1.Height:=tempChild.Image1.Height;
for i:=1 to (tempChild.Image1.Picture.Width-2) do
for j:=1 to (tempChild.Image1.Picture.Height-2) do
begin
temp:=0; temp2:=0;
for k:=0 to 2 do
for l:=0 to 2 do
begin
color:=tempChild.Image1.Canvas.Pixels[i+k-1,j+l-1];
temp:=temp+maska[k,l]*Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
temp2:=temp2+maska[l,k]*Round((0.30*GetRValue(color))+(0.59*GetGValue(color))+(0.11*GetBValue(color)));
end;
temp:=round(temp/15);
temp2:=round(temp2/15);
temp:=round(sqrt(power(temp,2)+power(temp2,2)));
FChild.Image1.Canvas.Pixels[i,j]:=RGB(255-temp,255-temp,255-temp);
end;
end;
//цепное кодирование
procedure TForm_Main.A1Click(Sender: TObject);
var
i,j,k,l,temp: integer;
tempChild: TForm_Child;
w,h,sw,sh,kol_object: integer;
s_mass: array [0..100,0..100] of integer;
originalColor: TColor;
kod_F: string;
ind_w,ind_h: integer;
begin
if not (ActiveMDIChild=Nil) then
begin
temp:=StrToInt(InputBox('Цепное кодирование', 'Введите количество пикселей в на квадрат сетки','5'));
tempChild:=Tform_Child(ActiveMDIChild);
w:=tempChild.Image1.Width;
h:=tempChild.Image1.Height;
sw:=round(w/temp); sh:=round(h/temp);
Form_Kod.Memo1.Clear;
// заполняем массив сетки 0
for i:=0 to sw-1 do
for j:=0 to sh-1 do s_mass[i,j]:=0;
//считаем ср. яркость каждого квадрата
for i:=0 to sw-1 do
for j:=0 to sh-1 do
begin
//считываем все пиксели квадрата и записываем их
for k:=0 to temp-1 do
for l:=0 to temp-1 do
begin
originalColor:=tempChild.Image1.Canvas.Pixels[i*temp+k, j*temp+l];
s_mass[i,j]:=s_mass[i,j]+GetRValue(originalColor);
end;
s_mass[i,j]:=round(s_mass[i,j]/(temp*temp));
end;
kod_F:='';
kol_object:=1;
//основная функция
for i:=0 to sw-1 do
for j:=0 to sh-1 do
begin
if (s_mass[i,j]>0) then
begin
ind_w:=i;
ind_h:=j;
while(true) do
begin
//выходим если вокруг все 0 или -1
if ( ((s_mass[ind_w-1,ind_h-1]=-1) or (s_mass[ind_w-1,ind_h-1]=0))
and ((s_mass[ind_w,ind_h-1]=-1) or (s_mass[ind_w,ind_h-1]=0))
and ((s_mass[ind_w+1,ind_h-1]=-1) or (s_mass[ind_w+1,ind_h-1]=0))
and ((s_mass[ind_w-1,ind_h]=-1) or (s_mass[ind_w-1,ind_h]=0))
and ((s_mass[ind_w+1,ind_h]=-1) or (s_mass[ind_w+1,ind_h]=0))
and ((s_mass[ind_w-1,ind_h+1]=-1) or (s_mass[ind_w-1,ind_h+1]=0))
and ((s_mass[ind_w,ind_h+1]=-1) or (s_mass[ind_w,ind_h+1]=0))
and ((s_mass[ind_w+1,ind_h+1]=-1) or (s_mass[ind_w+1,ind_h+1]=0)))
then
begin
break;
end;
//если граница уходит за картинку
if (((ind_w-1)<0) or ((ind_h-1)<0) or ((ind_w+1)>=sw) or ((ind_h+1)>=sh)) then
begin
break;
end;
//3
if ((s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w,ind_h-1])
and (s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w+1,ind_h-1])
and (s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w+1,ind_h])
and (s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w-1,ind_h+1])
and (s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w,ind_h+1])
and (s_mass[ind_w-1,ind_h-1]>=s_mass[ind_w+1,ind_h+1])) then
begin
kod_F:=kod_F+'3';
s_mass[ind_w,ind_h]:=-1;
ind_w:=ind_w-1;
ind_h:=ind_h-1;
end
else
begin
//2
if ((s_mass[ind_w,ind_h-1]>=s_mass[ind_w-1,ind_h-1])
and (s_mass[ind_w,ind_h-1]>=s_mass[ind_w+1,ind_h-1])
and (s_mass[ind_w,ind_h-1]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w,ind_h-1]>=s_mass[ind_w+1,ind_h])
and (s_mass[ind_w,ind_h-1]>=s_mass[ind_w-1,ind_h+1])
and (s_mass[ind_w,ind_h-1]>=s_mass[ind_w,ind_h+1])
and (s_mass[ind_w,ind_h-1]>=s_mass[ind_w+1,ind_h+1])) then
begin
kod_F:=kod_F+'2';
s_mass[ind_w,ind_h]:=-1;
ind_h:=ind_h-1;
end
else
begin
//1
if ((s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w-1,ind_h-1])
and (s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w,ind_h-1])
and (s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w+1,ind_h])
and (s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w-1,ind_h+1])
and (s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w,ind_h+1])
and (s_mass[ind_w+1,ind_h-1]>=s_mass[ind_w+1,ind_h+1])) then
begin
kod_F:=kod_F+'1';
s_mass[ind_w,ind_h]:=-1;
ind_w:=ind_w+1;
ind_h:=ind_h-1;
end
else
begin
//0
if ((s_mass[ind_w+1,ind_h]>=s_mass[ind_w-1,ind_h-1])
and (s_mass[ind_w+1,ind_h]>=s_mass[ind_w,ind_h-1])
and (s_mass[ind_w+1,ind_h]>=s_mass[ind_w+1,ind_h-1])
and (s_mass[ind_w+1,ind_h]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w+1,ind_h]>=s_mass[ind_w-1,ind_h+1])
and (s_mass[ind_w+1,ind_h]>=s_mass[ind_w,ind_h+1])
and (s_mass[ind_w+1,ind_h]>=s_mass[ind_w+1,ind_h+1])) then
begin
kod_F:=kod_F+'0';
s_mass[ind_w,ind_h]:=-1;
ind_w:=ind_w+1;
end
else
begin
//7
if ((s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w-1,ind_h-1])
and (s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w,ind_h-1])
and (s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w+1,ind_h-1])
and (s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w+1,ind_h])
and (s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w-1,ind_h+1])
and (s_mass[ind_w+1,ind_h+1]>=s_mass[ind_w,ind_h+1])) then
begin
kod_F:=kod_F+'7';
s_mass[ind_w,ind_h]:=-1;
ind_w:=ind_w+1;
ind_h:=ind_h+1;
end
else
begin
//6
if ((s_mass[ind_w,ind_h+1]>=s_mass[ind_w-1,ind_h-1])
and (s_mass[ind_w,ind_h+1]>=s_mass[ind_w,ind_h-1])
and (s_mass[ind_w,ind_h+1]>=s_mass[ind_w+1,ind_h-1])
and (s_mass[ind_w,ind_h+1]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w,ind_h+1]>=s_mass[ind_w+1,ind_h])
and (s_mass[ind_w,ind_h+1]>=s_mass[ind_w-1,ind_h+1])
and (s_mass[ind_w,ind_h+1]>=s_mass[ind_w+1,ind_h+1])) then
begin
kod_F:=kod_F+'6';
s_mass[ind_w,ind_h]:=-1;
ind_h:=ind_h+1;
end
else
begin
//5
if ((s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w-1,ind_h-1])
and (s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w,ind_h-1])
and (s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w+1,ind_h-1])
and (s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w-1,ind_h])
and (s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w+1,ind_h])
and (s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w,ind_h+1])
and (s_mass[ind_w-1,ind_h+1]>=s_mass[ind_w+1,ind_h+1])) then
begin
kod_F:=kod_F+'5';
s_mass[ind_w,ind_h]:=-1;
ind_w:=ind_w-1;
ind_h:=ind_h+1;
end
else
begin
kod_F:=kod_F+'4';
s_mass[ind_w,ind_h]:=-1;
ind_w:=ind_w-1;
end;
end;
end;
end;
end;
end;
end;
end;
if (Length(kod_F)>10) then
begin
Form_Kod.Show;
Form_Kod.Memo1.Lines.Add(inttostr(kol_object)+') '+kod_F) ;
kol_object:=kol_object+1;
kod_F:='';
end;
end;
end;
end;
end;
end.
Г.2 Модуль 2 (Исходный код Child.pas)
unit Child;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ComCtrls, StdCtrls, Math;
type
TForm_Child = class(TForm)
EditSelect: TEdit;
Image1: TImage;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
public
end;
var
Form_Child: TForm_Child;
Selection: integer=0;
x1: integer=0;
x2: integer=0;
y1: integer=0;
y2: integer=0;
Selected: integer=0;
lx,ly: integer;
implementation
uses Main;
{$R *.dfm}
procedure TForm_Child.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;
procedure TForm_Child.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (X>0) and (X<ClientWidth) and (Y>0) and (Y<ClientHeight) and (Button=mbLeft) then
begin
if (Selected=1) then Image1.Canvas.Rectangle(x1,y1,lx,ly);
Selection:=1;
EditSelect.Text:=IntToStr(Selection);
x1:=X; y1:=Y; lx:=X; ly:=Y;
Main.MyRect:=Rect(x1,y1,lx,ly);
end;
end;