Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
дипломчик.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
3.03 Mб
Скачать

Список литературы

1. Fisher R. CVOnline: Motion and time sequence Analysis [Электронный ресурс]. – 2002

2. Morris R. An Integrated Traffic and Pedestrian Vision System [Электронный ресурс]. – 1998

3. Вежневец В. Введение в Computer Vision [Электронный ресурс]. – 2003

4. Davies D., Palmer P., Mirmehdi M. Detection and Tracking of Very Small Low Contrast Objects [Электронный ресурс]. – 1994

5. Сойфер В.А. Компьютерная обработка изображений. Часть 2. Методы и алгоритмы. Соросовский образовательный журнал, №3, 1996, с. 110 – 121.

6. Р.Гонсалес, Р.Вудс, «Цифровая обработка изображений», ISBN 5-94836-028-8, изд-во: Техносфера, Москва, 2005. – 1072 с.

7. Козлов В. Н., Функциональный анализ, Санкт-Петербург: СПбГПУ, 2012, c. 461.

8. Тули М. Справочное пособие по цифровой электронике: Пер. с англ. — М.: Энергоатомиздат, 1990.

9. Sony BRC H900 Command List

10. Sony BRC H900 Operating Manual

11.Bechtel W. The Cardinal Mercier Lectures at the Catholic University of Louvain: An Exemplar Neural Mechanism: The Brain’s Visual Processing System. 2003

12. Программно-аппаратный комплекс AxxonNext [Электронный ресурс]. - Режим доступа: http: //www. axxonnext. com. 

13. Программно-аппаратный комплекс подсчета пассажиров DL-Bus [Электронный ресурс

14. G. Yang and Thomas S. Huang. «Human face detection in a complex background. Pattern Recognition», 27(1):53–63, 1994

15. C. Kotropoulos, I. Pitas. «Acoustics, Speech, and Signal Processing», 1997. ICASSP-97, 1997 IEEE International Conference on p.2537–2540 v. 4

16.  T. K. Leung, M. C. Burl, P. Perona. «Finding Faces in Cluttered Scenes Using Random Labeled Graph Matching»

17. K. C. Yow, R Cipolla, «Feature-based human face detection», Image and vision computing 15 (9),p. 713–735, 1997

18. Татаренков Д. А. Анализ методов обнаружения лиц на изображении // Молодой ученый. — 2015. — №4. — С. 270-276.

19. Lanitis, A.; Taylor, C.J.; Ahmed, T.; Cootes, T.F.; Wolfson «Image Anal. Classifying variable objects using a flexible shape model» Image Processing and its Applications, 1995., p.70–74

20. Горбунов В.М. Теория принятия решений. Учебное пособие, Томск, 2010, с.67

21. Прейко М., Устройства управления роботами: схемотехника и программирование – М.: Издательство ДМК, 2004, 202с.

Приложение 1. Код программы

Файл Mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <opencv2/core/core.hpp>

#include <opencv2/features2d/features2d.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/nonfree/nonfree.hpp>

#include <opencv2/objdetect/objdetect.hpp>

#include <QtSerialPort/QSerialPort>

#include <QtSerialPort/QSerialPortInfo>

#include "cv.h"

#include "highgui.h"

#include <stdio.h>

#include <ctype.h>

#include <QMainWindow>

#include <opencv\cv.h>

#include <iostream>

#include <stdlib.h>

#include <QDebug>

#include <algorithm>

#include <limits>

#include <time.h>

#include <math.h>

#include "myport.h"

#include <QThread>

#include "tracking.h"

#undef min

#undef max

namespace Ui {

class MainWindow;

}

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

explicit MainWindow(QWidget *parent = 0);

~MainWindow();

IplImage* first_img;

// int add_pt;

MyPort *port422;

// CvPoint2D32f *window_center;

IplImage *image;//для детектирования лица

CvRect target;//интересующая область

CvPoint pt;

CvPoint2D32f window_center;

CvPoint2D32f prev_mass_center;

CvPoint2D32f mass_center;

bool object_moving;

float sum;

// CvPoint2D32f mass_center_next;

// CvRect face_size;

bool detect_face(IplImage *gray, CvHaarClassifierCascade *haar_cascade, CvMemStorage *mem_storage, CvRect &face_rect);

QSerialPort *serial;

QByteArray command_read;

QByteArray command;

// unsigned char camera_id;

void init(const IplImage *gray, const CvRect &face_rect);

void deinit();

bool object_tracking (IplImage *gray, CvRect &face_rect);

signals:

void send_command (QByteArray command );

private slots:

void on_pushButton_up_clicked();

void on_pushButton_down_clicked();

void on_pushButton_left_clicked();

void on_pushButton_right_clicked();

void on_pushButton_clicked();

private:

Ui::MainWindow *ui;

IplImage *prev_img;

IplImage *current_img;

IplImage *previous_pyramid;

IplImage *current_pyramid;

int count_point;

CvPoint2D32f *current_points;

CvPoint2D32f *prev_points;

char *status;

CvTermCriteria tc;

int flags;

};

