Алгоритмы выделения контуров
Рефераты >> Программирование и компьютеры >> Алгоритмы выделения контуров

Файл заголовка:

//---------------------------------------------------------------------------

#ifndef MainUnitH

#define MainUnitH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <Graphics.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

published: // IDE-managed Components

TPanel *Panel1;

TImage *FromImage;

TPanel *Panel2;

TImage *ToImage;

TButton *Button1;

void fastcall Button1Click(TObject *Sender);

private: // User declarations

public: // User declarations

fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

cpp файл:

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "MainUnit.h"

#include "GraphicUnit.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void fastcall TForm1::Button1Click(TObject *Sender)

{

AlgorithBeatle(FromImage->Picture->Bitmap,

ToImage->Picture->Bitmap);

ToImage->Visible = false;

ToImage->Visible = true;

}

//---------------------------------------------------------------------------

Листинг 4. Модуль выделения контуров.

Файл заголовка:

//---------------------------------------------------------------------------

#ifndef GraphicUnitH

#define GraphicUnitH

//---------------------------------------------------------------------------

#include <Graphics.hpp>

extern void AlgorithBeatle(Graphics::TBitmap* FromImage,

Graphics::TBitmap* ToImage);

extern void AlgorithScan(Graphics::TBitmap* FromImage,

Graphics::TBitmap* ToImage);

#endif

cpp файл:

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "GraphicUnit.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#include <Sysutils.hpp>

/*

Отслеживающий алгоритм выделения контуров

"Алгоритм жука"

*/

void AlgorithBeatle(Graphics::TBitmap* FromImage,

Graphics::TBitmap* ToImage)

{

typedef enum {North, East, South, West} TDirectional;

int X,Y; // Координаты первой встречи с объектом

int cX,cY; // Текущие координаты маркера

Byte *Line, *ToLine; // Обрабатываемые линии

Byte B; // Значение текущего пиксела

TDirectional Direct; // Направление движения жука

// Идем до тех пор, пока не встретим черную область

for (Y = 0; Y < FromImage->Height; Y++)

{

Line = (Byte*)FromImage->ScanLine[Y];

for (X = 0; X < FromImage->Width; X++)

{

B = Line[X];

if (B < 255)

break;

}

// Если встречен объект, отличающийся от цвета фона (255 - белый)

// прервать поиск

if (X != FromImage->Width)

break;

}

// Если не нашли ни одного черного пиксела, то выходим из процедуры

if ((X == FromImage->Width) && (Y == FromImage->Height))

return;

// Если все нормально, начинаем обход по алгоритму жука

ToLine = (Byte*)ToImage->ScanLine[Y];

ToLine[X] = 0;

// Поворачиваем налево (новое направление - север)

cX = X;

cY = Y - 1;

Direct = North;

Line = (Byte*)FromImage->ScanLine[cY];

// Пока не придем в исходную точку, выделяем контур объекта

while ((cX != X) || (cY != Y))

{

// В зависимости от текущего направления движения жука

switch (Direct)

{

// Север

case North:

{

B = Line[cX];

// Если элемент "черный", поворачиваем снова "налево"

if (B < 255)

{

ToLine = (Byte*)ToImage->ScanLine[cY];

ToLine[cX] = 0;

Direct = West;

cX--;

}

// Иначе поворачиваем "направо"

else

{

Direct = East;

cX++;

}

}

break;

// Восток

case East:

{

B = Line[cX];

// Если элемент "черный", поворачиваем снова "налево"

if (B < 255)

{

ToLine = (Byte*)ToImage->ScanLine[cY];

ToLine[cX] = 0;

Direct = North;

cY--;

Line = (Byte*)FromImage->ScanLine[cY];

}

// Иначе поворачиваем "направо"

else

{

Direct = South;

cY++;

Line = (Byte*)FromImage->ScanLine[cY];

}

}

break;

// Юг

case South:

{

B = Line[cX];

// Если элемент "черный", поворачиваем снова "налево"

if (B < 255)

{

ToLine = (Byte*)ToImage->ScanLine[cY];

ToLine[cX] = 0;

Direct = East;

cX++;

}

// Иначе поворачиваем "направо"

else

{

Direct = West;

cX--;

}

}

break;

// Запад

case West:

{

B = Line[cX];

// Если элемент "черный", поворачиваем снова "налево"

if (B < 255)

{

ToLine = (Byte*)ToImage->ScanLine[cY];

ToLine[cX] = 0;

Direct = South;

cY++;

Line = (Byte*)FromImage->ScanLine[cY];

}

// Иначе поворачиваем "направо"

else

{

Direct = North;

cY--;

Line = (Byte*)FromImage->ScanLine[cY];

}

}

}

}

}

// ---------------------------------------------------------------------------

void AlgorithScan(Graphics::TBitmap* FromImage,

Graphics::TBitmap* ToImage)

{

// Тип ветви (левая или правая)

typedef enum {bLeft, bRight} TBranchType;

// Структура, описывающая ветвь

struct TBranch

{

TBranchType BranchType; // Тип ветви

TBranch* Branch; // Парная ветвь

};

// Структура, описывающая строку

struct TString

{

int BeginX; // Начало черной серии

int EndX; // Конец черной серии

TBranch* Branch; // Указатель на структуру ветви

};

// Возможные ситуации

typedef enum {

sBegin, // Начало

sNext, // Продолжение

sBranch, // Ветвление

sFusion, // Слияние

sEnd // Конец

} TSituation;

// Сканируемая полоса

struct TLine

{

Byte* L1; // Верхняя линия


Страница: