ProgRoman
-
Количество публикаций
190 -
Зарегистрирован
-
Посещение
-
Days Won
7
Сообщения, опубликованные пользователем ProgRoman
-
-
Добрый день разбираюсь с алгоритмом 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-тье изображение везде похоже... хотя должно быть лучше...
-
и у меня возник ещё вопрос для сопоставления дескрипторов я сейчас использую метод ближайших соседей встроенный у flann
int knn=5; FlannBasedMatcher matchr; vector<DMatch> matches; matchr.knnMatch(descriptors1,descriptors2,matches,knn);
он выдаёт ошибку, что может быть не так...
-
Большое спасибо, всё получилось
у меня сейчас такой вопрос, какие пороги надо писать в сифте
SiftFeatureDetector detector();
я пробовал так SiftFeatureDetector detector(40, 70); но никакого drawMatches не отображалось.. наверно пороги нужно брать другие?..
-
а что за либа может быть не подключена.. в доп зависимостях у меня следующие
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>
-
Добрый день, пытался запустить готовые детекторы из примеров, но что-то не особо получилось пример 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
-
минимизируем оценку совмещения двух контуров.
Это полный перебор по всем точкам для выяснения какой дескриптор первой формы лежит ближе ко второй.. вроде бы это n2 n(количество точек на 1-ой и второй форме)без учёта (подсчёта близости самих дескрипторов этих гистограмм) затем по этим совмещённым точкам подсчитывается (энергия) стоимость чем меньше она тем лучше т.е. образы формы очень близки вроде как то так можно...
-
h(i) что мы строим для каждой точки контура и называется как я понял shape context и мы в конце имеем N(пусть 100) этих дескрипторов, которые описывают контур формы дальше если по алгоритму я понял строится весовая матрица и уже находится полное паросочетание с наименьшей стоимостью..
а можно ли как-то использовать эти дескрипторы для сравнения двух форм с помощью к примеру обычных метрик грубо говоря без переупорядочивания элементов гистограмм h(i)
-
т.е. я правильно понимаю пусть у нас есть два изображения, даже лучше контуры с уже выделенными точками одно это Pi а второе это Qj i и j изменяются по количеству точек т.е. от 1 до N для построения Shape context надо для каждой точки первого изображения строить эти окружности и считать количество попавших в сектора точек первого же изображения т.е. это потом разворачивается в матрицу число строк это log( r ) а число столбцов Q условно(обозначения из википедии)) и каждый элемент этой матрицы это и есть количество точек попавших в тот или иной сектор. т.е правильно ли при построении диаграммы для одного изображения второе при этом не используется так
в самой формуле стоит так q-pi или (q )тут просто начальная точка и таким образом получается вектор...
-
Всем привет, вот разбираюсь с алгоритмом Shape context ниже ссылки на него
как я понял действует он следующим образом
1. сперва надо получить контуры изображений, затем из изображения(контура) берутся N точек pi где i = 1 до N
2. для каждой точки строится n-1 вектор
3. для каждой точки pi получить соответствующую гистограмму hi
мне единственно пока не очень понятно как строится эта гистограмма
- 1
-
Спасибо большое, сейчас разбираюсь с shape context и просматриваю SIFT
-
попробовал вроде бы результаты лучше... также картинки очистил от фона т.е. остались только знаки
-
согласен, что такие методы не особо точны
вот ещё по самому методу я при вычислении расстояния вычислял разность между пикселями каждый с каждым
dmj=MIN(dmj,abs(xi-yj))
не стоит ли брать не только разность интенсивностей у пикселей, но и их расположение ну т.е.dmj=MIN(dmj,abs(xi-yj)+abs(i-j))
-
эти результаты уже с приведением изображений в градации серого, при бинаризации почему-то у меня всегда 0 получается....
фон пока не пробовал вычитать..., но я как то думал, что она и так должна бы работать ну пусть хуже чем с контурами объектов, но всё равно должна бы давать какие-то разумные реультаты... а эти что-то не особо понятны...
-
ok, спасибо)
я применяю её для сравнения двух изображений к примеру дорожных знаков, и что-то как то не особо успешно... на одном и том же изображении она даёт 0 в других случаях всё как-то не особо понятно... к примеру при сравнении этой мерой 3-х прикреплённых изображений первые два из одного класса а второе из другого такие результаты
первое с третьим 0.0352941
первое со вторым 0.117647
на мой взгляд это странно я думал для более похожих изображений расстояние будет меньше чем для более отличающихся изображений
-
Добрый день у меня вопрос правильно ли я понял само расстояние как оно считается
Пусть есть два изображения 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; }
похоже ли на правду ну что я реализовал или где-то ошибаюсь?...
-
Спасибо всё действительно работает!)
единственно что-то уж очень долго считает на изображениях
-
-
в маткаде я подобрал точки так что бы обратная матрица к ковариационной была отлична от нуля p1(1,2,3,4);p2(3,5,0,-7); p3(5,-1,11,34);, но у меня в маткаде получился один ответ у программы совсем другой причём если при обращении поставить DECOMP_SVD т.е. Mat icov = cov.inv(DECOMP_SVD); то тоже будет другой ответ... почему что-то не особо ясно.. может ошибка где-то в функции махаланоблиса, которую я написал...
-
ну да вроде бы со средний всё нормально... считается средний вектор его размерность будет 4 строки 1 столбец вроде всё так..
-
почему не то у меня 4 это размерность пространства т.е. точка в R4 вот всего 2-е точки т.е. первая p1(1,2,3,4); p2(3,5,0,7), ну и точка для тестирования это x1(1,2,3,4)
-
сейчас проверил в маткаде определитель ковариационной матрицы равен 0, что-то как не изменяю матрицу X он всё равно 0
-
пробовал сперва брать просто придуманные вектора, но тоже ничего хорошего (матрица обратная к ковариационной тоже нулевая)
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);
-
я для тестирования использую базу данных изображений, пока просто матрица состоит из 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;
-
С исключением разобрался вот нормальный код без исключений, только вот сейчас непонятно почему матрица обратная ковариационной у меня всегда получается нулевой..
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); }
Retinex
в OpenCV
Опубликовано · Report reply
изображения переводятся в вещественный тип
img.convertTo(ts,CV_64FC3,1.0/255.0);
и все действия происходят уже в нём...