Jump to content
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), а что должно само освобождаться?

 

Share this post


Link to post
Share on other sites

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

 

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

Share this post


Link to post
Share on other sites

331.JPG

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

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

Share this post


Link to post
Share on other sites

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

  • Like 1

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
38 минут назад, fotomer сказал:

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

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

Share this post


Link to post
Share on other sites
38 минут назад, Khludenkov сказал:

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

  • Like 1

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


  • Recently Browsing   0 members

    No registered users viewing this page.

×