#endif // MAINWINDOW_H

Файл myport.h

#ifndef MYPORT_H

#define MYPORT_H

#include <QObject>

#include <QDebug>

#include <QtSerialPort/QserialPort>//Обьявляем работу с портом

#include <QMainWindow>

#include "math.h"

#include <unistd.h>

struct Settings {//Структура с настройками порта

QString name;

// // qint32 baudRate;

// QSerialPort::DataBits dataBits;

// QSerialPort::Parity parity;

// QSerialPort::StopBits stopBits;

// QSerialPort::FlowControl flowControl;

// QSerialPort::setSettingsRestoredOnClose setSettingsRestoredOnClose;

};

class MyPort : public QObject

{

Q_OBJECT

public:

explicit MyPort(QObject *parent = 0);

~MyPort();//хз

QSerialPort thisPort;

Settings SettingsPort;

//QByteArray command;

QByteArray command_read;

unsigned char camera_id = 0x83;

float s;

signals:

void finished_Port(); //Сигнал закрытия класса

void error_(QString err);//Сигнал ошибок порта

void outPort(QString data); //Сигнал вывода полученных данных

public slots:

void ClosePort(); // Слот отключения порта

void ConnectPort(void); // Слот подключения порта

void StopMoving();

void left();

void right ();

// void Write_Settings_Port();// Слот занесение настроек порта в класс

void process_Port(); //Тело

void choose_action (float prev, float next, float window_center);

void WriteToPort(QByteArray data); // Слот от правки данных в порт

private slots:

void handleError(QSerialPort::SerialPortError error);//Слот обработки ощибок

void ReadInPort(); //Слот чтения из порта по ReadyRead

};

#endif // MYPORT_H

Файл Main.cpp

#include "mainwindow.h"

#include <QApplication>

#include <QCoreApplication>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/highgui/highgui.hpp>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MainWindow w;

w.show();

return a.exec();

}

Файл Mainwindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include <QFileDialog>

#include <QDebug>

#include <QtDebug>

#include <QString>

#include <windows.h>

#include <iostream>

using namespace std;

using namespace cv;

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

/*для порта и передачи команд*/

//camera_id = 0x83;

//serial = new QSerialPort(this);

//serial->setPortName("COM1");

current_img = NULL;

prev_img = NULL;

current_pyramid = NULL;

previous_pyramid = NULL;

count_point = 0;

flags = 0;

current_points = NULL;

prev_points = NULL;

status = NULL;

object_moving=false;

sum =0;

QThread *my_thread = new QThread;//Создаем поток для порта платы

MyPort *port422 = new MyPort();//Создаем обьект по классу

port422->moveToThread(my_thread);//помешаем класс в поток

port422->thisPort.moveToThread(my_thread);//Помещаем сам порт в поток

// port422->

//Загружаем обученные данные для классификатора

CvHaarClassifierCascade *cascade_frontal_face = (CvHaarClassifierCascade *)cvLoad("D:/openCV/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml", 0, 0, 0);

//"D:/openCV/opencv/sources/data/haarcascades/haarcascade_mcs_upperbody.xml"

if (!cascade_frontal_face)

{

qDebug()<<"Error to load model"<<endl;

close();

}

CvMemStorage *MemStorage = cvCreateMemStorage(0);

tc = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03);

// connect(port422, SIGNAL(error_(QString)), this, SLOT(Print(QString)));//Лог ошибок

connect(my_thread, SIGNAL(started()),port422, SLOT(process_Port()));//Переназначения метода run

connect(port422, SIGNAL(finished_Port()), my_thread, SLOT(quit()));//Переназначение метода выход

connect(my_thread, SIGNAL(finished()),port422, SLOT(deleteLater()));//Удалить к чертям поток

connect(port422, SIGNAL(finished_Port()),my_thread, SLOT(deleteLater()));//Удалить к чертям поток

