Перейти к содержимому
Compvision.ru
Cfr

Трекинг объектов.

Recommended Posts

А вариант использования 2х или 3х камер с известной геометрией их расположения?

Это совсем другая задача. Я ей никогда не занимался (хотя хочется - нет времени).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Там есть папка release, запускай через bat-файл, в котором прописаны параметры используемых алгоритмов.

Батником файл запускается только после преобразования С++ (у меня 2008). А вот из под С++ не хочет.

И какой именно "hgfhgfhgf" открывать. в папке "hgfhgfhgf" или "blob_track".

И еще с какого то раза, когда я запустил батник, появились кружочки, а потом их не стало и больше не выходит...

Вобщем совсем запутался и где настройки менять тоже не нашел(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что означает "после преобразования С++" я даже предположить не могу.

"hgfhgfhgf" - это я по привычке дал имя случайным образом.

В папке release есть bat файл. Его можно редактировать в блокноте. Открой его, посмотри какие параметры там указаны. Их и меняй. Если запустить сам exe без bat файла из командной строки, то он выведет доступные опции и параметры.

Как оно работает:

1. Неподвижная камера смотрит куда-нибудь, сцена без движения.

2. Начинается движение, небольшое, объект меньше четверти размера кадра.

3. Он должен выделиться кружком.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В папке release есть bat файл. Его можно редактировать в блокноте. Открой его, посмотри какие параметры там указаны. Их и меняй. Если запустить сам exe без bat файла из командной строки, то он выведет доступные опции и параметры.

Когда bat файл открываю там только:

blobtrack.exe fg=FG_0S bd=BD_Simple bt=MSFG btpp=None bta=HistPVS f:\Alles\video_bmp\cl_winter4.avi

pause

И чтобы что то поменять в рограмме мне надо "hgfhgfhgf" открывать из папки blob_track или hgfhgfhgf?

И кстате какой бы я не открывал он не показывает исходников.

Надо просто в Source файле писать? Обязательно весь проект загружать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если честно, меня очень удивляют твои затруднения. Элементарные знания языка и среды разработки должны быть - как же ты собираешься разбираться в гораздо более сложных алгоритмах?

Visual Studio надо открывать hgfhgfhgf.sln. В Solution Explorer будет отображаться дерево проекта с исходниками.

Ммм, ты знаешь что такое bat файлы, "командная строка", параметры функции main? Надо тебе разобраться с этими понятиями.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я иду к этому потихоньку.

Просто мы недавно начали изучать информатику, а это я сам... по своему желанию, экспериментирую.

bat файлы, "командная строка", параметры функции main я знаю, но не досканально

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Улучшил алгоритм, решил проблему падения памяти.

При потере объекта программа зависала и вылетала критическая ошибка.

Не смог реализовать удаление точек, если они сильно отдалились от объекта.

И хочу еще попробовать заполнять массив cvGoodFeaturesToTrack

#include "tracking.h"

IplImage *curr_img;
IplImage *prev_img;
IplImage *curr_pyramid_img;
IplImage *prev_pyramid_img;
int points_count;
CvPoint2D32f *curr_points;
CvPoint2D32f *prev_points;
int flags;
char *status;
CvRect face_rect;

void FinalizeTracking()
{
if (curr_img) cvReleaseImage(&curr_img);
if (prev_img) cvReleaseImage(&prev_img);
if (curr_pyramid_img) cvReleaseImage(&curr_pyramid_img);
if (prev_pyramid_img) cvReleaseImage(&prev_pyramid_img);

points_count = 0;
flags = 0;

if (curr_points) {//free((void *)curr_points);
delete []curr_points;
curr_points = NULL;
}
if (prev_points) {//free((void *)prev_points);
delete []prev_points;
prev_points = NULL;
}
if (status) {//free((void *)status);
delete []status;
status = NULL;
}

// cvDestroyWindow("points");
}

void InitTracking(const IplImage *gray_img, const CvRect face_rect)
{
flags = 0;

curr_img = cvCreateImage(cvSize(gray_img->width, gray_img->height), IPL_DEPTH_8U, 1);
prev_img = cvCreateImage(cvSize(gray_img->width, gray_img->height), IPL_DEPTH_8U, 1);
curr_pyramid_img = cvCreateImage(cvSize(gray_img->width + 8, gray_img->height / 3), IPL_DEPTH_8U, 1);
prev_pyramid_img = cvCreateImage(cvSize(gray_img->width + 8, gray_img->height / 3), IPL_DEPTH_8U, 1);

const int step_x = face_rect.width / 16;
const int step_y = face_rect.height / 16;
points_count = (face_rect.width / step_x) * (face_rect.height / step_y);

curr_points = //(CvPoint2D32f *)malloc(sizeof(CvPoint2D32f) * points_count);
new CvPoint2D32f[points_count * 2];
prev_points = //(CvPoint2D32f *)malloc(sizeof(CvPoint2D32f) * points_count);
new CvPoint2D32f[points_count * 2];
status = //(char *)malloc(sizeof(char) * points_count);
new char[points_count * 2];

size_t pc = 0;
for (int i = face_rect.y, stop_i = face_rect.y + face_rect.height; i < stop_i; i += step_y) {
for (int j = face_rect.x, stop_j = face_rect.x + face_rect.width; j < stop_j; j += step_x) {
curr_points[pc] = cvPoint2D32f((double)j, (double)i);
++pc;
}
}

cvCopyImage(gray_img, curr_img);
cvFindCornerSubPix(curr_img, curr_points, points_count, cvSize(3, 3), cvSize(-1, -1), tc);

std::swap(prev_img, curr_img);
std::swap(prev_pyramid_img, curr_pyramid_img);
// std::swap(prev_img->imageData, curr_img->imageData);
// std::swap(prev_pyramid_img->imageData, curr_pyramid_img->imageData);
std::swap(prev_points, curr_points);

// cvNamedWindow("points");
}

CvRect TrackingFace(IplImage *gray_img, CvRect face_rect)
{
cvCopyImage(gray_img, curr_img);

cvCalcOpticalFlowPyrLK(prev_img, curr_img, prev_pyramid_img, curr_pyramid_img,
prev_points, curr_points, points_count, cvSize(20, 20), 3, status, 0, tc, flags);
flags |= CV_LKFLOW_PYR_A_READY;

if (!points_count) {
//if (curr_points) {//free((void *)curr_points);
// delete []curr_points;
// curr_points = NULL;
//}
//if (prev_points) {//free((void *)prev_points);
// delete []prev_points;
// prev_points = NULL;
//}
//if (status) {//free((void *)status);
// delete []status;
// status = NULL;
//}
return cvRect (0, 0, 0, 0);
}

double left = std::numeric_limits<double>::max();
double top = std::numeric_limits<double>::max();
double right = std::numeric_limits<double>::min();
double bottom = std::numeric_limits<double>::min();

int k = 0;
for (int i = 0; i < points_count; ++i) {
if (status[i]) {
curr_points[k] = curr_points[i];

cvDrawCircle(gray_img, cvPoint((int)curr_points[k].x, (int)curr_points[k].y), 1, cvScalar(255, 255, 255));

if (curr_points[k].x < left) left = curr_points[k].x;
if (curr_points[k].x > right) right = curr_points[k].x;
if (curr_points[k].y < top) top = curr_points[k].y;
if (curr_points[k].y > bottom) bottom = curr_points[k].y;

++k;
}
}
points_count = k;

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, curr_img);
std::swap(prev_pyramid_img, curr_pyramid_img);
// std::swap(prev_img->imageData, curr_img->imageData);
// std::swap(prev_pyramid_img->imageData, curr_pyramid_img->imageData);
std::swap(prev_points, curr_points);

if (showTracking) cvShowImage("Tracking", gray_img);

return face_rect;
}

