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

Проблемы с ExtractSURF() и CvMemStorage

Recommended Posts

ну тут вопрос возможно ли распараллеливание SURF (что эквивалентно ответу на вопрос можно ли делить изображение на куски)

http://www.vision.ee.ethz.ch/~surf/eccv06.pdf надо как бы понять сам алгоритм.

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

а так то пусть 1Гб занято системой на всякую лабуду,

загружаем 1 изображение ~1Гб находим точки + N мб (зависит от длины вектора дескрипторов и количества точек)

удаляем 1 изображения -1Гб

загружаем 2 изображение (все тоже самое)

удаляем 2 изображение

имеем (N1+N2)мб точек+дескрипторы. фильтруем с помощью flannFindPairs.

удаляем все остальные точки, имеем Nмб точек.

пихаем все добро в cvFindHomography там RANSAC'ом фильтруется.

(кстати хотелось бы получить его отдельную реализацию, а то он встроен cvFindHomography , а внутренний код я не осилил и сам написать тоже не осилил)

(и еще вопрос когда надо использовать матрицу гомографии, а когда фундаментальную матрицу)

удаляем все точки.имеем только матрицу гомографии.

загружем 2 изображения ~2Гб и делаем cvWarpPerspective (для варпа полюбому надо загружать все изображения или писать что то свое)

в итоге за 4 гб вроде и не вышли.

другое дело если это какие то замуты в opencv ограничение на кол-во точек и используемую суммарную память. (вроде в винде х32 приложение может использовать макс 2Гб с расширением (какой то там ключ) вроде бы 3Гб)

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


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

ну тут вопрос возможно ли распараллеливание SURF (что эквивалентно ответу на вопрос можно ли делить изображение на куски)

http://www.vision.ee.ethz.ch/~surf/eccv06.pdf надо как бы понять сам алгоритм.

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

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

а так то пусть 1Гб занято системой на всякую лабуду,

загружаем 1 изображение ~1Гб находим точки + N мб (зависит от длины вектора дескрипторов и количества точек)

удаляем 1 изображения -1Гб

загружаем 2 изображение (все тоже самое)

удаляем 2 изображение

имеем (N1+N2)мб точек+дескрипторы. фильтруем с помощью flannFindPairs.

удаляем все остальные точки, имеем Nмб точек.

пихаем все добро в cvFindHomography там RANSAC'ом фильтруется.

Важно понимать, что у нас есть такая замечательная вещь, как виртуальная память, там мы можем хранить большие объемы и не обязательно пихать все в ОЗУ :)

(кстати хотелось бы получить его отдельную реализацию, а то он встроен cvFindHomography , а внутренний код я не осилил и сам написать тоже не осилил)

(и еще вопрос когда надо использовать матрицу гомографии, а когда фундаментальную матрицу)

удаляем все точки.имеем только матрицу гомографии.

загружем 2 изображения ~2Гб и делаем cvWarpPerspective (для варпа полюбому надо загружать все изображения или писать что то свое)

Да, насчет RANSAC вы правы - я тоже хотел бы отдельно. Также не знаю ответа на вопрос "когда надо использовать матрицу гомографии, а когда фундаментальную матрицу". И конечно то, о чем я тоже задумывался - как "скормить" всё изображение (мы подаем только одно изображение, а не два) функции cvWarpPerspective() ...

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


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

ну так собственно говоря сам SURF и заключается в том как выделить точки и как посчитать дескрипторы.

Важно понимать, что у нас есть такая замечательная вещь, как виртуальная память, там мы можем хранить большие объемы и не обязательно пихать все в ОЗУ

ну если винда сделает все сама на автомате то хорошо, но скорее всего об этом надо самому заботится.

(мы подаем только одно изображение, а не два) функции cvWarpPerspective()

да точно, я ошибся. но подумайте о том, что если мы склеиваем N изображений, то у нас первое изображение растет постоянно

т.е. на первом шаге 1+(1-per1)

на втором 1+(1-per1)+(1-per2)

на N шаге 1+(1-per1)+(1-per2)+..+(1-perN)

где perN процент перекрытия изображений на N шаге.

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


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

