Первая страница
Наша команда
Контакты
О нас

    Головна сторінка



Пояснювальна записка до магістерської кваліфікаційної роботи магістра

Пояснювальна записка до магістерської кваліфікаційної роботи магістра




Сторінка5/9
Дата конвертації13.03.2017
Розмір1.59 Mb.
ТипПояснювальна записка
1   2   3   4   5   6   7   8   9

Висновок
В даному розділі запропоновано спосіб знаходження та відстеження переміщення обличчя людини. Особливістю запропонованого способу знаходження та відстеження переміщення обличчя людини є введення етапу підтвердження виділених об’єктів за кольором шкіри людини. Розроблено спосіб сегментації зображення для знаходження обличчя людини. Відмінною особливістю запропонованого способу є об’єднання двох процесів - кластеризація зображення з використанням пошуку сегментів по просторовому та колірному признаку. Розроблено алгоритм по виділенню об’єктів цифрового зображення шляхом сегментації для знаходження обличчя людини та алгоритм колірної сегментації шкіри обличчя.

3 РОЗРОБКА ПРОГРАМНИХ ЗАСОБІВ ВІДСТЕЖУВАННЯ ЗА ПЕРЕМІЩЕННЯМ ОБЛИЧЧЯ
Послідовність знаходження та відстеження переміщення обличчя людини складається із ряду етапів. При цьому виконується пошук на зображенні області, для якої виконується певний критерій відповідності обличчю людини. Розробці програмних засобів знаходження та відстеження переміщення обличчя людини присвячений даний розділ. Нова розробка є подальшим вдосконаленням уже існуючих розробок з метою бути корисною та принести позитивний ефект як для потенційних споживачів, так і для виробників.
3.1 Обгрунтування вибору мови програмування
Об’єктно-орієнтовані мови програмування користуються великою популярністю серед програмістів, тому що вони дозволяють використовувати переваги об’єктно-орієнтованого підходу не тільки на етапах проектування і конструювання програмних систем, але і на етапах їхньої реалізації, тестування, супроводу. Нині найбільш розповсюдженими об’єктно-орієнтованими мовами програмування є С++, C#, Java.

C# — об'єктно-орієнтована мова програмування з безпечною системою типізації для платформи .NET. Розроблена Андерсом Гейлсбергом, Скотом Вілтамутом та Пітером Гольде під егідою Microsoft Research. Вона успадкувала від Java концепції віртуальної машини (середовище .NET), байт-коду (MSIL) і більшої безпеки вихідного коду програм, плюс врахувала досвід використання програм на Java.

Головною особливістю мови C# є його орієнтованість на платформу Microsoft .NET — творці C# ставили своєю метою надання розробникам природних засобів доступу до всіх можливостей платформи .NET.

Крім того, творці С# хотіли приховати від розробника якомога більше незначних технічних деталей, включаючи операції по упаковці та розпаковуванню типів, ініціалізації змінних і збірці сміття. Завдяки цьому програміст, що пише на C#, може краще концентруватися на змістовній частині завдання. В процесі рішення цієї задачі проектувальники C# намагалися врахувати уроки реалізації Visual Basic, який достатньо успішний в утаєнні деталей реалізації, але недостатньо ефективний для написання крупних промислових систем: творці C# декларують, що нова мова володіє потужністю С++ і в той же час простотою Visual Basic.

Таким чином, C# є мовою програмування, орієнтованою на розробку для платформи .NET і придатною як для швидкої розробки додатків, так і для розробки великомасштабних проектів.

C# займає деяку проміжну позицію: із стандарту мови прибрані найбільш неприємні і неоднозначні особливості С++, але в той же час мова зберегла потужні виразні можливості, властиві для таких мов, як С++ та Java [68].

Програма на мові C# виконується в середовищі .NET Framework - інтегрованому компоненті Windows, що містить віртуальну систему виконання (середовище CLR) і уніфікований набір бібліотек класів. Середовище CLR являє собою комерційну реалізацію інфраструктури Microsoft CLI (common language infrastructure), міжнародного стандарту, основи середовищ виконання і розробки з тісною взаємодією мов і бібліотек.

Вихідний код, написаний на мові C#, компілюється в проміжну мову (IL) у відповідності зі специфікацією CLI. Код IL та ресурси, такі як растрові зображення і рядки, зберігаються на диску в виконуваному файлі, званому збіркою, з розширенням EXE або DLL в більшості випадків. Збірка містить маніфест з відомостями про типи збірки, версії, мовою і регіональних параметрах і вимогах безпеки.

При виконанні програми на C# збірка завантажується в середовище CLR залежно від відомостей у маніфесті. Далі, якщо вимоги безпеки дотримані, середовище CLR виконує JIT-компіляцію для перетворення коду IL в інструкції машинного коду. Середовище CLR також надає інші служби, пов'язані з автоматичним збором сміття, обробкою виключень і управлінням ресурсами. Код, що виконується середовищем CLR, іноді називають «керованим кодом» в протиставлення «некерованому коду», який компілюється в машинний код, призначений для певної системи.

Взаємодія між мовами є ключовою особливістю .NET Framework. Оскільки код на проміжній мові IL, створений компілятором C#, відповідає специфікації CTS, код IL на основі C# може взаємодіяти з кодом, створюваним версіями мов Visual Basic, Visual C++, Visual J# платформи .NET Framework і ще більш ніж 20 CTS-сумісних мов. В одній збірці може бути кілька модулів, написаних на різних мовах платформи .NET Framework, і типи можуть посилатися один на одного, як якщо б вони були написані на одній мові.

Мова має строгу статичну типізацію, підтримує поліморфізм, перевантаження операторів, вказівники на функції-члени класів, атрибути, події, властивості, винятки, коментарі у форматі XML.

При створенні мови в основу дизайну лягла легкість використання, домінуюча над потужністю мови та швидкістю виконання. Цілісність концепції об'єктно-орієнтованої мови видно, скажімо в реалізації пакування/розпакування. Це дозволяє розглядати всі типи (навіть примітивні) як об'єкти, що дозволяє вирішувати багато проблем додатків.

У C# представлена ​​концепція просторів імен, аналогічна пакетів в Java. Це дозволяє ієрархічно структурувати систему типів, роблячи код набагато більш зрозумілим і дозволяючи уникнути проблем з ім'ям. Можна розглядати простір імен як директорії, а мовні типи як файли в цих директоріях.

Переваги C# [68, 69]:


  • C# створювався паралельно з каркасом Framework .Net і повною мірою враховує всі його можливості;

  • C# є повністю об'єктно-орієнтованою мовою, де навіть типи, вбудовані в мову, представлені класами;

  • C# є спадкоємцем мов C/C++, зберігаючи кращі риси цих популярних мов програмування. Загальний з цими мовами синтаксис, знайомі оператори мови полегшують перехід програмістів від С++ до C #;

  • зберігаючи основні риси свого попередника, мова стала простіше і надійніше;

  • завдяки каркасу Framework .Net, який став надбудовою над операційною системою, програмісти C# отримують ті ж переваги роботи з віртуальною машиною, що і програмісти Java. Ефективність коду навіть підвищується, оскільки виконавче середовище CLR являє собою компілятор проміжної мови, в той час як віртуальна Java-машина є інтерпретатором байт-коду;

  • потужна бібліотека каркаса підтримує зручність побудови різних типів додатків на C#, дозволяючи легко будувати Web-служби, інші види компонентів, досить просто зберігати і отримувати інформацію з бази даних та інших сховищ даних;

  • реалізація, що поєднує побудова надійного та ефективного коду, є важливим чинником, що сприяє успіху C# [68].

Із урахуванням перерахованих переваг вибираємо для розробки програмного забезпечення для виявлення та відстеження обличчя людини мову програмування C#.
3.2 Розробка програми відстеження за переміщенням обличчя людини
Проблема розпізнавання обличчя людини розглядалася ще на ранніх стадіях комп'ютерного зору. Ряд компаній протягом більше 40 років активно розробляють автоматизовані, а зараз і автоматичні системи розпізнавання людських облич [5, 27, 70-75]: ImageWare (система FaceID); Smith & Wesson (система ASID - Automated Suspect Identification System); Imagis, Epic Solutions, Spillman, Miros (система Trueface); Vissage Technology (система Vissage Gallery); Visionics (система FaceIt). На теперішній час існують багато програмних пакетів, в яких використовуються засоби для виділення та відстеження за переміщенням обличчя людини.

В даному напрямку, тобто по розробці та впровадженню програм для виділення та відстеження переміщення обличчя людини, працюють такі відомі фірми як: Google, Lenovo, Corel Corporation, Axio Vision, Creative та інші. Ними та іншими компаніями та фірмами розроблено ряд програмних продуктів, таких як FaceNet, CCT Face Recognition SDK 1.5, VeriFace Pro, FaceID, Automated Suspect Identification System, Face-Интеллект, Intelligent Scissors, Random Walker та інші [27, 70-75], які дозволяють проводити виділення та відстеження переміщення обличчя людини з використанням тих чи інших алгоритмів. В нашому випадку розробляється програмний продукт по обробці зображень з метою виділення та відстеження переміщення обличчя людини. Програма дозволяє проводити виділення обличчя людини на основі використання методу ключових точок обличчя із застосуванням сегментації зображення. Процес виділення обличчя людини завершується при виконані вибраних умов по аналізі ключових точок обличчя. В магістерській роботі пропонується розширити діапазон можливостей програми проведення виділення обличчя людини шляхом визначення розмірів сегментів по просторових ознаках та різниці перепаду кольору. Виділення сегментів зображення виконується на основі порівняння вибраних пікселів із сусідніми по колірному порогу.

Для написання програми використовуємо мову С#, а також програми із набору бібліотеки OpenCV. Першим етапом роботи програми буде задача виділення одного кадру з потоку. Для цього скористаємось розробленою процедурою private Capture capture.

Також необхідно вказати на клас, який буде вказувати, з якою швидкістю виконувати захват виділених об’єктів з відеопотоку. Створюємо об’єкт для таймеру, вказуємо інтервал для таймеру, запукаємо таймер та виконуємо процес захоплення одного кадру із відео потоку.

private Capture capture;

private HaarCascade haarCascade;

DispatcherTimer timer;

private void Window_Loaded(object sender, RoutedEventArgs e)

{

capture = new Capture();



haarCascade = new HaarCascade(@"haarcascade_frontalface_alt_ tree.xml");

timer = new DispatcherTimer();

timer.Tick += new EventHandler(timer_Tick);

timer.Interval = new TimeSpan(0, 0, 0, 0, 0);

timer.Start();

}

void timer_Tick(object sender, EventArgs e)



Наступним етапом буде попередня обробка зображення по корекції яскравості та кольору. Потім виконуємо просторове диференціювання отриманого зображення для виділення контурів об’єктів. Виділені об’єкти слугуватимуть для пошуку обличчя людини у зображенні. Наступним етапом буде реалізація процесу виявлення обличчя людини у зображенні. Даний етап виконаємо на основі метода ключових точок.

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

На наступному етапі створюється узагальнений список типу Іmage з параметрами Bgr, що вказує на формат отриманого зображення. Цьому формату присвоюємо ім’я, що розбивається на фрейми. Перевіряємо, чи дійсно отримано задані фрагменти є обличчям людини та конвертуємо їх в попередній формат.

Image currentFrame = capture.QueryFrame();

if (currentFrame != null)

{

Image grayFrame = currentFrame.Convert();



Отримуємо обличчя, яке вдалось розпізнати, та поміщаємо його у чорний прямокутник.

var detectedFaces = grayFrame.DetectHaarCascade(haarCascade)[0]; foreach (var face in detectedFaces)

{

currentFrame.Draw(face.rect, new Bgr(0, double.MaxValue, 0), 3);



Якщо облич більше двох, то для наступного обличчя використовуємо коричневий колір для прямокутника. Виводимо зображення на екран та очищаємо ресурси, що були задіяні.

if (detectedFaces.Length > 1)

currentFrame.Draw(face.rect, new Bgr(1, 29, 89), 3);

}

image1.Source = ToBitmapSource(currentFrame);



currentFrame.Dispose();

}

Програмний код описаних вище класів та методів поданий у додатках. Інші підпрограми, що розроблені для виділення та відстеження переміщення обличчя людини описані в наступних параграфах даної роботи.


3.3 Розробка підпрограми по сегментації зображення
Програма для сегментації зображення буде такою.

Описуємо основну функцію для проведення операції сегментації обличчя людини.

private void segmentation()