connect(this,SIGNAL(send_command(QByteArray)),port422,SLOT(WriteToPort(QByteArray)));//отправка в порт данных

//Захватываем видео (можно и с камеры) с лицами

port422->ConnectPort();

CvCapture* capture_web = cvCaptureFromCAM (0);

assert( capture_web );

if (capture_web == NULL)

{

qDebug()<<"Error to catch the camera!!!!"<<endl;

cvClearMemStorage(MemStorage);

cvRelease((void **)&cascade_frontal_face);

close();

}

cvNamedWindow("frame", 1);

// cvNamedWindow("points", 1);

IplImage *gray = NULL;

window_center = cvPoint2D32f(0.f, 0.f);

prev_mass_center = cvPoint2D32f(0.f, 0.f);

mass_center = cvPoint2D32f(0.f, 0.f);

// mass_center_next = cvPoint2D32f(0.f, 0.f);

//Прямоугольник найденного лица

CvRect face_rect = cvRect(0, 0, 0, 0);

//Control control_action;

enum detector_states //Состояния нашего детектора

{

find_object,

track_object

};

detector_states state = find_object;

IplImage *frame = cvQueryFrame(capture_web);

my_thread->start();

while(true)

{

frame = cvQueryFrame(capture_web);

if (frame == NULL)

{

qDebug()<<"Error"<<endl;

break;

}

//Вся работа ведётся на изображении в градациях серого

if (!gray)

{

gray= cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);

//CvPoint2D32f window_center = cvPoint2D32f(0.f, 0.f);

window_center.x = float(frame->width/2);

window_center.y = float(frame->height/2);

// qDebug()<<"Center x:"<<prev_mass_center.x<<endl;

// qDebug()<<"Center y:"<<prev_mass_center.y<<endl;

}

cvCvtColor(frame, gray, CV_RGB2GRAY);

//Наш примитивный автомат

switch (state)

{

case find_object: //Поиск лица

while (detect_face(gray, cascade_frontal_face, MemStorage, face_rect)==false)

{

// cvShowImage("frame", frame);

// cvShowImage("points", gray);

if (cvWaitKey(33) > 0)

break;

frame = cvQueryFrame(capture_web);

// gray= cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);

cvCvtColor(frame, gray, CV_RGB2GRAY);

}

init(gray, face_rect);

state = track_object;

break;

case track_object: //Сопровождение лица

if (!object_tracking(gray, face_rect))

{

unsigned char stop []= {0x83, 0x01, 0x06, 0x01, 0x00, 0x00, 0x03, 0x03, 0xFF};//8x 01 06 01 VV WW 03 03 FF

command.clear();

command.append((char*)stop, sizeof(stop));

send_command(command);

object_moving=false; //Лицо потеряно, деинициализируем данные сопровождения и меняем состояние

qDebug()<<"lost"<<endl;

prev_mass_center.x = NULL;

prev_mass_center.y = NULL;

deinit();

state = find_object;

}

else

{

if (prev_mass_center.x!=NULL)

{

float delta_x = mass_center.x - prev_mass_center.x;

float next = mass_center.x;

// qDebug()<<"next-prev"<<delta_x<<endl;

if (object_moving==false)//если камера неподвижна

{

sum = delta_x + sum;

if ((sum)>10)//объект движется влево

{

//if (window_center-next>0)//движется от края к центра

//break;//ничего не делаем

if ((window_center.x-next)<-30)//движется от центра к краю

{

unsigned char move_right[]= {0x83, 0x01, 0x06, 0x01, 0x03, 0x00, 0x02, 0x03, 0xFF};

command.clear();

command.append((char*)move_right, sizeof(move_right));

send_command(command);

//right();//камеру смещаем вправо

object_moving==true;

sum=0;

//qDebug()<<"next-prev"<<delta_x<<endl;

}

// qDebug()<<"next-prev"<<next-prev<<endl;

}

else if ((sum)<-10)//объект движется вправо

{

if ((window_center.x-next)>0)

{

unsigned char move_left []= {0x83, 0x01, 0x06, 0x01, 0x03, 0x00, 0x01, 0x03, 0xFF};

// 8x 01 06 01 VV WW 01 03 FF

// QByteArray command;

command.clear();

command.append((char*)move_left, sizeof(move_left));

send_command(command);

// left();//камеру смещаем влево

object_moving==true;

sum=0;

}

}

}

else if (fabs(window_center.x-next)<50)//если камера подвижна

{

unsigned char stop []= {0x83, 0x01, 0x06, 0x01, 0x00, 0x00, 0x03, 0x03, 0xFF};//8x 01 06 01 VV WW 03 03 FF

command.clear();

command.append((char*)stop, sizeof(stop));

send_command(command);

object_moving==false;

qDebug()<<"rastoyanie do centra"<<window_center.x-next<<endl;

}

}//moving (prev_mass_center.x, mass_center.x, window_center.x);

}

// }

break;

}