хмм посмотрел что происходит в диспетчере задач, когда доходит дело до cvExtractSURF , так там резкое выделение памяти где то 1.5 гига, вообще то странно, учитывая, что потом то все освобождается (т.е. это не дескрипторы столько занимают) по F10 не удалось войти в функцию возможно потому что она в скомпиленой либе?

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

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


CvMat* homography_matrix = cvCreateMat(3, 3, CV_32FC1); 

cvFindHomography(points2, points1, homography_matrix, CV_RANSAC, RANSAC_ERR); // возможно переставлять points1 и points2 местами?

IplImage* img_rgb1 = cvLoadImage("1.bmp");

IplImage* img_rgb2 = cvLoadImage("2.bmp");

IplImage* img_warp=cvCreateImage(cvSize(img_rgb1->width+img_rgb2->width,img_rgb1->height+img_rgb2->height),IPL_DEPTH_8U,3);

cvWarpPerspective(img_rgb2,img_warp,homography_matrix,CV_WARP_FILL_OUTLIERS,cvScalarAll(0));

cvSetImageROI(img_warp,cvRect(0,0,img_rgb1->width,img_rgb1->height));

cvCopy(img_rgb1,img_warp);

cvResetImageROI(img_warp);

в итоге у меня удачно получилось склеить два снимка которые вы выкладывали, они правда 30-40 мб и в размере 5кх7к

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


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

хмм посмотрел что происходит в диспетчере задач, когда доходит дело до cvExtractSURF , так там резкое выделение памяти где то 1.5 гига, вообще то странно, учитывая, что потом то все освобождается (т.е. это не дескрипторы столько занимают) по F10 не удалось войти в функцию возможно потому что она в скомпиленой либе?

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

Какой размер тайла Вы ставите?

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

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


CvMat* homography_matrix = cvCreateMat(3, 3, CV_32FC1); 

cvFindHomography(points2, points1, homography_matrix, CV_RANSAC, RANSAC_ERR); // возможно переставлять points1 и points2 местами?

IplImage* img_rgb1 = cvLoadImage("1.bmp");

IplImage* img_rgb2 = cvLoadImage("2.bmp");

IplImage* img_warp=cvCreateImage(cvSize(img_rgb1->width+img_rgb2->width,img_rgb1->height+img_rgb2->height),IPL_DEPTH_8U,3);

cvWarpPerspective(img_rgb2,img_warp,homography_matrix,CV_WARP_FILL_OUTLIERS,cvScalarAll(0));

cvSetImageROI(img_warp,cvRect(0,0,img_rgb1->width,img_rgb1->height));

cvCopy(img_rgb1,img_warp);

cvResetImageROI(img_warp);

в итоге у меня удачно получилось склеить два снимка которые вы выкладывали, они правда 30-40 мб и в размере 5кх7к

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

Скиньте весь код, если не затруднит.

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


Ссылка на сообщение
Поделиться на других сайтах
Какой размер тайла Вы ставите?

целиком.

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

да вроде как оба правильные только 1 будет выглядеть лучше другого, как определить какой лучше хз.

первоочередная задача сейчас реализовать RANSAC для тестирования тут два варианта, либо навелосипедить самому или выдрать из opencv ,еще есть вариант с http://web.me.com/dellaert/FrankDellaert/Publications/Entries/2009/7/16_GroupSAC_(ICCV_09).html

http://code.google.com/p/groupsac/

ну вот код вообщем то ничего особенного, чем больше HESSIAN тем меньше точек находит.

// SURF_test.cpp : Defines the entry point for the console application.

//


#include "stdafx.h"


#include <cv.h>

#include <highgui.h>


#define HESSIAN 500

#define FLAG_NUM_DESCR 1

#define RANSAC_ERR 1


#define WITH_VISUAL_TESTS 0 // вывод точек, линий  и т.д. для визуальной проверки

#define WITH_LINES 1 // с линиями или только точки

#define ALL_GREY 0 // только грей или цветные



void flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors, const CvSeq*, const CvSeq* imageDescriptors, std::vector<int>& ptpairs )