void ShowTracking()
{
if (showTracking) cvNamedWindow("Tracking");
else cvDestroyWindow("Tracking");
}
[/codebox]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

С глюками согласен - исправил.

Вот, добавил простенький алгоритм отсева отделившихся точек:

1. вычисляем центр масс распределения точек;

2. по нему корректируем размеры описывающего прямоугольника;

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

У меня вроде как работает нормально.

#include <algorithm>
#include <limits>

#include <highgui.h>
#include <cv.h>

#undef min
#undef max

////////////////////////////////////////////////////////////////////////////
//Поиск лица на кадре
bool detect_face(IplImage *gray_img, CvHaarClassifierCascade *haar_cascade, CvMemStorage *mem_storage, CvRect &face_rect)
{
cvClearMemStorage(mem_storage);

//Поиск лиц
CvSeq *faces = cvHaarDetectObjects(gray_img, haar_cascade, mem_storage, 1.1, 2, 0, cvSize(20, 20));
if (!faces || !faces->total)
return false;

//Возвращаем первое найденное
face_rect = *(CvRect *)cvGetSeqElem(faces, 0);
return true;
}
////////////////////////////////////////////////////////////////////////////
class LKData
{
private:
//Всякие данные
IplImage *curr_img;
IplImage *prev_img;
IplImage *curr_pyramid_img;
IplImage *prev_pyramid_img;

int points_count;
CvPoint2D32f *curr_points;
CvPoint2D32f *prev_points;
char *status;

CvTermCriteria tc;
int flags;

public:
LKData()
: curr_img(NULL), prev_img(NULL), curr_pyramid_img(NULL), prev_pyramid_img(NULL),
points_count(0), flags(0), curr_points(NULL), prev_points(NULL), status(NULL)
{
tc = cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03);
cvNamedWindow("points", 1);
}
////////////////////////////////////////////////////////////////////////////
~LKData()
{
deinit();
cvDestroyWindow("points");
}
////////////////////////////////////////////////////////////////////////////
//Инициализация данных для сопровождения
void init(const IplImage *gray_img, const CvRect &face_rect)
{
deinit();

curr_img = cvCreateImage(cvSize(gray_img->width, gray_img->height), IPL_DEPTH_8U, 1);
prev_img = cvCreateImage(cvSize(gray_img->width, gray_img->height), IPL_DEPTH_8U, 1);
curr_pyramid_img = cvCreateImage(cvSize(gray_img->width, gray_img->height), IPL_DEPTH_8U, 1);
prev_pyramid_img = cvCreateImage(cvSize(gray_img->width, gray_img->height), IPL_DEPTH_8U, 1);

//Покроем прямоугольник лица равномерной сеткой из точек
const int step_x = face_rect.width / 16;
const int step_y = face_rect.height / 16;
points_count = (face_rect.width / step_x + 1) * (face_rect.height / step_y + 1);
curr_points = new CvPoint2D32f[points_count];
prev_points = new CvPoint2D32f[points_count];
status = new char[points_count];

size_t pc = 0;
for (int i = face_rect.y, stop_i = face_rect.y + face_rect.height; i < stop_i; i += step_y)
{
for (int j = face_rect.x, stop_j = face_rect.x + face_rect.width; j < stop_j; j += step_x)
{
curr_points[pc] = cvPoint2D32f((float)j, (float)i);
++pc;
}
}
points_count = (int)pc;

cvCopyImage(gray_img, curr_img);
cvFindCornerSubPix(curr_img, curr_points, points_count, cvSize(3, 3), cvSize(-1, -1), tc);

//Смена указателей на параметры
std::swap(prev_img, curr_img);
std::swap(prev_pyramid_img, curr_pyramid_img);
std::swap(prev_points, curr_points);
}
////////////////////////////////////////////////////////////////////////////
//Деинициализация данных для сопровождения
void deinit()
{
if (curr_img)
{
cvReleaseImage(&curr_img);
curr_img = NULL;
}
if (prev_img)
{
cvReleaseImage(&prev_img);
prev_img = NULL;
}
if (curr_pyramid_img)
{
cvReleaseImage(&curr_pyramid_img);
curr_pyramid_img = NULL;
}
if (prev_pyramid_img)
{
cvReleaseImage(&prev_pyramid_img);
prev_pyramid_img = NULL;
}

points_count = 0;
flags = 0;

if (curr_points)
{
delete []curr_points;
curr_points = NULL;
}
if (prev_points)
{
delete []prev_points;
prev_points = NULL;
}
if (status)
{
delete []status;
status = NULL;
}
}
////////////////////////////////////////////////////////////////////////////
//Сопровождение лица
bool tracking_face(IplImage *gray_img, CvRect &face_rect)
{
cvCopyImage(gray_img, curr_img);

//Вычисление нового положения точек с помощью пирамидального алгоритма анализа оптического потока Лукаса-Канаде
cvCalcOpticalFlowPyrLK(prev_img, curr_img, prev_pyramid_img, curr_pyramid_img,
prev_points, curr_points, points_count, cvSize(20, 20), 3, status, 0, tc, flags);
flags |= CV_LKFLOW_PYR_A_READY;

if (!points_count)
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 mc = cvPoint2D32f(0.f, 0.f);

int k = 0;
for (int i = 0; i < points_count; ++i)
{
if (status[i])
{
curr_points[k] = curr_points[i];

if (curr_points[k].x < left)
left = curr_points[k].x;
if (curr_points[k].x > right)
right = curr_points[k].x;

if (curr_points[k].y < top)
top = curr_points[k].y;
if (curr_points[k].y > bottom)
bottom = curr_points[k].y;

mc.x += curr_points[k].x;
mc.y += curr_points[k].y;

++k;
}
}
points_count = k;

mc.x /= (float)points_count;
mc.y /= (float)points_count;

//Вычисление расстояния от центра масс, до ближайших сторон описывающего прямоугольника
float min_x = std::min(mc.x - left, right - mc.x);
float min_y = std::min(mc.y - top, bottom - mc.y);

//Границы описывающего прямоугольника пересчитываются с учётом полученных минимальных значений + небольшой отступ на всякий случай
left = mc.x - min_x - min_x / 4.f;
right = mc.x + min_x + min_x / 4.f;
top = mc.y - min_y - min_y / 4.f;
bottom = mc.y + min_y + min_y / 4.f;

//Удаление точек, которые не попали в новый прямоугольник
k = 0;
for (int i = 0; i < points_count; ++i)
{
if (curr_points[i].x > left &&
curr_points[i].x < right &&
curr_points[i].y > top &&
curr_points[i].y < bottom)
{
curr_points[k] = curr_points[i];

//Вывод точек
cvDrawCircle(gray_img, cvPoint((int)curr_points[k].x, (int)curr_points[k].y), 1, cvScalar(255, 0, 255));
++k;
}
}
points_count = k;

printf("points_count = %i\n", points_count);

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, curr_img);
std::swap(prev_pyramid_img, curr_pyramid_img);
std::swap(prev_points, curr_points);

cvShowImage("points", gray_img);

return true;
}
};
////////////////////////////////////////////////////////////////////////////
int main()
{
//Загружаем обученные данные для классификатора
CvHaarClassifierCascade *haar_cascade = (CvHaarClassifierCascade *)cvLoad("c:\\Program Files\\OpenCV_1_1\\data\\haarcascades\\haarcascade_frontalface_alt2.xml", 0, 0, 0);
if (!haar_cascade)
return 1;
CvMemStorage *mem_storage = cvCreateMemStorage(0);

//Захватываем видео (можно и с камеры) с лицами
#if 0
CvCapture *video = cvCaptureFromFile("e:\\video_bmp\\cam_face.avi");
#else
CvCapture *video = cvCaptureFromCAM(0);
#endif
if (!video)
{
cvClearMemStorage(mem_storage);
cvRelease((void **)&haar_cascade);
return 2;
}

cvNamedWindow("frame", 1);
IplImage *gray_img = NULL;

//Прямоугольник найденного лица
CvRect face_rect = cvRect(0, 0, 0, 0);

LKData lk_data;

enum detector_states //Состояния нашего детектора
{
find_face,
track_face
};
detector_states state = find_face;

for (IplImage *frame = cvQueryFrame(video); frame; frame = cvQueryFrame(video))
{
//Вся работа ведётся на изображении в градациях серого
if (!gray_img)
gray_img = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 1);
cvCvtColor(frame, gray_img, CV_RGB2GRAY);

//Наш примитивный автомат
switch (state)
{
case find_face: //Поиск лица
if (detect_face(gray_img, haar_cascade, mem_storage, face_rect))
{
//Лицо найдено, инициализируем данные для сопровождения и меняем состояние
lk_data.init(gray_img, face_rect);
state = track_face;
}
break;

case track_face: //Сопровождение лица
if (!lk_data.tracking_face(gray_img, face_rect))
{
//Лицо потеряно, деинициализируем данные сопровождения и меняем состояние
lk_data.deinit();
state = find_face;
}
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(10) > 0)
break;
}

