Министерство образования и науки Украины
Государственный университет информатики и искусственного интеллекта
Д08401464.ЛР
Кафедра программное обеспечение интеллектуальных систем
Лабораторная работа №5
по курсу: «Распознавание изображений»
на тему: «Описание линий»
Проверил:
_____________ ст.
преп. Бочаров Д. М.
(дата,
подпись)
Выполнил:
_____________ ст.
гр. СШИ-11с Дьяченко О.В.
(дата, подпись)
Донецк
2011
Цель: получение практических навыков описания контуров объектов на изображении при помощи аппроксимации прямыми линиями.
Задание.
В систему компьютерной обработки изображений, разработанную в предыдущих лабораторных работах, добавить функцию описания выделенного контура объекта методом цепного кодирования.
Теоретическая информация
Цепное кодирование является широко известным способом описания границы дискретного объекта. На изображение, содержащее кривую линию, наносится сетка, и фиксируются узлы, ближайшие к пересечению с кривой. Затем последовательность узлов кодируется восьмеричными числами в соответствии с кодом Фримена. Цепным кодом (кодом Фримэна) называют последовательность целых чисел от 0 до 7, задающих одно из семи дискретных направлений при переходе от одной граничной точки к следующей при выбранном направлении обхода границы. Граница при этом понимается как замкнутая цепочка в смысле восьми соседей. Этот метод особенно удобен при сравнении двух кривых. Если две кривые идентичны, то функция взаимной корреляции достигает значения 1.
Рисунок 1 – Код Фримэна
Экранные формы
Рисунок 2 – Результат работы программы
Листинг программы
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;
……
private
Mass: array [0..255] of integer;
moda: integer;
public
end;
var
Form_Main: TForm_Main;
MyRect,MyRect2: TRect;
implementation
uses Gist;
{$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.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);
// заполняем массив сетки 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.
Выводы: В результате выполнения работы были получены практические навыки описания контуров объектов на изображении при помощи аппроксимации прямыми линиями и выполнена программная реализация описания контуров числами Фримена на языке высокого уровня.