{

	int length = (int)(objectDescriptors->elem_size/sizeof(float));


    cv::Mat m_object(objectDescriptors->total, length, CV_32F);

	cv::Mat m_image(imageDescriptors->total, length, CV_32F);



	// copy descriptors

    CvSeqReader obj_reader;

	float* obj_ptr = m_object.ptr<float>(0);

    cvStartReadSeq( objectDescriptors, &obj_reader );

    for(int i = 0; i < objectDescriptors->total; i++ )

    {

        const float* descriptor = (const float*)obj_reader.ptr;

        CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );

        memcpy(obj_ptr, descriptor, length*sizeof(float));

        obj_ptr += length;

    }

    CvSeqReader img_reader;

	float* img_ptr = m_image.ptr<float>(0);

    cvStartReadSeq( imageDescriptors, &img_reader );

    for(int i = 0; i < imageDescriptors->total; i++ )

    {

        const float* descriptor = (const float*)img_reader.ptr;

        CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader );

        memcpy(img_ptr, descriptor, length*sizeof(float));

        img_ptr += length;

    }


    // find nearest neighbors using FLANN

    cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);

    cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);

    cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4));  // using 4 randomized kdtrees

    flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked


    int* indices_ptr = m_indices.ptr<int>(0);

    float* dists_ptr = m_dists.ptr<float>(0);

    for (int i=0;i<m_indices.rows;++i) {

    	if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) {

    		ptpairs.push_back(i);

    		ptpairs.push_back(indices_ptr[2*i]);

    	}

    }

}

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

