Jump to content
Compvision.ru
Sign in to follow this  
Cfr

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

Recommended Posts

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

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

Share this post


Link to post
Share on other sites
Там есть папка release, запускай через bat-файл, в котором прописаны параметры используемых алгоритмов.

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites
В папке 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 файле писать? Обязательно весь проект загружать?

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

И хочу еще попробовать заполнять массив 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]

Share this post


Link to post
Share on other sites

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

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

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]

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

BlobTrack.rar

Share this post


Link to post
Share on other sites
Да и в самом opencv есть blob_tracking_modules, вроде неплохо работает

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Никто не пробовал переписать это на 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]

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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

Share this post


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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

Прога работает, но очень часто выбивает "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;

}

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×