cvReleaseCapture(&video);
cvDestroyWindow("frame");
cvClearMemStorage(mem_storage);
cvRelease((void **)&haar_cascade);

return 0;
}
////////////////////////////////////////////////////////////////////////////[/codebox]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нашел отличную реализацию, трекинга объектов :) спешу с вами поделиться. Смотрите вложение.

Есть основные 4 функции cvLabel, cvFilterByArea, cvUpdateTracks, cvRenderTracks;

В cvLabel передается сегментированное изображение, функция назначает белым пятнам(blob), каждому свой номер. (как сегментировать решаем сами, в примере осуществляется поиск красного квадрата)

cvFilterByArea удаляет blob-ы которые не подходят по площади.

cvUpdateTracks собственно сам трекинг.

cvRenderTracks отображение blob-ов.

Проект расположен тут: http://code.google.com/p/cvblob/

BlobTrack.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да и в самом opencv есть blob_tracking_modules, вроде неплохо работает

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Да и в самом opencv есть blob_tracking_modules, вроде неплохо работает

В самом деле так считате? Хм... как по мне так это один большой тормоз, кадры по секунде обрабатывает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну не знаю, я буквально намедни занялся вопросом слежения за движением в кадре. А что именно тормозит - трекинг, сегментация фона? Я попробовал только пару простых примеров

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я в детали не вдавался, но стандартный пример blob_tracking работает, мягко говоря, не очень быстро. Особенно ужасными тормоза становятся при выставлении опции сопровождения CCMSPF.