{

	//TODO

	//1.сделать консольные параметры

	//2.глобальная задача подготовить интерфейсы для разных методов(SIFT,SURF,STAR и т.д.)Нахождение точек, нахождение дескрипторов,сравнение дескрипторов разное, а остальное едино.

	//3.придумать более продуктивный способ выводить точки не загружая изображение, а как то поверх, возможно простой гуй чтобы выбирать\увеличивать область.

	//4.отдельно реализовать RANSAC или подключить GroupSAC

	//5.Подправить cvExtractSURF если возможно (жрёт память)

	//6.если прижмет подправить cvWarpPerspective под очень большие изображения.(разобраться со свопом)

	//7.разобраться с многопоточностью.

	//8.возможно перейти на opencv2.2/

	//9.сделать обработку для n изображений.

	//10.вычислить минимальную область достаточную для размещения первого и варпнутого изображения



	std::string name1= "img1.png";

	std::string name2= "img2.png";


	IplImage* img1_g = cvLoadImage(name1.c_str(), CV_LOAD_IMAGE_GRAYSCALE); // сразу в грей (потом можно подложить цветные)

	IplImage* img2_g = cvLoadImage(name2.c_str(), CV_LOAD_IMAGE_GRAYSCALE);


	int width1=img1_g->width;

	int height1=img1_g->height;

	int width2=img2_g->width;

	int height2=img2_g->height;


	CvMemStorage* storage = cvCreateMemStorage(0);

	CvSeq *Keypoints1 = 0, *Descriptors1 = 0;

	CvSeq *Keypoints2 = 0, *Descriptors2 = 0;

	CvSURFParams params = cvSURFParams(HESSIAN, FLAG_NUM_DESCR);  // параметры по дефолту (500,1)

	cvExtractSURF( img1_g, 0, &Keypoints1, &Descriptors1,

						 storage, params );

	cvExtractSURF( img2_g, 0, &Keypoints2, &Descriptors2,

						 storage, params );


	// нахождение пар 

	std::vector<int> ptpairs;

	//проверить функцию.возможно переписать.

	flannFindPairs( Keypoints1, Descriptors1, Keypoints2, Descriptors2, ptpairs );  // быстрее чем брутфорсный перебор // функцию не проверял

	//по хорошему тут сразу же удалить точки которые не попали в пары(если критична память)


	IplImage* img1;

	IplImage* img2;

	int n_channel=0;

	if (ALL_GREY)

	{

		img1=img1_g;

		img2=img2_g;

		n_channel=1;

	}

	else

	{

		cvReleaseImage(&img1_g);

		cvReleaseImage(&img2_g);

		img1 = cvLoadImage(name1.c_str());

		img2 = cvLoadImage(name2.c_str());

		n_channel=img1->nChannels; // оба изображения должны быть цветные

		//n_channel=3;

	}


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

	if (WITH_VISUAL_TESTS)

	{

		//тестируем найденные точки (все точки без сопоставлений)


		// получить из Seq точки

		CvSURFPoint* point1;

		for (int i=0;i<Keypoints1->total;i++)

		{

			point1=(CvSURFPoint*)cvGetSeqElem(Keypoints1,i);

			cvCircle(img1,															/* the dest image */

				cvPoint( cvRound( point1->pt.x), cvRound( point1->pt.y ) ), 2,      /* center point and radius */

				cvScalar(0, 0, 255, 0),												/* the color red */

				-1, 8, 0);

		}

		cvSaveImage("points1.png", img1);


		CvSURFPoint* point2;

		for (int i=0;i<Keypoints2->total;i++)

		{

			point2=(CvSURFPoint*)cvGetSeqElem(Keypoints2,i);

			cvCircle(img2,															/* the dest image */

				cvPoint( cvRound( point2->pt.x), cvRound( point2->pt.y ) ), 2,      /* center point and radius */

				cvScalar(255, 0, 0, 0),												/* the color blue */

				-1, 8, 0);

		}

		cvSaveImage("points2.png", img2);


		//рисуем линии просто для составленных пар

		//по горизонтали 

		IplImage* img_lines_g=cvCreateImage(cvSize(width1+width2,MAX(height1,height2)),IPL_DEPTH_8U,n_channel);

		cvSetImageROI(img_lines_g,cvRect(0,0,width1,height1));

		cvCopy(img1,img_lines_g);

		cvSetImageROI(img_lines_g,cvRect(width1,0,width2,height2));

		cvCopy(img2,img_lines_g);

		cvResetImageROI(img_lines_g);

		for( int i = 0; i < (int)ptpairs.size(); i += 2 )

		{

			CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( Keypoints1, ptpairs[i]);

			CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( Keypoints2, ptpairs[i+1] );

			cvLine( img_lines_g, cvPoint(r1->pt.x,r1->pt.y ),

					cvPoint(width1+r2->pt.x, r2->pt.y ), cvScalar(0, 255, 255, 0) ,1,CV_AA);

		}

		cvSaveImage("lines_g.png", img_lines_g);

		cvReleaseImage(&img_lines_g);

		//по вертикали

		IplImage* img_lines_v=cvCreateImage(cvSize(MAX(width1,width2),height1+height2),IPL_DEPTH_8U,n_channel);

		cvSetImageROI(img_lines_v,cvRect(0,0,width1,height1));

		cvCopy(img1,img_lines_v);

		cvSetImageROI(img_lines_v,cvRect(0,height1,width2,height2));

		cvCopy(img2,img_lines_v);

		cvResetImageROI(img_lines_v);

		for( int i = 0; i < (int)ptpairs.size(); i += 2 )

		{

			CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( Keypoints1, ptpairs[i]);

			CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( Keypoints2, ptpairs[i+1] );

			cvLine( img_lines_v, cvPoint(r1->pt.x,r1->pt.y ),

					cvPoint(r2->pt.x, height1+r2->pt.y ), cvScalar(255, 255, 0, 0) ,1,CV_AA);

		}

		cvSaveImage("lines_v.png", img_lines_v);

		cvReleaseImage(&img_lines_v);


		//подсветка пар точек (без и с линиями)  с выводом

		//по горизонтали

		IplImage* img_pairs_g=cvCreateImage(cvSize(width1+width2,MAX(height1,height2)),IPL_DEPTH_8U,n_channel);

		cvSetImageROI(img_pairs_g,cvRect(0,0,width1,height1));

		cvCopy(img1,img_pairs_g);

		cvSetImageROI(img_pairs_g,cvRect(width1,0,width2,height2));

		cvCopy(img2,img_pairs_g);

		cvResetImageROI(img_pairs_g);


		cvNamedWindow( "lines_g", 0);

		cvShowImage( "lines_g", img_pairs_g);

		for(int i=0;

		{	

			int key=cvWaitKey(0);

			if (key==27) //esс

				break;

			else

			{

				if (key ==2490368) //стрелка вверх

				{

					i+=2;

				}

				if (key ==2621440) //стрелка вниз

				{

					i-=2;

				}

				if (((int)ptpairs.size()-2)<i)

					i=0;

				if (i<0)

					i=(int)ptpairs.size()-2;

				CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( Keypoints1, ptpairs[i]);

				CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( Keypoints2, ptpairs[i+1] );

				cvCircle(img_pairs_g,															

					cvPoint(r1->pt.x,r1->pt.y), 4,     

					cvScalar(0, 255, 255, 0),												

					-1, 8, 0);

				cvCircle(img_pairs_g,															

					cvPoint(width1+r2->pt.x, r2->pt.y), 4, 

					cvScalar(0, 255, 255, 0),												

					-1, 8, 0);

				if (WITH_LINES)

				{

					cvLine( img_pairs_g, cvPoint(r1->pt.x,r1->pt.y ),

						cvPoint(width1+r2->pt.x, r2->pt.y ), cvScalar(0, 255, 255, 0) ,1,CV_AA);

				}

				//для больших ихображений будет тормозить

				cvShowImage( "lines_g", img_pairs_g);//придумать более продуктивный способ выводить точки не загружая изображение, а как то поверх.

			}

		}

		cvReleaseImage(&img_pairs_g);

	}

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


	//считаем матрицу гомографии

	int c_point_count = ((int)ptpairs.size())/2;

	CvMat* points1 = cvCreateMat(2, c_point_count, CV_32FC1); 

	CvMat* points2 = cvCreateMat(2, c_point_count, CV_32FC1);   

	for( int i = 0; i < (int)ptpairs.size(); i += 2)

	{

		CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( Keypoints1, ptpairs[i]);

		CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( Keypoints2, ptpairs[i+1]);


		cvmSet(points1,0,i/2,r1->pt.x);

		cvmSet(points1,1,i/2,r1->pt.y);

		cvmSet(points2,0,i/2,r2->pt.x);

		cvmSet(points2,1,i/2,r2->pt.y);

	}

	CvMat* homography_matrix = cvCreateMat(3, 3, CV_32FC1); 

	cvFindHomography(points2, points1, homography_matrix, CV_RANSAC, RANSAC_ERR);


	//cvFindHomography(points1, points2, homography_matrix, CV_RANSAC, RANSAC_ERR);// матрица наоборот?


	//вся матрица гомографии

	int m11=CV_MAT_ELEM( *homography_matrix, float, 0, 0 );//

	int m12=CV_MAT_ELEM( *homography_matrix, float, 0, 1 );//

	int m13=CV_MAT_ELEM( *homography_matrix, float, 0, 2 );//сдвиг по х

	int m21=CV_MAT_ELEM( *homography_matrix, float, 1, 0 );//

	int m22=CV_MAT_ELEM( *homography_matrix, float, 1, 1 );//

	int m23=CV_MAT_ELEM( *homography_matrix, float, 1, 2 );//сдвиг по у

	int m31=CV_MAT_ELEM( *homography_matrix, float, 2, 0 );//

	int m32=CV_MAT_ELEM( *homography_matrix, float, 2, 1 );//

	int m33=CV_MAT_ELEM( *homography_matrix, float, 2, 2 );//



	//вопрос в том что накладывается сверху? как определить лучший вариант(более глубокий вопрос это выбор нелинейной области перекрытия + сглаживание)

	IplImage* img_out=cvCreateImage(cvSize(width1+width2,height1+height2),IPL_DEPTH_8U,n_channel); // максимальный размер 

	//IplImage* img_out=cvCreateImage(cvSize(m13+width2,m23+height2),IPL_DEPTH_8U,n_channel); // попытка выделить минимальный необходимый размер

	cvWarpPerspective(img2,img_out,homography_matrix,CV_WARP_FILL_OUTLIERS,cvScalarAll(0));

	cvSetImageROI(img_out,cvRect(0,0,width1,height1));

	cvCopy(img1,img_out);

	cvResetImageROI(img_out);

	cvSaveImage("out.png", img_out);


	//конец. удаляем все

	cvReleaseImage(&img1);

	cvReleaseImage(&img2);

	//удалить точки и дескрипторы (правильно через cvClearSeq или через cvReleaseMemStorage или cvClearMemStorage?)

	cvClearSeq(Keypoints1);

	cvClearSeq(Keypoints2);

	cvClearSeq(Descriptors1);

	cvClearSeq(Descriptors2);

	cvClearMemStorage(storage);

	cvReleaseMemStorage(&storage); // вроде бы достаточно только этого вместо cvClearSeq и cvClearMemStorage

	return 0;

}[/code]

  • Like 1

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


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

Я еще скидывал спутниковые снимки - вот вы их проверьте ...

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


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

так я про них и говорил.

У меня уже вот этот код дает ошибку, описанную выше (не хватает памяти):


objectGray = cvLoadImage("D:\\IMGS\\LANSAT\\1.bmp", CV_LOAD_IMAGE_GRAYSCALE );

imageGray = cvLoadImage("D:\\IMGS\\LANSAT\\2.bmp", CV_LOAD_IMAGE_GRAYSCALE );


CvMemStorage* storage = cvCreateMemStorage(0);

CvSeq *keys1 = 0, *desc1 = 0;

CvSeq *keys2 = 0, *desc2 = 0;

CvSURFParams paramz = cvSURFParams(500, 1);

cvExtractSURF( objectGray, 0, &keys1, &desc1, storage, paramz);

cvExtractSURF( imageGray, 0, &keys2, &desc2, storage, paramz);

Версия библиотеки OpenCV2.2

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


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

ну так наверно из-за cvExtractSURF

HESSIAN поставьте 6000 вместо 500 например и попробуйте так.

хотя у меня и с 500 работало на opencv2.1 (хотя думаю это не влияет)

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


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

ну так наверно из-за cvExtractSURF

HESSIAN поставьте 6000 вместо 500 например и попробуйте так.

хотя у меня и с 500 работало на opencv2.1 (хотя думаю это не влияет)

Я знаю, что HESSIAN можно и больше поставить, но ведь тогда качество сшивки будет неприемлемым.

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


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

http://opencv.willowgarage.com/documentation/dynamic_structures.html#cvseq

ну чтение из cvSeq вроде так

(desrcriptor->first)->data; // 1 элемент последовательности

((desrcriptor->first)->h_next)->data; // 2 элемент последовательности

только как там эта инфа хранится я не знаю.

и еще я flannFindPairs не проверял и не разбирался взял из каких то примеров. там как раз чтение и сравнение дескрипторов.

а cvExtractSURF надо внутрь лезть смотреть где там выделения памяти такое сильное, но чо то по F10 у меня в функцию не заходит при дебаге(может просто не компилить библиотеку, а тупо подключить сорцы? тогда можно будет и функцию править и при дебаге смотреть)

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


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

http://opencv.willowgarage.com/documentation/dynamic_structures.html#cvseq

ну чтение из cvSeq вроде так

(desrcriptor->first)->data; // 1 элемент последовательности

((desrcriptor->first)->h_next)->data; // 2 элемент последовательности

только как там эта инфа хранится я не знаю.

и еще я flannFindPairs не проверял и не разбирался взял из каких то примеров. там как раз чтение и сравнение дескрипторов.

а cvExtractSURF надо внутрь лезть смотреть где там выделения памяти такое сильное, но чо то по F10 у меня в функцию не заходит при дебаге(может просто не компилить библиотеку, а тупо подключить сорцы? тогда можно будет и функцию править и при дебаге смотреть)

flannFindPairs() глянул мельком. А вот насчет того, чтобы править саму OpenCV у меня опыта маловато :)

