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

Как прикрутить OpenCV к билдеру?

Recommended Posts

На данном этапе я пока собрал нужную литературу и додумываю как всё-таки использовать фильтр Калмана,ведь он в основном используется для динамических систем.

Я так понял ,что нужно создать окно,которое будет проходить по изображению и в котором будет проводиться наше восстановление.У меня была идея сделать из линии что-то вроде траектории движения и на разрыве использовать фильтр Калмана до тех пор,пока траектория не продолжится .Но твоё решение вроде смотрится проще,только я пока не сильно понимаю как найти конец какой цепочки подходит к концу другой.Если есть примеры или литература-буду благодарен за просвещение!

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


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

Набросал на скорую руку программу на создание связных серий (треков) - посмотри:

#include <list>


#include <highgui.h>

#include <cv.h>

////////////////////////////////////////////////////////////////////////////


typedef std::list<CvPoint> points_cont;

typedef std::list<points_cont> tracks_cont;

////////////////////////////////////////////////////////////////////////////


// Находятся ли две точки рядом друг с другом

bool is_near(const CvPoint &p1, const CvPoint &p2)

{

	return (abs(p1.x - p2.x) < 2) && (abs(p1.y - p2.y) < 2);

}

////////////////////////////////////////////////////////////////////////////


// Добавление точек в массив связных треков

void add_to_track(tracks_cont &tracks, const CvPoint &p)

