ProgRoman
-
Количество публикаций
190 -
Зарегистрирован
-
Посещение
-
Days Won
7
Сообщения, опубликованные пользователем ProgRoman
-
-
нет он и без обращения падает это я специально проверял
-
Добрый день, я написал свою реализацию расстояния махаланобиса, но проект всё время падает с исключением
Необработанное исключение в "0x751a9617" в "testapp.exe": Исключение Microsoft C++: cv::Exception по адресу 0x0012de30..ниже код моего метода
double calcMah(const Mat &Xk,const Mat &x) { int rw = Xk.rows; int cl = Xk.cols; Mat xm(rw,1,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]; } Mat mv = Mat::ones(rw,cl,CV_64F).mul(xm); Mat Xvg=Xk-mv; Mat cov =Xvg*Xvg.t(); Mat icov = cov.inv(); Mat res = (xm-x)*icov*(xm-x).t(); return res.at<double>(0); }
-
Добрый день, у меня линейно не разделимая выборка данных, для классификации я применяю RBF ядро, но выборка не изменяется т.е. я к каждому елементу вектора применяю RBF ядро и я думал, что выборка изменится будет более линейно разделимой, но получилось, что она не очень-то и разделилась.. подскажите каккие использовать ядра
-
Всем добрый день, у меня такой вопрос есть ли в opencv встроенные функции для оптимизации целевой функции(с ограничениями или без) я искал, но что-то пока безуспешно ни чего не нашёл
-
у меня возник ещё вопрос по выводу формул для SVM в двойственной задачи у целевой функции у меня получается два плюса вот ссылка http://www.machinelearning.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_INCAS там в 1-ой системе целевая функция с обратным знаком взята и знаки самих слагаемых у функции различны, а у меня всё время получаются слагаемые с одинаковыми знаками прикрепляю картинку с тем как я выводил. В чём ошибка что-то разобраться не могу пока..
-
а в реализованной программе параметр С задаётся как
float myC = 100;
-
А ну вообще да вроде бы так логично пасибо вот ещё, что не понятно в задаче есть ограничения
0<=λ<=C, так вот что такое C написано что это параметр алгоритма, ну т.е. его как задавать вообще произвольно или какие-то ограничения на него накладываются. И ещё такой вопрос в самом алгоритме под пунктом 4 стоит решение оптимизационной задачи относительно λs как решать эту задачу я что-то не понимаю и почему там надо вычислять обратную матрицу поясните пожалуйста
-
я пытаюсь реализовать INSAC это алгоритм классифицирующий вектора на два не пересекающихся класса. Он описан в википедии
и там же дана ссылка на конспект лекций Воронцова К.В., в котором тоже этот алгоритм рассмотрен. У меня есть несколько вопросов по этому методу
1.начальное приближение
Is = две ближайшие точки из разных классов
Io = все остальные точки
Ic = 0
Начальное приближение мне ясно там написано как можно его найти к примеру можно так
Выбирается произвольная точка выборки, и находится ближайшая к ней точка другого класса. Для неё, в свою очередь, находится ближайшая точка
в первом классе, и т. д. Этот итерационный процесс, как правило, сходится очень быстро к некоторой паре пограничных точек. Это и есть начальное приближение в этом алгоритме. Вопрос в том влияет ли число опорных точек(векторов) на качество решения.
Далее по алгоритму решается задача оптимизации с матрицей Q, но из чего она состоит...в конспекте лекций приведено следующее
Q=(yiyjK(xi, xj)), i,j=1..L Q размера LxL и вот как я понимаю y - это метка какому классу вектор принадлежит {-1,1}, K(xi, xj) это ядро к примеру евклидово расстояние между i-ым и j-ым вектором т.е. матрица Q - это три столбца первый принадлежность классу второй тоже принадлежность к классу и расстояние между этими векторами поясните пожалуйста что я не так понимаю, в конспекте написано о квадратной матрице, а я не понимаю как я вижу там только три столбца можно даже пример какой-нить что бы разобраться что за матрица
- 1
-
я прикрепил картинку с опорными векторами, на компьютере из дома, странно почему так отличается количество опорных векторов и ещё такой вопрос как найти сами опорные вектора ну я читал в какой-то статье есть два множества(класса) векторов берём произвольный вектор V1 из первого класса и ищем ближайший вектор U1 из второго класса потом берём вектор U1 и ищем ближайший вектор из первого класса и так повторяем несколько раз этот процесс должен стабилизироваться и у нас будут опорные вектора так ли они ищутся или используются какие-то другие методы?
-
-
да мне то же так кажется.
Вот ещё такой вопрос, что такой опорные вектора когда я читал про SVM я понял, что это вектора с наименьшим расстоянием между двумя классами векторов и они уже в дальнейшем и используются для получения гиперплоскости, я дописал код для вывода опорных векторов после обучения ну по нажатию 's'
int bс = svm.get_support_vector_count(); cout<<bс<<"\n"; for(int i=0; i<bс; i++) { const float* v = svm.get_support_vector(i); int x = v[0]; int y = v[1]; circle(img,Point(x,y),5,CV_RGB(255,255,255),1); }
но вид(их расположение) и количество опорных векторов уж больно странное, больно много их как мне кажется скрин экрана я прикрепил, причём это скрин с рабочего компьютера дома у меня на домашнем компьютере их меньше значительно, но всё равно видно на глаз, что там есть вектора не с минимальным расстоянием до другого класса
-
Отсюда ? http://www.compvisio...p?showtopic=404 , хотя похоже только по кнопкам )да вся основа была взята оттуда только переделана под С++ интерфейс вот, оказалось что программа работает правда очень долго минут 45 для 3-х классов в каждом из которых всего 5-ть точек. Но в моей задаче классов не 3-и а около 100-ни я классифицирую изображения..
и такой вопрос как я понимаю
void TrainSVM(void) { int num_sampl = points.size(); float myC = 100; float myGamma = 0.00001; Mat data(num_sampl,num_features,CV_32F); Mat responses(num_sampl,1,CV_32F); for(int i=0; i<num_sampl; i++) { data.at<float>(i,0) = points[i].pt.x; data.at<float>(i,1) = points[i].pt.y; responses.at<float>(i) = points[i].value; } SVMParams params(CvSVM::C_SVC, CvSVM::RBF, 0, myGamma, 0, myC, 0, 0, 0, TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 1000, 1e-6)); svm.clear(); svm.train(&(CvMat)data,&(CvMat)responses,0,0,params); }
в этом коде svm только обучается ну получает опорные вектора, а сама разделяющая гиперплоскость получается из вызова svm.predict(test) или гиперплоскость получается из вызова метода train тоже, тогда не совсем ясно как она хранится, ведь я понимаю благодаря ей распознавание происходит быстро уже по известной гиперплоскости
-
Всем привет, вот пытаюсь разобраться с SVM реализовал его вроде всё работает для двух классов всё считается хорошо, красные точки это 0 класс, зелёные это 1-ый и я ещё добавил ещё один 2-ой класс синие точки они заданы константно в программе
// testApp.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h" #include <cv.hpp> #include <opencv2\opencv.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\ml\ml.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <string> #include <iostream> using namespace std; using namespace cv; Mat img = Mat::zeros(Size(640,480),CV_8UC3); SVM svm; const int num_features = 2; struct TFeature { Point pt;//int pt[num_features]; int value; }; typedef vector<TFeature> TFeatureList; TFeatureList points; void Update(void) { for(int i=0; i<points.size(); i++) { if(points[i].value == 1) { circle(img,points[i].pt,3,CV_RGB(0,255,0),-1); } if(points[i].value == 0) { circle(img,points[i].pt,3,CV_RGB(255,0,0),-1); } if(points[i].value == 2) { circle(img,points[i].pt,3,CV_RGB(0,0,255),-1); } } } void on_mouse(int event, int x, int y, int flags, void* ) { if(img.empty()) return; TFeature pts; if(event == CV_EVENT_LBUTTONDOWN) { pts.pt = Point(x,y); pts.value = 0; points.push_back(pts); img = Mat::zeros(Size(640,480),CV_8UC3);; Update(); } if( event == CV_EVENT_RBUTTONDOWN) { pts.pt = Point(x,y); pts.value = 1; points.push_back(pts); img = Mat::zeros(Size(640,480),CV_8UC3);; Update(); } } void TrainSVM(void) { int num_sampl = points.size(); float myC = 100; float myGamma = 0.00001; Mat data(num_sampl,num_features,CV_32F); Mat responses(num_sampl,1,CV_32F); for(int i=0; i<num_sampl; i++) { data.at<float>(i,0) = points[i].pt.x; data.at<float>(i,1) = points[i].pt.y; responses.at<float>(i) = points[i].value; } SVMParams params(CvSVM::C_SVC, CvSVM::RBF, 0, myGamma, 0, myC, 0, 0, 0, TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 1000, 1e-6)); svm.clear(); svm.train(&(CvMat)data,&(CvMat)responses,0,0,params); } int _tmain(int argc, _TCHAR* argv[]) { img = Mat::zeros(Size(640,480),CV_8UC3); Mat test(1,num_features,CV_32F); namedWindow("SVMDemo",1); setMouseCallback("SVMDemo",on_mouse,0); int c=0; for(; { /*TFeature pts; pts.pt = Point(587,20); pts.value = 2; points.push_back(pts); pts.pt = Point(603,47); pts.value = 2; points.push_back(pts); pts.pt = Point(627,30); pts.value = 2; points.push_back(pts); pts.pt = Point(578,37); pts.value = 2; points.push_back(pts); pts.pt = Point(555,25); pts.value = 2; points.push_back(pts);*/ imshow("SVMDemo",img); c = waitKey(10); if((char)c ==27) break; switch((char)c) { case 's': { if(points.size()>0) { TrainSVM(); for(int x=0;x<640; x++) { for(int y=0; y<480;y++) { test.at<float>(0,0)=x; test.at<float>(0,1)=y; if(svm.predict(test) == 0) { circle(img,Point(x,y),1,CV_RGB(100,0,0),-1); } if(svm.predict(test) == 1) { circle(img,Point(x,y),1,CV_RGB(0,100,0),-1); } /*if(svm.predict(test) == 2) { circle(img,Point(x,y),1,CV_RGB(0,0,100),-1); }*/ Update(); } } } break; }; case 'r': { if(points.size()>0) { img = Mat::zeros(Size(640,480),CV_8UC3); svm.clear(); points.clear(); } break; }; default:; } } svm.clear(); points.clear(); return 0; } [/code] для появления точек третьего класса надо раскоментировать в двух местах
[code] /*TFeature pts; pts.pt = Point(587,20); pts.value = 2; points.push_back(pts); pts.pt = Point(603,47); pts.value = 2; points.push_back(pts); pts.pt = Point(627,30); pts.value = 2; points.push_back(pts); pts.pt = Point(578,37); pts.value = 2; points.push_back(pts); pts.pt = Point(555,25); pts.value = 2; points.push_back(pts);*//*if(svm.predict(test) == 2) { circle(img,Point(x,y),1,CV_RGB(0,0,100),-1); }*/
с двумя классами программа работает, при добавлении третьего всё подвисает и программа вообще ничего не выдаёт, подскажите что не так
вроде бы должен классифицировать больше 2-х классов как написано в документации
Type of SVM. We choose here the type CvSVM::C_SVC that can be used for n-class classification (n>2). This parameter is defined in the attribute CvSVMParams.svm_type.
-
спасибо большое всё действительно получилось
-
Добрый день вот написал вроде бы обычный обработчик тыкаю по изображению мышкой и должны появляться круги разного цвета, но что-то ничего не появляется подскажите что не так
#include "stdafx.h" #include <opencv2/video/tracking.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <ctype.h> using namespace cv; using namespace std; Mat img = Mat::zeros(640,480,CV_8UC3); const int num_features = 2; struct TFeature { Point pt;//int pt[num_features]; int value; }; typedef vector<TFeature> TFeatureList; TFeatureList points; void Update(void) { cout<<"------\n"; for(int i=0; i<points.size(); i++) { if(points[i].value == 0) { circle(img,points[i].pt,3,CV_RGB(0,255,0),1); } else { circle(img,points[i].pt,3,CV_RGB(255,0,0),1); } cout<<i<<" : "<<points[i].pt.x<<" ; "<<points[i].pt.y<<" = "<<points[i].value<<"\n"; } } void on_mouse(int event, int x, int y, int , void* ) { if(img.empty()) return; //if(img.) TFeature pts; if(event == CV_EVENT_LBUTTONDOWN) { pts.pt = Point(x,y); pts.value = 0; points.push_back(pts); img = Mat::zeros(640,480,CV_8UC3); Update(); } if( event == CV_EVENT_RBUTTONDOWN) { pts.pt = Point(x,y); pts.value = 1; points.push_back(pts); img = Mat::zeros(640,480,CV_8UC3); Update(); } } int main( int argc, char** argv ) { namedWindow("test",1); setMouseCallback("test",on_mouse,0); imshow("test",img); waitKey(0); return 0; }
-
Ты в режиме компиляции Debug подключаешь Debug версию OpenCV? А в режиме Release - Release OpenCV?
1. Дело в том, что, например, sizeof(std::vector) в Debug не равен sizeof(std::vector) в Release. Поэтому, если программа и OpenCV скомпилирована по-разному, то при передаче того же std::vector будет ошибка.
2. Ещё один момент: чтобы выделять память в dll, а освобождать её в exe надо использовать один и тот же менеджер памяти. А, значит, надо компилировать и exe и dll из OpenCV с опцией "Multithread debug dll" в Debug режиме и "Multithread dll" в Release.
Почему это важно? Ты передаёшь в функцию поиска контуров пустой std::vector, ожидаешь, что его заполнят точками. То есть при передаче вектора как параметра должно соблюдаться правило (1), а именно sizeof(std::vector) из exe должен быть равен sizeof(std::vector) из dll. Далее вектор заполняется точками, то есть происходит выделение памяти под них внутри dll. А освобождаться эта память будет уже в деструкторе вектора в exe. То есть должно соблюдаться правило (2). Иначе получишь ошибку освобождения памяти - твоя программа упадёт при выходе из функции.
Всё это может быть для тебя не очевидно, да и в учебниках, как правило, не разъясняется. Но по-другому нельзя.
Добрый день, у меня проблема осталась пока не решённой
в проект в дополнительные зависимости я добавляю
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
т.е. как я понял это дебаг версия Opencv, но работает программа в релиз конфигурации в дебаг она вылетает с исключением, что тут может не так быть я пытался
я пытался сделать что бы дебаг версия Opencv работала в дебаг конфигурации, а релиз версия соответственно в релиз конфигурации, сделать это получилось конечно, но при этом с++ интерфейс перестал поддерживаться т.е. он мог считать изображение, но вывести уже нет
Mat ret = imread("1_0.jpg"); imshow("test",ret);
проект выбрасывал исключение
Необработанное исключение в "0x755fb9bc" в "testApp.exe": Исключение Microsoft C++: cv::Exception по адресу 0x0032ea70..
Необработанное исключение в "0x0049ed66" в "testApp.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000018".
с-шный интерфейс работает при этом всё ок.
-
Большое спасибо с вашим примером разобрался полностью
теперь пытаюсь полностью на с++ сделать
Я же в самом начале написал - одинаково компилировать.
я использую Visual Studio 2008 opencv 2.2
на студии создаю проект Консольное приложение Win32 ну а потом присоединяю opencv к проекту и компилирую я думал что он должен бы с++ компилятор использовать
название приложения name.cpp я что-то не знаю где ещё что поменять что бы использовать другой(c++) компилятор
-
У меня контуры почему то всё равно представляются тем маленьким кружочком не знаю что не так и книжку "Learning OpenCV" о контурах про использование флагов читал не понятно где ошибаюсь вывод контуров тот же
// Объявление читалки точек CvSeqReader reader; // Инициализация читалки точек cvStartReadSeq( contour, &reader, 0 ); // Две точки CvPoint pt[2]; for( int i=0; i<contour->total-1; i++ ) { CV_READ_SEQ_ELEM( pt[0], reader ); CV_READ_SEQ_ELEM( pt[1], reader ); cvLine(img12,pt[0],pt[1],CV_RGB(255,0,0),4); }
со всеми флагами и CV_CHAIN_APPROX_NONE и CV_CHAIN_APPROX_SIMPLE получается маленький кружочек внизу изображения, хотя я думал, что должен бы получиться знак..
Раз работает, то первоначальная проблема: разные рантаймы OpenCV и твоего приложения (то есть CRT - C run time).
а как сделать ну что бы они совпадали что бы можно было полностью интерфейсом С++ пользоваться
-
Я почитал ветку форума Работа с контурами
и у меня опять возник вопрос, мне для работы нужны точки координаты контура
// Объявление читалки точек CvSeqReader reader; // Инициализация читалки точек cvStartReadSeq( contour, &reader, 0 ); // Две точки CvPoint pt[2]; for( int i=0; i<contour->total-1; i++ ) { CV_READ_SEQ_ELEM( pt[0], reader ); CV_READ_SEQ_ELEM( pt[1], reader ); cvLine(img12,pt[0],pt[1],CV_RGB(255,0,0),4); }
но контур по этим точкам выводится совсем уж странный
-
написал поиск контуров через С-функции
IplImage* src = cvLoadImage( "C:/images/1_1.jpg", CV_LOAD_IMAGE_GRAYSCALE ); IplImage* src1= cvCreateImage( cvGetSize(src), 8, 1 ); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contour = 0; cvThreshold(src,src1,110,255,CV_THRESH_BINARY); cvNamedWindow( "Source", 1 ); cvShowImage( "Source", src1 ); cvFindContours( src1, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
вроде бы всё замечательно всё работает ну в отличии от С++, но вот что странно, картинку которую я использую для теста я прикрепил к сообщению у меня получаются 10-ть точек контура.. и они расположены практически в одном месте вот вывод точек контураfor( int i=0; i<contour->total; ++i ) { CvPoint* p = (CvPoint*)cvGetSeqElem ( contour, i ); int x = p->x; int y = p->y; circle(ts1,Point(x,y),5,Scalar(100,100,100)); }
-
попробовал подставить, но что-то тоже не пошло.. даже не с компилировалось...
Ошибка 15 general error c101008d: Failed to write the updated manifest to the resource of file
-
изображение грузится canny тоже отрабатывается и можно тоже вывести изображение всё ок ошибка как я понял наверное тут findContours(tsImg,v,CV_RETR_LIST,CV_CHAIN_APPROX_NONE,Point(0,0)); при её выполнении вылетает Нарушение прав доступа при чтении
Тут обязательно твой exe в отладке должен быть собран с отладочными dll из OpenCV и использовать динамические отладочные CRT.В релизе exe должен быть собран с релизными dll из OpenCV и использовать динамические релизные CRT.
Ну и твой exe и OpenCV должны быть собранными компилятором одной версии.
а как это проверить. У меня 2008 студия openCV 2.2 проект собирается ну как написано на страничке opencv добавляю дополнительные зависимости в компоновщик-->Ввод это в свойствах проекта
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
и
затем сервис-> параметры-> каталоги
C:\OpenCV2.2\include
C:\OpenCV2.2\include\opencv
включаемые файлы
C:\OpenCV2.2\lib
файлы библиотек
ну и с самого начала надо ещё debug на release поменять
может я не то написал я не так давно пишу на с++ поэтому извиняюсь)
-
Всем привет у меня такой вопрос пытаюсь на изображении выделить контуры, но постоянно вылетает исключение что-то не понимаю что не так делаю подскажите пожалуйста где ошибаюсь
вот фрагмент кода:
Mat img= imread("C:/images/1.jpg",CV_LOAD_IMAGE_GRAYSCALE); Canny(img,tsImg,20,100); vector<vector<Point>> v; findContours(tsImg,v,CV_RETR_LIST,CV_CHAIN_APPROX_NONE,Point(0,0));
-
Добрый день у меня возникла следующая трудность загружаю цветную картинку далее необходимо работать с цветовыми компонентами отдельно для этого использую split вот код
Mat img= imread("C:/images/1_1.jpg"); Mat chan[3]; Mat zr(img.rows,img.cols,CV_8UC1); zr.zeros(zr.rows,zr.cols,CV_8UC1); split(img,chan); Mat timg(img.rows, img.cols,CV_8UC3); Mat mchan[3]; mchan[0]=chan[0];mchan[1]=em;mchan[2]=em; merge(mchan,3,timg); imshow("2:",timg);
этот код выполняется но если начать выводить каждую компоненту на просмотр т.е. R G и B то он не выводит изображение в оттенках B G и R если выводить только chan то выведется серое изображение вот отсюда я подумал, что возможно что то не так разбивается на каналы может я что-то не то делаю код ниже вообще не работаетMat img= imread("C:/images/1_1.jpg"); vector<Mat> chan; Mat zr(img.rows,img.cols,CV_8UC1); zr.zeros(zr.rows,zr.cols,CV_8UC1); split(img,chan);
тут выбрасывается исключение vector iterator + offset out of range вот.. подскажите пожалуйста что не так я делаю с разбиением изображения на каналы
Mahalanobis
в OpenCV
Опубликовано · Report reply
без вызова этого метода проект работает нормально, поэтому я понял, что наверно проблема в самой функции