А я сейчас другой задачей занимаюсь - пытаюсь открыть большое изображение (~1GB) по частям и потом скормить части cvSetImageData() ...

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


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

хмм IplImage* img= cvCreateImage(cvSize(20000,20000), IPL_DEPTH_8U, 3); так работает, а если ,30к х 30к то уже ошибка.

http://tech.groups.yahoo.com/group/OpenCV/message/55861

тут пишут что может это из-за фрагментации памяти, и надо поправить CV_MAX_ALLOC_SIZE.

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


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

хмм IplImage* img= cvCreateImage(cvSize(20000,20000), IPL_DEPTH_8U, 3); так работает, а если ,30к х 30к то уже ошибка.

http://tech.groups.yahoo.com/group/OpenCV/message/55861

тут пишут что может это из-за фрагментации памяти, и надо поправить CV_MAX_ALLOC_SIZE.

Хм ... возможно это понадобится для cvWarpPerspective(), хотя есть задумка, как обойти проблему - не знаю правильно ли это будет работать, но на крайний случай буду пытаться менять CV_MAX_ALLOC_SIZE и перекомпилировать библиотеку.

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


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

CV_MAX_ALLOC_SIZE я нашел только в cxmisc.h

но чо то сакрального смысла я не понял)

ну там действительно какие то настройки.