{

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

	bool find_track = false;

	for (tracks_cont::iterator it = tracks.begin(); it != tracks.end(); ++it)

	{

		if (is_near(it->front(), p))

		{

			it->push_front(p);

			find_track = true;

			break;

		}

		if (is_near(it->back(), p))

		{

			it->push_back(p);

			find_track = true;

			break;

		}

	}

	// Если серия не найдена, то создаём новую

	if (!find_track)

	{

		points_cont new_track;

		new_track.push_back(p);

		tracks.push_back(new_track);

	}

	else

	{

		// Если точка найдена, то пробуем объединить соприкасающиеся серии

		for (tracks_cont::iterator it1 = tracks.begin(); it1 != tracks.end(); ++it1)

		{

			tracks_cont::iterator it2 = it1;

			for (++it2; it2 != tracks.end()

			{

				if (is_near(it1->front(), it2->front()))

				{

					for (points_cont::iterator it_p = it2->begin(); it_p != it2->end(); ++it_p)

					{

						it1->push_front(*it_p);

					}

					it2 = tracks.erase(it2);

					continue;

				}

				if (is_near(it1->front(), it2->back()))

				{

					for (points_cont::reverse_iterator it_p = it2->rbegin(); it_p != it2->rend(); ++it_p)

					{

						it1->push_front(*it_p);

					}

					it2 = tracks.erase(it2);

					continue;

				}

				if (is_near(it1->back(), it2->front()))

				{

					for (points_cont::iterator it_p = it2->begin(); it_p != it2->end(); ++it_p)

					{

						it1->push_back(*it_p);

					}

					it2 = tracks.erase(it2);

					continue;

				}

				if (is_near(it1->back(), it2->back()))

				{

					for (points_cont::reverse_iterator it_p = it2->rbegin(); it_p != it2->rend(); ++it_p)

					{

						it1->push_back(*it_p);

					}

					it2 = tracks.erase(it2);

					continue;

				}

				++it2;

			}

		}

	}

}

////////////////////////////////////////////////////////////////////////////


int _tmain(int argc, _TCHAR* argv[])

{

	IplImage* img = cvLoadImage("f:\\break_lines.png", 0);

	cvShowImage("img", img);


	// Создание массивов связных точек

	tracks_cont tracks;

	unsigned char* pbuf = (unsigned char *)img->imageData;

	for (int y = 0; y < img->height; ++y)

	{

		for (int x = 0; x < img->width; ++x)

		{

			if (*pbuf == 0)

				add_to_track(tracks, cvPoint(x, y));

			++pbuf;

		}

		pbuf += (img->widthStep - img->width);

	}


	IplImage* second_img = cvCreateImage(cvGetSize(img), 8, 1);

	cvSet(second_img, cvScalar(255));


	// Вывод итоговых серий

	for (tracks_cont::iterator it1 = tracks.begin(); it1 != tracks.end()

	{

		if (it1->size() == 1)

			it1 = tracks.erase(it1);

		else

			++it1;

	}

	for (tracks_cont::iterator it1 = tracks.begin(); it1 != tracks.end(); ++it1)

	{

		for (points_cont::iterator it2 = it1->begin(); it2 != it1->end(); ++it2)

		{

			(second_img->imageData + it2->y * second_img->widthStep + it2->x)[0] = 0;


			cvShowImage("second_img", second_img);

			if (cvWaitKey(40) > 0)

				break;

		}

	}


	cvReleaseImage(&second_img);

	cvReleaseImage(&img);

	cvDestroyAllWindows();


	return 0;

}

////////////////////////////////////////////////////////////////////////////[/code]

Никаких оптимизаций и проверок, времени нет. По-хорошему, сейчас надо определить какая серия каким концом относится к другой серии с другим концом. А после фильтром Кальмана восстановить пропущенные точки.

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


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

Спасибо,буду разбираться!Потом отпишусь!А какую среду разработки посоветуешь или без разницы?

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


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

Я майкрософтовской студией пользуюсь, так как ей и OpenCV компилирую. Удобно отлаживать.

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


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

Чувствую,что тоже на нее перейду,потому что Builder ругается на it1,пишет,что он уже был декларирован.Может я где-то что-то и недоглядел :


  for (tracks_cont::iterator it1 = tracks.begin(); it1 != tracks.end()

        {

                if (it1->size() == 1)

                        it1 = tracks.erase(it1);

                else

                        ++it1;

        }

       for (tracks_cont::iterator it1=tracks.begin(); it1 != tracks.end(); ++it1)

        {

                for (points_cont::iterator it2 = it1->begin(); it2 != it1->end(); ++it2)

                {

                        (second_img->imageData + it2->y * second_img->widthStep + it2->x)[0] = 0;


                        cvShowImage("second_img", second_img);

                        if (cvWaitKey(40) > 0)

                                break;

                }

        }


[/code]

Сейчас буду пробовать в студии.

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


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

Такое бывает, когда совместимость с MFC включена.

во втором цикле так напишите, и все должно скомпилироваться:

it1=tracks.begin(); it1 != tracks.end(); ++it1

PS: Переход на студию поддерживаю, много проблем уходит

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


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

Программа успешно компилируется,но при запуске выдает ошибку.Пробовал уже и в студии и в Builder.

В Builder:

В студии:

Не могу понять,что ей не нравится.

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


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

Что за ошибка в студии? На скриншоте ничего нет.

И выложи своё изображение с разрывными линиями.

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


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

Ошибок нет,но программа не выдает результат!

Выкладываю элементарное изображение:

Для наглядности вот тип изображения,которое должно восстанавливаться в идеале:

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


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

"Элементарное изображение" обрабатывается быстро и без проблем. Может, ты путь неправильно прописал. Что говорит отладчик об ошибке? В какой строке?

Изображение с изолиниями обрабатывается очень медленно. Нужна оптимизация.

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


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

Я разобрался,все работает,проблема была в версии OpenCV.

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

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

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


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

Найти концы легко: берёшь начало (front) и конец (back) каждого списка и находишь ближайшее (евклидово расстояние) начало или конец другого.

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


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

Целесообразно будет использовать функцию с подальшей передачей параметров ?И куда лучше сохранять подошедшие концы.Я немного сбился со своего алгоритма.


//Евклидово расстояние

double dist(const CvPoint &w1, const CvPoint &w2)

{

return  sqrt((double)((w2.x - w1.x)*(w2.x - w1.x) +(w2.y - w1.y)*(w2.y - w1.y))) ;

}

Или можно сделать все как-то проще?

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


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

Евклидово расстояние проще не вычислишь.

А данные сохраняй так, как тебе удобней с ними будет после работать. Можешь вообще в вектора или матрицы перегнать. Я бы так и сделал.

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


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

А можно ли реализовать создание треков так,чтобы они прорисовывались только один раз(однопиксельно) без "утолщений".Это нужно ,чтобы избежать трудностей в дальнейшем.

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


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

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

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


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

Как скомпилировать OpenCV 2.2 для работы с С++Builder. ??

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


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

Как скомпилировать OpenCV 2.2 для работы с С++Builder. ??

У меня топикоп ниже версия 2.0 есть, правда почемуто на тех функциях которые мне нужны вылетает.

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


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

У меня топикоп ниже версия 2.0 есть, правда почемуто на тех функциях которые мне нужны вылетает.

Здесь http://www.compvision.ru/forum/index.php?showtopic=81&st=20 есть полный проект с длл, заголовочниками и либами под билдер 6 для версии 2.1.

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


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

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

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


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

Процесс писать пока нету времени, вот работающий минимальный проект Opencv 2.1 + Builder 6:

Empty_proj.rar

и мои include из opencv2.1/include/

include.rar

В рамках выложенного вами проекта все отлично - через Progect - Option - Directories прописал пути к вашим include и lib в проекте и через bcb6 все прекрасно откомпилировалось, создался exe и я увидел картинку с камеры. Но возникла проблема после того как я создал свой собсвенный проект, поместил туда папки с вашими include и lib, а также все dll. Опять-же прописал все пути в Progect - Option - Directories, а также прописал #include "cv.h"

#include "highgui.h"

в файле MainDemo.h (сам файл проекта MainDemo.bpr соответственно),

но, при компиляции выдаются ошибки:

[Linker Error] Unresolved external '_cvCreateImage' referenced from D:\АСПИРАНТУРА\MY PROJECT\UCVISION V1.0\MAINDEMO_.OBJ

[Linker Error] Unresolved external 'mycvGetImage(Extctrls::TImage *, _IplImage *)' referenced from D:\АСПИРАНТУРА\MY PROJECT\UCVISION V1.0\MAINDEMO_.OBJ

[Linker Error] Unresolved external 'mycvShowImage(Extctrls::TImage *, _IplImage *)' referenced from D:\АСПИРАНТУРА\MY PROJECT\UCVISION V1.0\MAINDEMO_.OBJ

[Linker Error] Unresolved external '_cvReleaseImage' referenced from D:\АСПИРАНТУРА\MY PROJECT\UCVISION V1.0\MAINDEMO_.OBJ

Данные ошибки появляются когда я вставляю в тело программы следующий код (впрочем попытка использовать ЛЮБЫЕ функции openCV приводит к тому-же результату!!!!):

void __fastcall TForm_MainDemo::Button2Click(TObject *Sender)

{

CvSize sz; sz.width=320; sz.height=240;

src = cvCreateImage(sz,IPL_DEPTH_8U,3);

mycvGetImage(Image1,src);

mycvShowImage(Image2,src);

cvReleaseImage(&src);

}

Этот код должен переводить TImage в объект OpenCV типа IplImage и обратно при помощи библиотеки myCV

Вот ссылка на библиотеку Вот ссылка на библиотеку

http://roboforum.ru/wiki/%D0%91%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0_myCV#.D0.9D.D0.B0.D0.B7.D0.BD.D0.B0.D1.87.D0.B5.D0.BD.D0.B8.D0.B5_.D0.B1.D0.B8.D0.B1.D0.BB.D0.B8.D0.BE.D1.82.D0.B5.D0.BA.D0.B8

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

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


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

Судя по включаемым заголовочникам:

А пути к либам прописали (Library Path в свойствах проекта) ?

Попробуйте прямо в тот проект который у Вас с форума взят вставить свой кусок кода.

Если будет работать, значит дело в свойствах проекта.

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


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

Судя по включаемым заголовочникам:

А пути к либам прописали (Library Path в свойствах проекта) ?

Попробуйте прямо в тот проект который у Вас с форума взят вставить свой кусок кода.

Если будет работать, значит дело в свойствах проекта.

Прописано D:\АСПИРАНТУРА\MY PROJECT\UCVISION v1.0\libs в Library Path в меню Progect - Option - Directories. Или где-то еще надо пути прописывать, я прописываю пути к либам и прочему именно в этом меню. Может еще чего не хватает?

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


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

Прописано D:\АСПИРАНТУРА\MY PROJECT\UCVISION v1.0\libs в Library Path в меню Progect - Option - Directories. Или где-то еще надо пути прописывать, я прописываю пути к либам и прочему именно в этом меню. Может еще чего не хватает?

Может русские буквы и пробелы в названиях директорий мешают?

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×