Приведённый RinOS пример, на первый взгляд, довольно неплох. Однако для него необходимо провести предварительную бинаризацию, что не всегда возможно. Например, при сопровождением лиц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Никто не пробовал переписать это на CUDA?

У меня какие-то проблемы с CUDA, пытаюсь запустить базовый проект из этой темы http://www.compvision.ru/forum/index.php?showtopic=95

не выходит, пишет:

1>------ Build started: Project: CUDAWinApp2, Configuration: Release Win32 ------
1>Compiling...
1>""\nvcc.exe"" не является внутренней или внешней
1>командой, исполняемой программой или пакетным файлом.
1>Project : error PRJ0019: A tool returned an error code from "Compiling..."
1>Project : warning PRJ0018 : The following environment variables were not found:
1>$(CUDA_BIN_PATH)
1>$(NVSDKCUDA_ROOT)
1>$(CUDA_INC_PATH)
1>Build log was saved at "file://c:\Users\aigork\Desktop\CUDAWinApp2\CUDAWinApp2\Release\BuildLog.htm"
1>CUDAWinApp2 - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========[/codebox]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

CUDA SDK и toolkit поставил? nvcc.exe - это как раз компилятор в ассемблер видеокарты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
CUDA SDK и toolkit поставил? nvcc.exe - это как раз компилятор в ассемблер видеокарты.

На сайте NVidia есть ссылка на пример реализации SURF на CUDA + OpenCV 2.0, можно его покопать еще для общего развития :( :

http://www.mis.tu-darmstadt.de/surf

И еще, в SVN версии OpenCV появились намеки на то, что в следующей версии появится поддержка GPU (CUDA). См. директорию opencv/modules/gpu/.

Полезно будет посмотреть библиотеку для трекинга OpenTL (судя по всему, на базе OpenCV) : http://www.opentl.org/index.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Полезно будет посмотреть библиотеку для трекинга OpenTL (судя по всему, на базе OpenCV) : http://www.opentl.org/index.html

Посмотрел эту библиотеку. Трекинг работает очень даже неплохо, но все равно на проце, гпу не используется, хотя на их сайте указано, что должно работать и на гпу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте.

Я новичок, начал читать форумы и книгу.

Подскажите пожалуйста мне направление для решения следующей задачи.

Будет видеофайл, его разрешение 1920x1080 или 1440x1080. Камера установлена в одном положении, никуда не крутится. Движущихся объектов несколько. Мне нужен один( может получаться смазанным, двигаться будет в определённом направлении(справа налево или слева направо))

Нужно обработать видеофайл: определить объект и сопроводить его.

Какие функции подойдут для решения моей задачи?

Реализовывать собираюсь на python'e. Реально ли ..:unsure: ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте.

Я новичок, начал читать форумы и книгу.

Подскажите пожалуйста мне направление для решения следующей задачи.

Будет видеофайл, его разрешение 1920x1080 или 1440x1080. Камера установлена в одном положении, никуда не крутится. Движущихся объектов несколько. Мне нужен один( может получаться смазанным, двигаться будет в определённом направлении(справа налево или слева направо))

Нужно обработать видеофайл: определить объект и сопроводить его.

Какие функции подойдут для решения моей задачи?

Реализовывать собираюсь на python'e. Реально ли ..:unsure: ?

Реально, но нужно уменьшить разрешение раза в 4.

Для того чтобы как то определиться с возможностями opencv посмотрите примеры, в папке opencv/samples/c.

Неплохо бы посмотреть на картинку, узнать что меняется (стационарный ли фон, или меняется и т.д.)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте!

Есть задача-сделать что-то типа проги lkdemo, только снимать координаты поставленного маркера постоянно, а не только в момент клика мышкой. Разумеется в данном случае ОДНОГО маркера.Не подскажете в каком направлении копать?

Заранее спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте!

Есть задача-сделать что-то типа проги lkdemo, только снимать координаты поставленного маркера постоянно, а не только в момент клика мышкой. Разумеется в данном случае ОДНОГО маркера.Не подскажете в каком направлении копать?

Заранее спасибо.

В примере маркеры рисуются окружностями:

             
cvCircle( image, cvPointFrom32f(points[1][i]), 3, CV_RGB(0,255,0), -1, 8,0);[/code]

в cvPointFrom32f(points[1][i]) лежат текущие координаты i-той точки, рассчитанные оптическим потоком.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Т.е. на таком разрешении никак не получится?

Кадров немного, видео длится всего несколько секунд. Время обработки не очень критично.

Прикрепил снимки, пришлось их немного обрезать. cv.rar

Подскажите пожалуйста в какую сторону копать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте!

Имееться веб-камера, которая следит за движением круга. Камера делает джпег картинки и, сравнивая центр круга на картинках, выводит сообщение в какую сторону движеться круг.

Прога работает, но очень часто выбивает "Segmentation fault". Дебаггал через gdb - невожможно считать с p[0] и p[1]. Чуть-чуть проекспереминтивовав, случалось, когда сменить освещение круга и камеры, то прога работала нормально. Но в проге добавил ещё цикл "раскачки камеры" - тоесть сперва камера работает вхолостую, а потом сохраняем кадры.

В чём может быть проблема - в камере или нужно сменить метод распознавания круга?

Пробовал распознать круги простой прогой распознавания с книги, но джпеги делал стандартной Линуксовской программой Cheese - распознаються нормально, но если вручную делать джпеги с помощью OpenCV, то очень часто та же ошибка - "Segmentation fault", невожможно считать с p[0] и p[1].

#include "cv.h"

#include "highgui.h"

#include <math.h>

#include <stdio.h>






int main(int argc, char** argv) 

{


	CvCapture* capture = cvCaptureFromCAM( 0 ); 		



	if (capture==NULL) printf("error capturing from camera\n");


	assert( capture );


        cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352);//1280); 

        cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288);//960); 



	cvWaitKey(100);


        IplImage* frame=0;


        char filename[512];


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

	{

	frame = cvQueryFrame( capture );  // "раскачка" камеры

	cvWaitKey(1);

	}



	float previous[3]; // array for previous circle coordinates - x,y,r

	previous[0]=0;

	previous[1]=0;