/* maximum size of dynamic memory buffer.

   cvAlloc reports an error if a larger block is requested. */

#define  CV_MAX_ALLOC_SIZE    (((size_t)1 << (sizeof(size_t)*8-2)))
а может это надо менять
/* maximal size of local memory storage */

#define  CV_MAX_LOCAL_SIZE  \

    (CV_MAX_LOCAL_MAT_SIZE*CV_MAX_LOCAL_MAT_SIZE*(int)sizeof(double))
cvWarpPerspective() наверно можно и по кускам. Если имеем матрицу гомографии H, то левый верхний варпим по ней, а остальные со смещением относительно левого верхнего.(но надо проверить)
int m13=CV_MAT_ELEM( *homography_matrix, float, 0, 2 );//сдвиг по х

 int m23=CV_MAT_ELEM( *homography_matrix, float, 1, 2 );//сдвиг по у

как определить наклон сторон прямоугольника я пока не понял.

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


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

CV_MAX_ALLOC_SIZE я нашел только в cxmisc.h

но чо то сакрального смысла я не понял)

ну там действительно какие то настройки.

/* maximum size of dynamic memory buffer.

   cvAlloc reports an error if a larger block is requested. */

#define  CV_MAX_ALLOC_SIZE    (((size_t)1 << (sizeof(size_t)*8-2)))
а может это надо менять
/* maximal size of local memory storage */