cvDrawRect(frame, cvPoint(face_rect.x, face_rect.y), cvPoint(face_rect.x + face_rect.width, face_rect.y + face_rect.height), cvScalar(255, 0, 0));

cvShowImage("frame", frame);

if (cvWaitKey(8) > 0)

break;

}

cvReleaseCapture(&capture_web);

cvDestroyWindow("frame");

cvDestroyWindow("points");

cvClearMemStorage(MemStorage);

cvRelease((void **)&cascade_frontal_face);

port422->ClosePort();

port422->finished_Port();

//serial->close();

// my_thread->exit();

}

MainWindow::~MainWindow()

{

delete ui;

}

bool MainWindow::detect_face(IplImage *gray, CvHaarClassifierCascade *cascade, CvMemStorage *MemStorage, CvRect &face_rect)

{

cvClearMemStorage(MemStorage);

CvSeq *faces = cvHaarDetectObjects(gray, cascade, MemStorage, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT|CV_HAAR_SCALE_IMAGE

, cvSize(50, 50));

// //Поиск лиц

if (!faces || !faces->total)

return false;

//Возвращаем первое найденное

face_rect = *(CvRect *)cvGetSeqElem(faces, 0);

return true;

// }

}

Файл myport.cpp

#include "myport.h"

MyPort::MyPort(QObject *parent) :

QObject(parent)

{

}

MyPort::~MyPort()

{

qDebug()<<"finish!!"<<endl;

emit finished_Port();//Сигнал о завершении работы

}

void MyPort :: process_Port(){//Выполняется при старте класса

qDebug()<<"Hello!"<<endl;

connect(&thisPort,SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleError(QSerialPort::SerialPortError))); // подключаем проверку ошибок порта

connect(&thisPort, SIGNAL(readyRead()),this,SLOT(ReadInPort()));//подключаем чтение с порта по сигналу readyRead()

}

void MyPort :: ConnectPort(void){//процедура подключения

thisPort.setPortName("COM6");

qDebug()<<"connecting.........."<<endl;

thisPort.setSettingsRestoredOnClose(false);

thisPort.open(QIODevice::ReadWrite);

thisPort.setBaudRate(QSerialPort::Baud9600);

thisPort.setDataBits(QSerialPort::Data8);//DataBits

thisPort.setParity(QSerialPort::NoParity);

thisPort.setStopBits(QSerialPort::OneStop);

thisPort.setFlowControl(QSerialPort::NoFlowControl);

//{

if (thisPort.isOpen()){

qDebug()<<"open"<<endl;

} else {

thisPort.close();

qDebug()<<"error to open port"<<endl;;

}

// object_moving=false;

// s =0;

// } else {

// thisPort.close();

// error_(thisPort.errorString().toLocal8Bit());

// }

}

void MyPort::handleError(QSerialPort::SerialPortError error)//проверка ошибок при работе

{

// if ( (thisPort.isOpen()) && (error == QSerialPort::ResourceError)) {

// error_(thisPort.errorString().toLocal8Bit());

// DisconnectPort();

// }

}//

void MyPort::ClosePort(){//Отключаем порт

unsigned char stop []= {camera_id, 0x01, 0x06, 0x01, 0x00, 0x00, 0x03, 0x03, 0xFF};//8x 01 06 01 VV WW 03 03 FF

QByteArray command;//command.clear();

command.append((char*)stop, sizeof(stop));

WriteToPort(command);

thisPort.waitForBytesWritten(200);

thisPort.close();

qDebug()<<"port closed!!!"<<endl;;

// if(thisPort.isOpen()){

// thisPort.close();

// error_(SettingsPort.name.toLocal8Bit() + " >> Закрыт!\r");

// }

}

void MyPort::StopMoving()

{

unsigned char stop []= {camera_id, 0x01, 0x06, 0x01, 0x00, 0x00, 0x03, 0x03, 0xFF};//8x 01 06 01 VV WW 03 03 FF

QByteArray command;//command.clear();

command.append((char*)stop, sizeof(stop));

WriteToPort(command);

}