{


IplImage saveWork = cvCloneImage(work);

float arg1 = 1;

float arg2 = 1;

int arg3 = 1;

try {

arg1 = Float.parseFloat(otsMField.getText());



arg2 = Float.parseFloat(otsHField.getText());

arg3 = Integer.parseInt(clastField.getText());

} catch (NumberFormatException e1) {

arg1 = 1;

arg2 = 1;

arg3 = 1;

}

multiplerOne = arg1;



multiplerSecond = arg2;

Якщо зображення кольорове, то переводимо його у градації сірого кольору.

if (work.getBufferedImageType() != 10)

{


tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);

cvCvtColor(work, tmp, CV_RGB2GRAY);

work = cvCloneImage(tmp);

Виконуємо фільтрацію зображення від можливих завад з використанням медіанного фільтра.

cvSmooth(work, work, CV_MEDIAN, 7, 7, 0, 0);

IplImage smoothImage;

Створюємо копію початкового зображення для виконання операції кластеризації.

smoothImage = cvCloneImage(work);

IplImage partSecond;

Виділяємо границі таким способом, де зображення розділяємо на два: перше - по якому пройшлись диференційним оператором для виділення вертикальних ліній і друге - для виділення горизонтальних ліній.

partOne = difHeign();

partSecond = difWidth();

}

imgVertical = partSecond;



imgHorizontal = partOne;

Отримуєм горизонтальні та вертикальні контури.

IplImage wKontur = getWKontur();

IplImage hKontur = getHKontur();

Ці контури об’єднуємо в єдиний контур, який буде використаний для сегментації зображення.

IplImage kontur = mixInOne(wKontur, hKontur);

На першому етапі знаходимо максимальне та мінімальне значення кольорів у зображенні.

public void clast()

