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

ProgRoman

Пользователи
  • Количество публикаций

    190
  • Зарегистрирован

  • Посещение

  • Days Won

    7

Сообщения, опубликованные пользователем ProgRoman


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

    Лекции по обработке изображений

    
    Mat msRetinex(const Mat &img)
    
    {	
    
    	Mat ims = img.clone();
    
    	Mat t1,t2,t3;
    
    
    	int sm = MIN(ims.size().height,ims.size().width);
    
    	if(!(sm%2))sm--;
    
    
    	GaussianBlur(ims,t1,Size(sm,sm),sm/1);
    
    	GaussianBlur(ims,t2,Size(sm,sm),sm/2);
    
    	GaussianBlur(ims,t3,Size(sm,sm),sm/3);
    
    
    	Mat l1,l2,l3,l4;
    
    	log(ims,l1);log(t1,l2);log(t2,l3);log(t3,l4);
    
    
    	Mat tr = (3*l1 - l2-l3-l4)/3;
    
    
    	return tr;
    
    }
    
    

    возможно надо применять другие размеры ядра или sigma брать другую...

    ниже прикреплены фото с результатами работы алгоритма 1-ое фото оригинальное изображение затем фото обработанное Single Retinex и 3-тье обработанное Multi Retinex... визуально 2-ое и 3-тье изображение везде похоже... хотя должно быть лучше...

    post-2515-0-13536400-1332502830_thumb.jp

    post-2515-0-12407300-1332502852_thumb.jp

    post-2515-0-56034400-1332502862_thumb.jp

    post-2515-0-88044700-1332502872_thumb.jp

    post-2515-0-18969600-1332502947_thumb.jp


  2. и у меня возник ещё вопрос для сопоставления дескрипторов я сейчас использую метод ближайших соседей встроенный у flann

    
            int knn=5;
    
            FlannBasedMatcher matchr;
    
    	vector<DMatch> matches;
    
    	matchr.knnMatch(descriptors1,descriptors2,matches,knn);
    
    

    он выдаёт ошибку, что может быть не так...


  3. Большое спасибо, всё получилось

    у меня сейчас такой вопрос, какие пороги надо писать в сифте

    SiftFeatureDetector detector();

    я пробовал так SiftFeatureDetector detector(40, 70); но никакого drawMatches не отображалось.. наверно пороги нужно брать другие?..


  4. а что за либа может быть не подключена.. в доп зависимостях у меня следующие

    C:\OpenCV2.2\lib\opencv_core220d.lib

    C:\OpenCV2.2\lib\opencv_highgui220d.lib

    C:\OpenCV2.2\lib\opencv_video220d.lib

    C:\OpenCV2.2\lib\opencv_ml220d.lib

    C:\OpenCV2.2\lib\opencv_legacy220d.lib

    C:\OpenCV2.2\lib\opencv_imgproc220d.lib

    а в инклудах

    
    #include <stdio.h>
    
    #include <opencv2/core/core.hpp>
    
    #include <opencv2/features2d/features2d.hpp>
    
    #include <opencv2/highgui/highgui.hpp>
    
    


  5. Добрый день, пытался запустить готовые детекторы из примеров, но что-то не особо получилось пример matcher_simple.cpp

    ниже тот же код что и в примере

    
    #include <stdio.h>
    
    #include <opencv2/core/core.hpp>
    
    #include <opencv2/features2d/features2d.hpp>
    
    #include <opencv2/highgui/highgui.hpp>
    
    
    using namespace cv;
    
    
    void help()
    
    {
    
    	printf("\nThis program demonstrates using features2d detector, descriptor extractor and simple matcher\n"
    
    			"Using the SURF desriptor:\n"
    
    			"\n"
    
    			"Usage:\n matcher_simple <image1> <image2>\n");
    
    }
    
    
    int main(int argc, char** argv)
    
    {
    
    	if(argc != 3)
    
    	{
    
    		help();
    
    		return -1;
    
    	}
    
    
    	Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    
    	Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
    
    	if(img1.empty() || img2.empty())
    
    	{
    
    		printf("Can't read one of the images\n");
    
    		return -1;
    
    	}
    
    
    	// detecting keypoints
    
    	SurfFeatureDetector detector();
    
    	vector<KeyPoint> keypoints1, keypoints2;
    
    	detector.detect(img1, keypoints1);
    
    	detector.detect(img2, keypoints2);
    
    
    	// computing descriptors
    
    	SurfDescriptorExtractor extractor;
    
    	Mat descriptors1, descriptors2;
    
    	extractor.compute(img1, keypoints1, descriptors1);
    
    	extractor.compute(img2, keypoints2, descriptors2);
    
    
    	// matching descriptors
    
    	BruteForceMatcher<L2<float> > matcher;
    
        vector<DMatch> matches;
    
        matcher.match(descriptors1, descriptors2, matches);
    
    
    	// drawing the results
    
    	namedWindow("matches", 1);
    
    	Mat img_matches;
    
    	drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
    
    	imshow("matches", img_matches);
    
    	waitKey(0);
    
    
    	return 0;
    
    }
    
    
    получил следующую ошибку
    Ошибка 2 error C2228: выражение слева от ".detect" должно представлять класс, структуру или объединение c:\documents and settings\мои документы\visual studio 2010\projects\testsapp\testsapp\testsapp.cpp 40 1 testsApp
    после исправления, исправленный код ниже
    
    	// detecting keypoints
    
    	SurfFeatureDetector  detector();
    
    	vector<KeyPoint> keypoints1, keypoints2;
    
    	detector().detect(img1, keypoints1);
    
    	detector().detect(img2, keypoints2);
    
    
    	// computing descriptors
    
    	SurfDescriptorExtractor extractor();
    
    	Mat descriptors1, descriptors2;
    
    	extractor().compute(img1, keypoints1, descriptors1);
    
    	extractor().compute(img2, keypoints2, descriptors2);
    
    
    	// matching descriptors
    
    	BruteForceMatcher<L2<float> > matcher();
    
        vector<DMatch> matches;
    
        matcher().match(descriptors1, descriptors2, matches);
    
    
    	// drawing the results
    
    	namedWindow("matches", 1);
    
    	Mat img_matches;
    
    	drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
    
    	imshow("matches", img_matches);
    
    	waitKey(0);
    
    

    получил следующую ошибку

    Ошибка 2 error LNK2019: ссылка на неразрешенный внешний символ "void __cdecl cv::drawMatches(class cv::Mat const &,class std::vector<class cv::KeyPoint,class std::allocator<class cv::KeyPoint> > const &,class cv::Mat const &,class std::vector<class cv::KeyPoint,class std::allocator<class cv::KeyPoint> > const &,class std::vector<struct cv::DMatch,class std::allocator<struct cv::DMatch> > const &,class cv::Mat &,class cv::Scalar_<double> const &,class cv::Scalar_<double> const &,class std::vector<char,class std::allocator<char> > const &,int)" (?drawMatches@cv@@YAXABVMat@1@ABV?$vector@VKeyPoint@cv@@V?$allocator@VKeyPoint@cv@@@std@@@std@@01ABV?$vector@UDMatch@cv@@V?$allocator@UDMatch@cv@@@std@@@4@AAV21@ABV?$Scalar_@N@1@4ABV?$vector@DV?$allocator@D@std@@@4@H@Z) в функции _wmain c:\documents and settings\мои документы\visual studio 2010\Projects\testsApp\testsApp\testsApp.obj testsApp


  6. минимизируем оценку совмещения двух контуров.

    Это полный перебор по всем точкам для выяснения какой дескриптор первой формы лежит ближе ко второй.. вроде бы это n2 n(количество точек на 1-ой и второй форме)без учёта (подсчёта близости самих дескрипторов этих гистограмм) затем по этим совмещённым точкам подсчитывается (энергия) стоимость чем меньше она тем лучше т.е. образы формы очень близки вроде как то так можно...


  7. h(i) что мы строим для каждой точки контура и называется как я понял shape context и мы в конце имеем N(пусть 100) этих дескрипторов, которые описывают контур формы дальше если по алгоритму я понял строится весовая матрица и уже находится полное паросочетание с наименьшей стоимостью..

    а можно ли как-то использовать эти дескрипторы для сравнения двух форм с помощью к примеру обычных метрик грубо говоря без переупорядочивания элементов гистограмм h(i)


  8. т.е. я правильно понимаю пусть у нас есть два изображения, даже лучше контуры с уже выделенными точками одно это Pi а второе это Qj i и j изменяются по количеству точек т.е. от 1 до N для построения Shape context надо для каждой точки первого изображения строить эти окружности и считать количество попавших в сектора точек первого же изображения т.е. это потом разворачивается в матрицу число строк это log( r ) а число столбцов Q условно(обозначения из википедии)) и каждый элемент этой матрицы это и есть количество точек попавших в тот или иной сектор. т.е правильно ли при построении диаграммы для одного изображения второе при этом не используется так

    в самой формуле стоит так q-pi или (q )тут просто начальная точка и таким образом получается вектор...


  9. Всем привет, вот разбираюсь с алгоритмом Shape context ниже ссылки на него

    Shape context Wiki

    Matching with Shape Contexts

    Shape context

    как я понял действует он следующим образом

    1. сперва надо получить контуры изображений, затем из изображения(контура) берутся N точек pi где i = 1 до N

    2. для каждой точки строится n-1 вектор

    3. для каждой точки pi получить соответствующую гистограмму hi

    мне единственно пока не очень понятно как строится эта гистограмма

    • Like 1

  10. согласен, что такие методы не особо точны

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

    
    dmj=MIN(dmj,abs(xi-yj))
    
    
    не стоит ли брать не только разность интенсивностей у пикселей, но и их расположение ну т.е.
    
    dmj=MIN(dmj,abs(xi-yj)+abs(i-j))
    
    


  11. эти результаты уже с приведением изображений в градации серого, при бинаризации почему-то у меня всегда 0 получается....

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


  12. ok, спасибо)

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

    первое с третьим 0.0352941

    первое со вторым 0.117647

    на мой взгляд это странно я думал для более похожих изображений расстояние будет меньше чем для более отличающихся изображений

    post-2515-0-62687800-1327480226_thumb.jp

    post-2515-0-04721100-1327480273_thumb.jp

    post-2515-0-98388100-1327480320_thumb.jp


  13. Добрый день у меня вопрос правильно ли я понял само расстояние как оно считается

    Пусть есть два изображения X и Y вытягиваем эти два изображения в вектор длина которого пусть N

    H(X,Y)- это расстояние Хаусдорфа,

    H(X,Y)=max(h1,h2)

    h1=maximinj|xi-yj|

    h2=maxjmini|xi-yj|

    то есть само расстояние разница берётся по пикселям изображений ниже приведён код

    
    double calcHausdorff(const Mat &v1,const Mat &v2)
    
    {
    
    	double res=0,h1=-100000,h2=-100000;
    
    	int n=v1.size().area();
    
    
    	//calc h1
    
    	for(int i=0; i<n; i++)
    
    	{
    
    		double xi = v1.at<double>(i);
    
    		double dmj=100000;
    
    		for(int j=0; j<n; j++)
    
    		{
    
    			double yj = v2.at<double>(j);
    
    			dmj=MIN(dmj,abs(xi-yj))
    
    		}
    
    		h1=MAX(h1,dmj);
    
    	}
    
    
    	//calc h2
    
    	for(int j=0; j<n; j++)
    
    	{
    
    		double yj = v2.at<double>(j);
    
    		double dmj=100000;
    
    		for(int i=0; i<n; i++)
    
    		{
    
    			double xi = v1.at<double>(i);
    
    			dmj=MIN(dmj,abs(xi-yj))
    
    		}
    
    		h2=MAX(h2,dmj);
    
    	}
    
    
    	res=MAX(h1,h2);
    
    	return res;
    
    }
    
    

    похоже ли на правду ну что я реализовал или где-то ошибаюсь?...


  14. вот что у меня получилось

    Mat X = (Mat_<double>(4,3)<<1,3,5,22,5,-1,3,20,11,4,-7,34);

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

    post-2515-0-84714500-1326965173_thumb.jp


  15. в маткаде я подобрал точки так что бы обратная матрица к ковариационной была отлична от нуля p1(1,2,3,4);p2(3,5,0,-7); p3(5,-1,11,34);, но у меня в маткаде получился один ответ у программы совсем другой причём если при обращении поставить DECOMP_SVD т.е. Mat icov = cov.inv(DECOMP_SVD); то тоже будет другой ответ... почему что-то не особо ясно.. может ошибка где-то в функции махаланоблиса, которую я написал...


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

    
    Mat X = (Mat_<double>(4,2)<<1,3,2,5,3,0,4,7);
    
    Mat x1 = (Mat_<double>(4,1)<<1,2,3,4);
    
    double d = calcMah(X,x1);
    
    


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

    
    int imSz = 50;// размер изображения для тестирования
    
    	Mat i1 = imread("C:/GTSRB/Final_Train/00000/00000_00026.jpg");//первое изображение из 0-го класса (тренировочное)
    
    	Mat i2 = imread("C:/GTSRB/Final_Train/00000/00005_00029.jpg");//второе изображение из 0-го класса (тренировочное)
    
    	Mat i3 = imread("C:/GTSRB/Final_Train/00016/00006_00028.jpg");//изображение для тестирования
    
    	Mat tst;
    
    
    	Mat tempMt(imSz*imSz,2,CV_64F);
    
            //преобразование перового изображения в вектор и запись в tempMt
    
    	{
    
    		Mat nts;
    
    		Mat rts;
    
    		Mat dts;
    
    		Mat nv(imSz*imSz,1,CV_64F);
    
    
    		cvtColor(i1,nts,CV_BGR2GRAY);
    
    		resize(nts,rts,Size(imSz,imSz));
    
    		rts.convertTo(dts,CV_64F,1.0/255.0);
    
    
    		int dx=-1;
    
    		for (int r=0;r<imSz;r++ )
    
    		{
    
    			for (int c=0;c<imSz;c++)
    
    			{
    
    				dx++;
    
    				nv.at<double>(dx)=dts.at<double>(r,c);
    
    			}
    
    		}
    
    
    		for(int p=0; p<imSz*imSz;p++)
    
    		{
    
    			tempMt.at<double>(p,0)=nv.at<double>(p);
    
    		}		
    
    	}
    
            //преобразование второго изображения в вектор и запись в tempMt
    
    	{
    
    		Mat nts;
    
    		Mat rts;
    
    		Mat dts;
    
    		Mat nv(imSz*imSz,1,CV_64F);
    
    
    		cvtColor(i2,nts,CV_BGR2GRAY);
    
    		resize(nts,rts,Size(imSz,imSz));
    
    		rts.convertTo(dts,CV_64F,1.0/255.0);
    
    
    		int dx=-1;
    
    		for (int r=0;r<imSz;r++ )
    
    		{
    
    			for (int c=0;c<imSz;c++)
    
    			{
    
    				dx++;
    
    				nv.at<double>(dx)=dts.at<double>(r,c);
    
    			}
    
    		}
    
    
    		for(int p=0; p<imSz*imSz;p++)
    
    		{
    
    			tempMt.at<double>(p,1)=nv.at<double>(p);
    
    		}
    
    	}
    
            //преобразование тестового изображения в вектор, запись в tst
    
    	{
    
    		Mat nts;
    
    		Mat rts;
    
    		Mat dts;
    
    		Mat nv(imSz*imSz,1,CV_64F);
    
    
    		cvtColor(i3,nts,CV_BGR2GRAY);
    
    		resize(nts,rts,Size(imSz,imSz));
    
    		rts.convertTo(dts,CV_64F,1.0/255.0);
    
    
    		int dx=-1;
    
    		for (int r=0;r<imSz;r++ )
    
    		{
    
    			for (int c=0;c<imSz;c++)
    
    			{
    
    				dx++;
    
    				nv.at<double>(dx)=dts.at<double>(r,c);
    
    			}
    
    		}
    
    
    		tst = nv.clone();
    
    	}
    
    
    
    	double d = calcMah(tempMt,tst);	
    
    	cout<<d;
    
    


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

    
    double calcMah(const Mat &Xk,const Mat &x)
    
    {
    
    	int rw = Xk.rows;
    
    	int cl = Xk.cols;
    
    	Mat xm(rw,1,CV_64F);
    
    	Mat mv(rw,cl,CV_64F);
    
    
    	//calc mean
    
    	for(int r=0; r<rw; r++)
    
    	{
    
    		Mat tmr = Xk.row(r).clone();
    
    		Scalar sc = mean(tmr);
    
    		xm.at<double>(r) = sc.val[0];
    
    	}		
    
    
    	for(int i=0; i<rw;i++)
    
    	{
    
    		double tempV = xm.at<double>(i);
    
    		for(int j=0; j<cl;j++)
    
    		{
    
    			mv.at<double>(i,j)=tempV;
    
    		}
    
    	}
    
    
    	Mat Xvg=Xk-mv;	
    
    	Mat cov =Xvg*Xvg.t();	
    
    	cout<<cov<<endl;
    
    	Mat icov = cov.inv();
    
    	cout<<icov<<endl;
    
    	Mat diff = xm - x;
    
    	cout<<diff<<endl<<diff.rows<<"  |  "<<diff.cols<<endl;
    
    	Mat res = diff.t()*icov*diff;
    
    
    	return res.at<double>(0);
    
    }
    
    

×