#define  CV_MAX_LOCAL_SIZE  \

    (CV_MAX_LOCAL_MAT_SIZE*CV_MAX_LOCAL_MAT_SIZE*(int)sizeof(double))
cvWarpPerspective() наверно можно и по кускам. Если имеем матрицу гомографии H, то левый верхний варпим по ней, а остальные со смещением относительно левого верхнего.(но надо проверить)
int m13=CV_MAT_ELEM( *homography_matrix, float, 0, 2 );//сдвиг по х

 int m23=CV_MAT_ELEM( *homography_matrix, float, 1, 2 );//сдвиг по у

как определить наклон сторон прямоугольника я пока не понял.

Насчет CV_MAX_ALLOC_SIZE я тоже не понял, где менять и что. А угол поворота всегда можно узнать, если у нас известны координаты углов.

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


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

(((size_t)1 << (sizeof(size_t)*8-2)))

sizeof(size_t)=32 бита на х32(64 на х64) , 254 (510) бит. чо то до гб как то далековато.

что значит оператор << в данном контексте я вообще не понял.

А угол поворота всегда можно узнать, если у нас известны координаты углов.

нам известна матрица гомографии, и как из не получить координаты углов?

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


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

(((size_t)1 << (sizeof(size_t)*8-2)))

sizeof(size_t)=32 бита на х32(64 на х64) , 254 (510) бит. чо то до гб как то далековато.

что значит оператор << в данном контексте я вообще не понял.

Оператор << это оператор сдвига влево (в гугле есть инфа)

нам известна матрица гомографии, и как из не получить координаты углов?


void GetCorners()