{

int min = getMin();



int max = getMax();

int clast_index = 0;

У визначеному діапазоні розставляємо центри кластерів.

for (int i = 0; i < claster_count; i++)

{

centroids.add(new ClastCentr((rand.nextInt(max - min - 1) + min)



+ rand.nextFloat(), clast_index++));

}

boolean isCheng = true;



Виконуємо процес кластеризації та перевіряємо, якщо якийсь кластер змінив свою позицію, значить потрібно ще ітерації.

while (isCheng)

{

isCheng = false;



iteration();

for (ClastCentr i : centroids)

{

if (i.isChengPosition)



isCheng = true;

Обраховуєм позицію кожного кластеру

for (ClastCentr i : centroids)

{

i.calcPosition();



}

Порівнюємо, якщо відстані від точки до її кластеру практично дорівнює відстані від точки до найближчого до неї кластеру, то записуємо цей кластер в альтернативний кластер.

min = 257;

int index = 0;

for (ClastPoint i : points)

{

min = 257;



for (int k = 0; k < claster_count; k++)

{

if (k == i.claster.number)



continue;

if (Math.abs(i.position - centroids.get(k).position) < min)

{

min = (int) Math.abs(i.position - centroids.get(k).position);



index = k;

}

int realDistans = (int) Math.abs(i.position - i.claster.position);



if ((realDistans / min) > 0.95)

{

i.alternativ_claster = centroids.get(index);



}

Проходимо по всім точкам, у яких є альтернативні кластери, і якщо пряма від точки до альтернативного кластера перетинає менше контурів, ніж пряма від точки до її кластера, то альтернативний кластер стає основним.

for (ClastPoint i : points)

{

if (i.alternativ_claster != null)



{

int crossingAlternativ = getNumberOfCrossing(i.X, i.Y,

i.alternativ_claster.X, i.alternativ_claster.Y);

int crossingMain = getNumberOfCrossing(i.X, i.Y, i.claster.X,

i.claster.Y);

if (crossingMain == crossingAlternativ)

}

if (crossingAlternativ < crossingMain)



{

i.claster = i.alternativ_claster;

Функція, що описує зміну кольору кластеру, буде такою

public void calcColor()

{

int R = 0;



int B = 0;

int G = 0;

int[] tmp = new int[3];

for (ClastPoint i : points)

{

tmp = i.color;



R += tmp[0];

G += tmp[1];

B += tmp[2];

}

if (points.size() > 0)



{

R = R / points.size();

G = G / points.size();

B = B / points.size();

}

color = new int[] { R, G, B };



}

Опис функції зміни позиції кластера виглядає таким чином.

public void calcPosition()

{

int X = 0;



int Y = 0;

for (ClastPoint i : points)

{

X += i.X;



Y += i.Y;

}

if (points.size() > 0)



{

this.X = X / points.size();

this.Y = Y / points.size();

}

Сегментуємо зображення, використовуючи контури для підвищення точності результатів сегментації. Результат виконаної операції виводимо на екран монітора.



Clastering clast = new Clastering(smoothImage, arg3, src, kontur);

clast.clast();

DrawWindow hough2 = new DrawWindow("Результат");

hough2.showImage(kontur.getBufferedImage());

showBorder(clast.getRezColor(), kontur);

work = cvCloneImage(saveWork);

Повна версія підпрограми сегментації зображення наведена у додатках до магістерської роботи.
3.4 Розробка підпрограми колірної сегментації
У роботі розглядалися колірні простори RGB, HSV та YCbCr. Простір RGB було вибрано для порівняння, а простори HSV і YCbCr - через наявність в них компоненти по кольору. Позбавлення від компоненти по яскравості при аналізі кольору пікселів дає можливість отримання інваріантності до зміни освітленості на зображенні. Для роботи програми було вибрано колірну модель YCbCr.

Конвертуємо RGB модель кольорів у модель YCbCr і використаємо перевірку на входження кольорів у вибраний діапазон

Y = [0, 1], Cb = [–0.15, 0.05], Cr = [0.05, 0.20].

Створюємо клас YCbCrColor для методу FromArgbColori

public static YCbCrColor FromArgbColori(int color)

Із моделі кольорів RGB вилучаємо компонент із color типу int та перетворюємо його в діапазон [0, 1].

const float f = 1f / 255f;

var r = (byte)(color >> 16) * f;

var g = (byte)(color >> 8) * f;

var b = (byte)(color) * f;

Створюємо новий YCbCr діапазон кольорів із моделі кольорів RGB за відомими формулами переведення в новий колірний простір.

var y = 0.299f * r + 0.587f * g + 0.114f * b;

var cb = -0.168736f * r + -0.331264f * g + 0.5f * b;

var cr = 0.5f * r + -0.418688f * g + -0.081312f * b;

return new YCbCrColor(y, cb, cr);

Кожний піксель в моделі кольорів YCbCr перевіряється з використання визначених нижніх та верхніх порогів:

public WriteableBitmap Process(WriteableBitmap snapshot)

{

var p = snapshot.Pixels;



var result = new WriteableBitmap(snapshot.PixelWidth, snapshot.PixelHeight);

var rp = result.Pixels;

Перевіряємо кожний піксель.

for (int i = 0; i < p.Length; i++)

{

var ycbcr = YCbCrColor.FromArgbColori(p[i]);



if (ycbcr.Y >= LowerThreshold.Y && ycbcr.Y <= UpperThreshold.Y

&& ycbcr.Cb >= LowerThreshold.Cb && ycbcr.Cb <= UpperThreshold.Cb

&& ycbcr.Cr >= LowerThreshold.Cr && ycbcr.Cr <= UpperThreshold.Cr)

{

rp[i] = 0xFFFFFF;



}

}

return result;



}

Розроблена підпрограма дозволяє виконувати додаткову перевірку виділених фрагментів на приналежність обличчю людини за кольором. Повністю програма наведена у додатках до магістерської роботи.



3.5 Розробка підпрограми просторового диференціювання
В основу розробки програми для пошуку обличчя людини використаємо сегментацію цифрових зображень із застосуванням методу кластерного аналізу. Цей метод реалізований у вигляді програми, яка приведена у додатках. Розроблена програма дозволяє виконати такі операції.

Для просторового диференціювання використовуємо оператори Собеля та Превітт. Для цього створюємо маску, яку будемо накладати на зображення та виконаємо диференціювання.

private void diffOperator()

{


float kernel[] = new float[9];

kernel[0] = 0;

kernel[1] = 1;

kernel[2] = 0;

kernel[3] = 1;

kernel[4] = -4;

kernel[5] = 1;

kernel[6] = 0;

kernel[7] = 1;

kernel[8] = 0;

int flag = 0;

CvMat kernel_matrix = CvMat.create(3, 3, CV_32FC1);

for (int i = 0; i < kerlel_row; i++)

{

for (int j = 0; j < kerlel_col; j++)



{

opencv_core.cvSet2D(kernel_matrix, i, j,

opencv_core.cvScalar(kernel[flag++], 0.0, 0.0, 0.0));

Маска для виконання операції виділення горизонтальних ліній буде описана таким чином.

IplImage difHeign()

{


IplImage f1 = cvCloneImage(work);

float kernel[] = new float[9];

kernel[0] = -1;

kernel[1] = -2;

kernel[2] = -1;

kernel[3] = 0;

kernel[4] = 0;

kernel[5] = 0;

kernel[6] = 1;

kernel[7] = 2;

kernel[8] = 1;

int flag = 0;

CvMat kernel_matrix = CvMat.create(3, 3, CV_32FC1);

for (int i = 0; i < kerlel_row; i++)

{

for (int j = 0; j < kerlel_col; j++)



{

opencv_core.cvSet2D(kernel_matrix, i, j,

opencv_core.cvScalar(kernel[flag++], 0.0, 0.0, 0.0));

Аналогічно описується маска для виділення вертикальних ліній.

IplImage difWidth()

{

IplImage f1 = cvCloneImage(work);



float kernel[] = new float[9];

kernel[0] = -1;

kernel[1] = 0;

kernel[2] = 1;

kernel[3] = -1;

kernel[4] = 0;

kernel[5] = 1;

kernel[6] = -1;

kernel[7] = 0;

kernel[8] = 1;

int flag = 0;

CvMat kernel_matrix = CvMat.create(3, 3, CV_32FC1);

for (int i = 0; i < kerlel_row; i++)

{

for (int j = 0; j < kerlel_col; j++)



{

opencv_core.cvSet2D(kernel_matrix, i, j,

opencv_core.cvScalar(kernel[flag++], 0.0, 0.0, 0.0));

Приведені маски дозволяють виконати просторове диференціювання зображення для виділення контурів об’єктів зображення.

Розроблена підпрограма дозволяє проводити просторове диференціювання цифрових зображень для пошуку обличчя людини. Повний лістинг підпрограми наведений у додатках до магістерської роботи.
3.6 Знаходження центру виділеної області
В отриманій виділеній області (знайдене обличчя) потрібно обчислити координати центру. Відповідно до отриманих даних відкривається можливість для розвитку програми - можливість реакції програми на зміну положення обличчя.

Так як обличчя може змінювати своє положення потрібно додати функцію прослуховувач події який при зміні положення обличчя повинен відобразити знаходження обличчя (описавши його прямокутником) та обчислити нову координату центру. Код програми наведений нижче.

document.addEventListener("facetrackingEvent", function (event)

{
overlayContext.clearRect(0, 0, 260, 180);


if (event.detection == "CS")

{
overlayContext.translate(event.x, event.y);


overlayContext.rotate(event.angle - (Math.PI / 2));
overlayContext.strokeStyle = "#CC0000";
overlayContext.strokeRect((-(event.width / 2)) >> 0, (-

(event.height / 2)) >> 0, event.width, event.height);


overlayContext.rotate((Math.PI / 2) - event.angle);
overlayContext.translate(-event.x, -event.y);

$scope.getCalibration = function ()

{
calibration = event.x;

}
playerObject.position.x = event.x - calibration;

}

}

Метод overlayContext.rotate повертає описаний прямокутник на кут event.angle. А змінна event.x зберігає в собі поточне місцезнаходження обличчя людини.



Для того, щоб ці дії вступили в силу, потрібно оновити сцену та зациклити. Зациклення викличе зависання браузеру, і щоб цього не трапилось, застосовують спеціальну рекурсію в паралельному потоці, яка й дозволяє робити анімації та інші дії з об’єктами не перевантажуючи роботу браузеру.

1   2   3   4   5   6   7   8   9



  • 3 РОЗРОБКА ПРОГРАМНИХ ЗАСОБІВ ВІДСТЕЖУВАННЯ ЗА ПЕРЕМІЩЕННЯМ ОБЛИЧЧЯ
  • 3.1 Обгрунтування вибору мови програмування
  • 3.2 Розробка програми відстеження за переміщенням обличчя людини
  • 3.3 Розробка підпрограми по сегментації зображення
  • 3.4 Розробка підпрограми колірної сегментації
  • 3 .5 Розробка підпрограми просторового диференціювання
  • 3.6 Знаходження центру виділеної області