for (int cycle=1; cycle<30 ;cycle++ )

{


  frame = cvQueryFrame( capture );


  sprintf(filename, "Image%d.jpg", cycle);

  cvSaveImage(filename, frame);


  cvWaitKey(100);           


  IplImage* image = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);


  IplImage* src = cvLoadImage(filename);


  CvMemStorage* storage = cvCreateMemStorage(0);


  cvSmooth(image, image, CV_GAUSSIAN, 5, 5 );


  CvSeq* results = cvHoughCircles(image, storage, CV_HOUGH_GRADIENT, 2, image->width/10);


  float* p = (float*) cvGetSeqElem( results, 1 );


	if ((previous[0]<p[0]) && (previous[1]<p[1]))

		printf(" right --->>>  down\n");

	if (previous[0]<p[0] && previous[1]>p[1])

		printf(" right --->>>  up\n");

	if (previous[0]>p[0] && previous[1]>p[1])

		printf(" left <<<---  up\n");

	if (previous[0]>p[0] && previous[1]<p[1])

		printf(" left <<<---  down\n");


	if (previous[0]==p[0] && previous[1]<p[1])

		printf(" right --->>>\n");

	if (previous[0]<p[0] && previous[1]==p[1])

		printf(" up\n");

	if (previous[0]==p[0] && previous[1]>p[1])

		printf(" left <<<--- \n");

	if (previous[0]>p[0] && previous[1]==p[1])

		printf(" down\n");


	if (previous[0]==p[0] && previous[1]==p[1])

		printf(" stable\n");



	previous[0]=p[0];

	previous[1]=p[1];


 }

 cvReleaseCapture( &capture );

 return 0;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Просто надо смотреть сколько элементов в последовательности results->total. Это будет количество найденных окружностей (Вам нужно чтобы было больше нуля). Иначе Вы обращаетесь к массиву с нулем элементов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Просто надо смотреть сколько элементов в последовательности results->total. Это будет количество найденных окружностей (Вам нужно чтобы было больше нуля). Иначе Вы обращаетесь к массиву с нулем элементов.

Большое спасибо! Помогло!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×