ТОП 10:

Детальний опис реалізації основних процедур та функцій додатку з прикладами.



class Contours implements Runnable {

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

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

CanvasFrame frame;

CanvasFrame frame2;

Змінна stoped необхідна для синхронного завершення потоку.

static boolean stoped;

public void run() {

В методі run() реалізоване тіло програми. Для початку створюються екземпляри об’єктів CanvasFram, і встановлюється дія при натисканні кнопки в правому верхньому куті вікна.

frame = new CanvasFrame("Main Frame");

frame2 = new CanvasFrame("Gray Frame");

stoped = false;

frame.setDefaultCloseOperation(CanvasFrame.EXIT_ON_CLOSE);

frame2.setDefaultCloseOperation(CanvasFrame.EXIT_ON_CLOSE);

 

try {

Створюється обєкт OpenCVFrameGrabber, за вдяки якому можна отримати зображення з відеокамери або відео файлу. В якості параметра передається номер пристрою тобто відеокамери. Якщо на комп’ютері декілька камер, то можна вибирати будь яку з них перша камера має нульовий номер, друга одиницю, і так далі. Якщо потрібно отримати відео з файлу, то вказується в якості параметра шлях до файлу. Так як можуть виникнути проблеми з відеокамерою, або з відео файлом, цей блок коду поміщається у в оператор try {}

OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);

grabber.start(); //запуск грабера

while (!stoped) {

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

IplImage Grab = grabber.grab();

if (Grab == null)

return;

Якщо зображення коректно було отримано з пристрою або з файлу, воно передається функції Detect(Grab) в якості параметру, для подальшої обробки, а після обробки буде повернуто в якості результату функції.

Grab = Detect(Grab);

Метод showImage(Grab) прорисовує зображення на фрейм.

frame.showImage(Grab);

}

} catch (Exception e) {

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

e.printStackTrace();

} finally {

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

frame.dispose();

frame2.dispose();

}

}

Метод stop() використовується для синхронного завершення роботи.

public void stop() {

stoped = true;

}

 

public IplImage Detect(IplImage Grab) {

В цій функції реалізовано саме серце методу виявлення об’єктів за їх контурами.

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

CvMemStorage storage = CvMemStorage.create(0);

Створюється екземпляр об’єкту CvSeq який описує послідовність точок контуру.

CvSeq contour = new CvSeq(null);

Створюється екземпляр об’єкту, завдяки якому можна отримати моменти контуру, для подальшої їх обробки.

CvMoments moments = new CvMoments();

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

CvHuMoments hu_moments = new CvHuMoments();

CvHuMoments hu_templ = new CvHuMoments();

 

try {

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

Scanner fileScan = new Scanner(new BufferedReader(new FileReader(

"C:\\moments.txt")));

if (fileScan.hasNext())

hu_templ.hu1(fileScan.nextDouble());

if (fileScan.hasNext())

hu_templ.hu2(fileScan.nextDouble());

if (fileScan.hasNext())

hu_templ.hu3(fileScan.nextDouble());

if (fileScan.hasNext())

hu_templ.hu4(fileScan.nextDouble());

if (fileScan.hasNext())

hu_templ.hu5(fileScan.nextDouble());

if (fileScan.hasNext())

hu_templ.hu6(fileScan.nextDouble());

if (fileScan.hasNext())

hu_templ.hu7(fileScan.nextDouble());

} catch (Exception e) {

}

//створюється екземпляр IplImage у якому буде зберігатися зображення у відтінках сірого. Одразу передаються розміри зображення, вказується що воно 8-ми бітне, а кількість каналів дорівнює 1.

IplImage gray = IplImage.create(Grab.width(), Grab.height(),

IPL_DEPTH_8U, 1);

 

if (Grab == null) {

System.err.println("Невозможно загрузить изображение.");

} else {

Функція cvCvtColor конвертує вхідне зображення в відтінки сірого. Вказується в якості параметрів вхідне зображення, вихідне, та метод конвертації у даному випадку з RGB в відтінки сірого.

cvCvtColor(Grab, gray, CV_BGR2GRAY);

Функція cvSmooth виконує розмиття зображення, в даному випадку розмиття по Гаусу. В якості параметрів отримує вхідне зображення, вихідне зображення тут воно теж саме, і ступінь розмиття, наступні три параметри в даному випадку не використовуються.

cvSmooth(gray, gray, CV_GAUSSIAN, 9, 0, 0, 0);

Наступними діями є підкреслення границь за допомогою оператора Кенні. Для цього виконується функція cvCanny, в якості параметрів якій передаються: вхідне зображення, вихідне тобто теж саме, значення нижнього та верхнього порогу.

cvCanny(gray, gray, 56, 100, 3);

Підкреслені контури виводяться на екран у фрейм за допомогою методу showImage()

frame.showImage(gray);

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

cvFindContours(gray, storage, contour,

Loader.sizeof(CvContour.class), CV_RETR_TREE,

CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));

 

int NC = 0;

//Перебираються всі контури

while (contour != null && !contour.isNull()) {

if (contour.elem_size() > 0) {

 

//апроксимуються

CvSeq points = cvApproxPoly(contour,

Loader.sizeof(CvContour.class), storage,

CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.002, 0);

 

//обчислюються моменти для кожного контуру

cvMoments(contour, moments, 1);

//обчислюються Hu моменти для кожного контуру

cvGetHuMoments(moments, hu_moments);

 

//порівнюються Hu моменти поточного контуру з шаблоним, і якщо ступінь схожості менше 150 виконати наступне

if (MatchShapes(hu_templ, hu_moments) < 150) {

 

//промалювати контур на вихідному зображенні

cvDrawContours(Grab, contour, CvScalar.RED,

CvScalar.RED, -1, 4, CV_AA);

//промалювати рамку навколо контуру

CvRect r = cvBoundingRect(contour, 1); int x = r.x(),

y = r.y(), w = r.width(), h = r.height();

cvRectangle(Grab, cvPoint(x, y), cvPoint(x + w, y +

h), CvScalar.MAGENTA, 4, CV_AA, 0);

 

 

}

 

System.out.print("NC = " + NC + "\n");

System.out.print("hu1 = " + hu_moments.hu1() + "\n");

System.out.print("hu2 = " + hu_moments.hu2() + "\n");

System.out.print("hu3 = " + hu_moments.hu3() + "\n");

System.out.print("hu4 = " + hu_moments.hu4() + "\n");

System.out.print("hu5 = " + hu_moments.hu5() + "\n");

System.out.print("hu6 = " + hu_moments.hu6() + "\n");

System.out.print("hu7 = " + hu_moments.hu7() + "\n");

 

NC++;

}

contour = contour.h_next();

}

//виводиться на екран вихідне зображення

frame2.showImage(gray);

}

 

return Grab;

}

 

//функції MatchShapes, порівнює Hu моменти двох контурів

private double MatchShapes(CvHuMoments hu_m_templ, CvHuMoments hu_m) {

double mt = 0;

double[] ma = new double[7];

double[] mb = new double[7];

 

ma[0] = hu_m_templ.hu1();

ma[1] = hu_m_templ.hu2();

ma[2] = hu_m_templ.hu3();

ma[3] = hu_m_templ.hu4();

ma[4] = hu_m_templ.hu5();

ma[5] = hu_m_templ.hu6();

ma[6] = hu_m_templ.hu7();

 

mb[0] = hu_m.hu1();

mb[1] = hu_m.hu2();

mb[2] = hu_m.hu3();

mb[3] = hu_m.hu4();

mb[4] = hu_m.hu5();

mb[5] = hu_m.hu6();

mb[6] = hu_m.hu7();

 

for (int i = 0; i < 7; i++) {

mt += Math

.abs((Math.signum(ma[i]) * Math.log(Math.abs(ma[i])) - Math

.signum(mb[i]) * Math.log(Math.abs(mb[i])))

/ Math.signum(ma[i]) * Math.log(Math.abs(ma[i])));

}

 

System.out.print("\nMatchResult = " + mt + "\n");

 

return mt;

}

 

}

 

class Haar implements Runnable {

//розмір відступу

private static final int SCALE = 2;

 

 

//шлях до файлу каскаду

private static final String CASCADE_FILE = "C:\\out_ok_25.02.2012.xml";

 

static boolean stoped;

 

public void run() {

stoped = false;

System.out.println("Starting OpenCV...");

 

Loader.load(opencv_objdetect.class);

 

CanvasFrame frame = new CanvasFrame("Main Frame");

frame.setDefaultCloseOperation(CanvasFrame.EXIT_ON_CLOSE);

 

try {

OpenCVFrameGrabber grabber = new OpenCVFrameGrabber("C:\\ggg.avi");

grabber.start();

while (!stoped) {

IplImage origImg = grabber.grab();

if (origImg == null)

return;

 

// конвертування в відтінки сірого

IplImage grayImg = IplImage.create(origImg.width(),

origImg.height(), IPL_DEPTH_8U, 1);

cvCvtColor(origImg, grayImg, CV_BGR2GRAY);

 

// створення зменшеної копії для підвищення швидкості виявлення IplImage smallImg = IplImage.create(grayImg.width() / SCALE,

grayImg.height() / SCALE, IPL_DEPTH_8U, 1);

cvResize(grayImg, smallImg, CV_INTER_LINEAR);

 

// еквалізація гістограми зменшеного зображення

IplImage equImg = IplImage.create(smallImg.width(),

smallImg.height(), IPL_DEPTH_8U, 1);

cvEqualizeHist(smallImg, equImg);

 

// створення тимчасового місця, що використовуються під час виявлення об'єкта

CvMemStorage storage = CvMemStorage.create();

 

//створення екземпляру каскадного класифікатору для розпізнавання об’єктів

CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(

cvLoad(CASCADE_FILE));

System.out.println("Detecting faces...");

CvSeq faces = cvHaarDetectObjects(equImg, cascade, storage,

1.1, 3, CV_HAAR_DO_CANNY_PRUNING);

cvClearMemStorage(storage);

 

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

int total = faces.total();

System.out.println("Found " + total + " obj");

for (int i = 0; i < total; i++) {

CvRect r = new CvRect(cvGetSeqElem(faces, i));

cvRectangle(

origImg,

// задається відступ

cvPoint(r.x() * SCALE, r.y() * SCALE),

cvPoint((r.x() + r.width()) * SCALE,

(r.y() + r.height()) * SCALE),

CvScalar.YELLOW, 6, CV_AA, 0);

}

//виведення зображення на екран

frame.showImage(origImg);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

frame.dispose();

}

 

}

 

public void stop() {

stoped = true;

}

}


 







Последнее изменение этой страницы: 2017-02-05; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.215.182.81 (0.024 с.)