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

Утечка памяти. Что надо освобождать.

Recommended Posts

Сделал программу получения видео в камеры и поиска на видео заданного объекта. По образцу с оф. сайта openCV.

int main( int argc, char** argv )
{
	VideoCapture cap(1); // Открыть камеру (устройство 1). Для открытия встроенной камеры вызывать 0 устройство.

	if(!cap.isOpened())  //  Проверка корректности отработки
{
string message = "Проверьте камеру или укажите другой номер устройства в коде"; 
//		readme(message); 
return -1; 
}

//Mat img_object = imread("D:\\005.jpg", CV_LOAD_IMAGE_GRAYSCALE); 
	Mat img_object = imread("D:\\feat\\iiL2.jpg", CV_LOAD_IMAGE_GRAYSCALE );

	for(;; )
{
	Mat frame; 
	cap >> frame; // Получить очередной фрейм из камеры

	Mat img_scene = frame; 

//	Mat img_scene = imread("D:\\feat\\iiR.jpg", CV_LOAD_IMAGE_GRAYSCALE );

//	Mat img_object = 	imread("D:\\stereoImg\\iL.jpg", CV_LOAD_IMAGE_GRAYSCALE );
//	Mat img_scene = 	imread("D:\\stereoImg\\iR.jpg", CV_LOAD_IMAGE_GRAYSCALE );

	if( !img_object.data || !img_scene.data )
	{ std::cout<< " --(!) Error reading images " << std::endl; return -1; }

	//	Detect the keypoints using SURF Detector
	int minHessian = 400;

	SurfFeatureDetector detector( minHessian );

	std::vector<KeyPoint> keypoints_object, keypoints_scene;

	detector.detect( img_object, keypoints_object );
	detector.detect( img_scene, keypoints_scene );

	//-- Step 2: Calculate descriptors (feature vectors)
	SurfDescriptorExtractor extractor;

	Mat descriptors_object, descriptors_scene;

	extractor.compute( img_object, keypoints_object, descriptors_object );
	extractor.compute( img_scene, keypoints_scene, descriptors_scene );

	//-- Step 3: Matching descriptor vectors using FLANN matcher
	FlannBasedMatcher matcher;
	std::vector< DMatch > matches;
	matcher.match( descriptors_object, descriptors_scene, matches );

	double max_dist = 0;
	double min_dist = 100;

	//	Quick calculation of max and min distances between keypoints
	for( int i = 0; i < descriptors_object.rows; i++ )
	{
		double dist = matches[i].distance;
		if( dist < min_dist ) min_dist = dist;
		if( dist > max_dist ) max_dist = dist;
	}

	printf("-- Max dist : %f \n", max_dist );
	printf("-- Min dist : %f \n", min_dist );

	//-- Draw only "good" matches (i.e. whose distance is less than 3 * min_dist )
	std::vector< DMatch > good_matches;

	for( int i = 0; i < descriptors_object.rows; i++ )
	{
		if( matches[i].distance < 3 * min_dist )
		{
			good_matches.push_back( matches[i]);
		}
	}

	Mat img_matches;
	drawMatches( img_object, keypoints_object, img_scene, keypoints_scene,
		good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
		vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

	//-- Localize the object
	std::vector<Point2f> obj;
	std::vector<Point2f> scene;

	for(int i = 0; i < good_matches.size(); i++)
	{
		//	Get the keypoints from the good matches
//		if( (keypoints_object[good_matches[i].queryIdx].pt.x - keypoints_object[good_matches[i].queryIdx].pt.x) > 0)
		{
			obj.push_back( keypoints_object[good_matches[i].queryIdx].pt );
			scene.push_back( keypoints_scene[good_matches[i].trainIdx].pt );
/*
			printf("p1.x = %f\tp2.x = %f\tdx = %f\r\n", keypoints_object[good_matches[i].queryIdx].pt.x,
				keypoints_scene[ good_matches[i].trainIdx ].pt.x,
				keypoints_object[good_matches[i].queryIdx].pt.x - keypoints_scene[ good_matches[i].trainIdx ].pt.x);
*/
		}
	}

	Mat H = findHomography( obj, scene, CV_RANSAC );

	//-- Get the corners from the image_1 ( the object to be "detected" )
	std::vector<Point2f> obj_corners(4);
	obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( img_object.cols, 0 );
	obj_corners[2] = cvPoint( img_object.cols, img_object.rows ); obj_corners[3] = cvPoint( 0, img_object.rows );
	std::vector<Point2f> scene_corners(4);

	perspectiveTransform( obj_corners, scene_corners, H);

	//-- Draw lines between the corners (the mapped object in the scene - image_2 )
	line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4 );
	line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
	line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
	line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );

	//-- Show detected matches
	imshow( "Good Matches & Object detection", img_matches );

	H.release();
	img_matches.release();
	

	waitKey(20);

	}
	return 0;
}

Постоянно "вылетает" по memory exception.

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

Скажите, что надо освобождать (release), а что должно само освобождаться?

 

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


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

Нет необходимости явно вызывать .Release у Mat

 

Какая точно ошибка?

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


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

331.JPG

Сижу в визуал студии 2010. Пробовал посмотреть стек вызовов. Не показывает.

А если в цикле показывать одно и то же окно через imshow. Его надо периодически уничтожать через destroy?

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


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

Ничего не надо уничтожать. Кстати говоря, если посмотришь в консоль, то увидишь где и почему появилась ошибка. Потом в отладчик.

  • Like 1

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


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

Спасибо, попробуем.

Убрал везде release(). Работает, спасибо.

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


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

А памяти точно достаточно? Фунции распознования довольно прожорливые. Еще если программа под х86, то в VisualStudio в настройках желательно указать Linker-System - Enable Large Adresses.

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


Ссылка на сообщение
Поделиться на других сайтах
38 минут назад, fotomer сказал:

Фунции распознования довольно прожорливые

То есть распберри к примеру не потянет?

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


Ссылка на сообщение
Поделиться на других сайтах
38 минут назад, Khludenkov сказал:

То есть распберри к примеру не потянет?

Зависит от кол-ва пикселей в картинке, например Win7 x64 с планкой 4Гб (все лишне отключено) на  поиске соответствия на 2 снимках по 18 МегаПикселей вылетает по памяти.

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


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

Если можно, ещё вопрос.

Есть Cortex A8 с установленным линуксом и opencv.

opencv используется для сшивки трёх кадров примерно по 900х600. Итоговое 1500х500.

Сшивает за 35 секунд.

Основное время занимает warp (25 секунд).

Можно ли как-то убыстрить этот процесс?

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


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

Конечно можно. Но для этого надо знать, что конкретно тормозит и почему. Обычно берут в руки профайлер (valgrind это будет судя по всему), смотрят, оптимизируют. Вряд ли получится что-то кардинально улучшить парой опций: либо оптимизировать вручную, либо искать альтернативные оптимизированные под конкретную платформу библиотеки, реализующие необходимый функционал.

  • Like 1

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×