{

	CvPoint src_corners[4] = {

		{0, 0},

		{object->width, 0},

		{object->width, object->height},

		{0, object->height}

	};


	double h[9];

	h[0] = cvmGet(homo, 0, 0); h[1] = cvmGet(homo, 0, 1); h[2] = cvmGet(homo, 0, 2);

	h[3] = cvmGet(homo, 1, 0); h[4] = cvmGet(homo, 1, 1); h[5] = cvmGet(homo, 1, 2);

	h[6] = cvmGet(homo, 2, 0); h[7] = cvmGet(homo, 2, 1); h[8] = cvmGet(homo, 2, 2);


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

	{

		double x = src_corners[i].x, y = src_corners[i].y;


		double Z = 1./(h[6]*x + h[7]*y + h[8]);

		double X = (h[0]*x + h[1]*y + h[2])*Z;

		double Y = (h[3]*x + h[4]*y + h[5])*Z;


		dst_corners[i] = cvPoint(cvRound(X), cvRound(Y));

	}

}

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


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

вообщем попробовал перекомпилировать opencv2.2

(((size_t)1 << (K*(sizeof(size_t)*8-2))))
k пробовал 2,4. походу тут какое то ограничение системы.(типа больше 2-х Гб нельзя на один процесс)
IplImage* img= cvCreateImage(cvSize(30000,20000), IPL_DEPTH_8U, 3);

где то так получается максимум.(на хр, 4 гига, vs 2008, opencv2.2) около 1.8ккк байт.

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


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

допилил внешний RANSAC, с внутренним не разобрался(там даже кол-во итераций и то фиксированное и он встроен в функцию так что там тоже допиливать\переписывать долго да еще и на С)

интересует вопрос о применении RANSAC к сопоставлению точек полученных от SURF,SIFT.

во первых что должно подаваться на вход в RANSAC просто два множества точек? должны ли количества точек в множествах совпадать?

во вторых должны ли эти точки как то быть упорядочены? (например в SURF мы сопоставляем точки по дескрипторам и получаем пары(причем связи могут быть не 1-1, а 1-N ), но потом мы эту информацию(о парах) никак не используем)

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


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

Подкину файлик в тему :)

Язык англ. и пример кода в конце.

RANSAC_outliers_example.pdf

  • Like 1

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


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

еще вопрос преобразование кординат через матрицу гомографии.

прямое (x,y)->(u,v)

u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

попытался из этих соотношений вывести обратное преобразование (u,v)->(x,y)

но то ли я неправильно вывел, то ли ошибки из-за округления получаются слишком большие числа (x,y)

как оно должно выглядеть? или можно просто как то преобразовать саму матрицу(обратную посчитать) не изменяя формулы?

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


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

еще вопрос преобразование кординат через матрицу гомографии.

прямое (x,y)->(u,v)

u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);
v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);[/code] попытался из этих соотношений вывести обратное преобразование (u,v)->(x,y) но то ли я неправильно вывел, то ли ошибки из-за округления получаются слишком большие числа (x,y) как оно должно выглядеть? или можно просто как то преобразовать саму матрицу(обратную посчитать) не изменяя формулы? MAPLE выдает такое (u->U ; v->V) : для X:
[code]x = (-V * m33 * m12 + V * m32 * m13 + m23 * m12 - m22 * m13 + m22 * U * m33 - m23 * U * m32) / (m11 * m22 - m11 * V * m32 - m12 * m21 + m12 * V * m31 - U * m31 * m22 + U * m32 * m21);
для y:
t2 = m11 * V;
t7 = U * m31;
y = -(m11 * m23 - t2 * m33 - m13 * m21 + m13 * V * m31 - t7 * m23 + U * m33 * m21) / (m11 * m22 - t2 * m32 - m12 * m21 + m12 * V * m31 - t7 * m22 + U * m32 * m21);
[/code]

  • Like 1

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


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

У меня такой вопрос:

Есть изображение

imageat.jpg

и матрица предобразования гомографии. Что если мне необходимо трансформировать изображение не всё сразу, а сначалу одну половину, а затем другую ...

Что посоветуете? Думаю, просто смещение по X,Y будет мало?

Вот попробывал сделать нечто подобное:

uploadj.png

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

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×