void MyPort::ReadInPort()

{

command_read.append(thisPort.readAll());

QByteArray y = command_read.toHex();

command_read.clear();

qDebug()<<"answer"<<y<<endl;

}

void MyPort::left()

{

unsigned char move_left []= {camera_id, 0x01, 0x06, 0x01, 0x03, 0x00, 0x01, 0x03, 0xFF};

// 8x 01 06 01 VV WW 01 03 FF

QByteArray command;

command.append((char*)move_left, sizeof(move_left));

WriteToPort(command);

}

void MyPort:: right()

{

unsigned char move_right[]= {camera_id, 0x01, 0x06, 0x01, 0x03, 0x00, 0x02, 0x03, 0xFF};

//command.clear();

QByteArray command;

command.append((char*)move_right, sizeof(move_right));

WriteToPort(command);

}

void MyPort :: WriteToPort(QByteArray data){//Запись данных в порт

// if(thisPort.isOpen()){

// sleep(7) ;

thisPort.write(data);

qDebug()<<"command is written"<<endl;

thisPort.waitForBytesWritten( 200);

//}

}

Файл tracking.cpp

#include "mainwindow.h"

//слежение за лицом

bool MainWindow::object_tracking (IplImage *gray, CvRect &face_rect)

{

cvCopyImage(gray, current_img);

//Вычисление нового положения точек с помощью пирамидального алгоритма анализа оптического потока Лукаса-Канаде

cvCalcOpticalFlowPyrLK(prev_img, current_img, previous_pyramid, current_pyramid,

prev_points, current_points, count_point, cvSize(20, 20), 3, status, 0, tc, flags);

flags |= CV_LKFLOW_PYR_A_READY;

if (count_point<30)

return false;

//Удаление не найденных точек, а также вычисление координат описывающего прямоугольника

float left = std::numeric_limits<float>::max();

float top = std::numeric_limits<float>::max();

float right = std::numeric_limits<float>::min();

float bottom = std::numeric_limits<float>::min();

//Центр масс

// CvPoint2D32f mass_center = cvPoint2D32f(0.f, 0.f);

// CvPoint2D32f prev_mass_center = cvPoint2D32f(0.f, 0.f);

prev_mass_center = mass_center;

int k = 0;

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

{

if (status[i])

{

current_points[k] = current_points[i];

if (current_points[k].x < left)

left = current_points[k].x;

if (current_points[k].x > right)

right = current_points[k].x;

if (current_points[k].y < top)

top = current_points[k].y;

if (current_points[k].y > bottom)

bottom = current_points[k].y;

mass_center.x += current_points[k].x;

mass_center.y += current_points[k].y;

++k;

}

}

count_point = k;

// MainWindow wind;

mass_center.x /= (float)count_point;

mass_center.y /= (float)count_point;

//mass_center_next = mass_center;

//Вычисление расстояния от центра масс, до ближайших сторон описывающего прямоугольника

float min_x = std::min(mass_center.x - left, right - mass_center.x);

float min_y = std::min(mass_center.y - top, bottom - mass_center.y);

//Границы описывающего прямоугольника пересчитываются с учётом полученных минимальных значений + небольшой отступ на всякий случай

left = mass_center.x - min_x - min_x / 4.f;

right = mass_center.x + min_x + min_x / 4.f;

top = mass_center.y - min_y - min_y / 4.f;

bottom = mass_center.y + min_y + min_y / 4.f;

//Удаление точек, которые не попали в новый прямоугольник

k = 0;

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

{

if (current_points[i].x > left &&

current_points[i].x < right &&

current_points[i].y > top &&

current_points[i].y < bottom)

{

current_points[k] = current_points[i];

//Вывод точек

cvDrawCircle(gray, cvPoint((int)current_points[k].x, (int)current_points[k].y), 1, cvScalar(255, 0, 255));

++k;

}

}

count_point = k;

// printf("points_count = %i\n", count_point);//записываем сколько точек нашлось

face_rect.x = (int)left;

face_rect.y = (int)top;

face_rect.width = (int)(right - left);

face_rect.height = (int)(bottom - top);

//Смена указателей на параметры

std::swap(prev_img, current_img);

std::swap(previous_pyramid, current_pyramid);

std::swap(prev_points, current_points);

cvShowImage("points", gray);

return true;

}

Санкт-Петербург

2016