Randel
Пользователи-
Количество публикаций
17 -
Зарегистрирован
-
Посещение
Репутация
0 НовичекО Randel
-
Звание
Бывалый
-
Ну вот тут вроде решили эту проблему используя boost'овые треды. Спасибо большое за ссылку и за обсуждение! В результате танцев с бубном, cvWaitKey(), gpu и прочих извращений на основании данного примера цель была условно достигнута. С шести камер (больше в свиче мест нет) идет параллельный захват. Кадров 20 в секунду с каждой есть точно, а большего и не нужно. Я, честно говоря, и не ожидал такого результата. Надеялся на 6-10. Интересно, но, судя по диспетчеру задач, загрузка процессора ~5-6%. Причем, что в отдельном потоке еще и нехитрая обработка идет. Так что boost+opencv это реально быстро Правда, работает все это дело только с камерами в локальной сети. Когда пытаешься использовать какие-нибудь далекие вебки (больше двух штук), то обязательно получаешь исключение в cvQueryFrame, типа "mjpeg overread", "frame bad header". Короче говоря, как я понимаю, битый фрейм приходит. Как это предупредить и обработать я пока не понял...Нужно как-то дропнуть кадр не пытаясь его прочитать. Так что пока работа продолжается, но в общем-то дело с мертвой точки сдвинулось.
-
Полностью согласен! И я бы сделал также. К сожалению, я не настолько силен в программировании, чтобы за обозримый срок написать такой обработчик самостоятельно с нуля. Но я уверен, что несмотря на сложность, задача то должна быть популярной. В той же робототехнике и т.п. Я думал, что уже есть готовые библиотеки, реализующие эти процедуры. Честно говоря, надеялся на opencv . Она же, вроде как, декларирует поддержку нескольких камер. Даже, помню, хелп такой читал...Я думал, что тот же VideoCapture реализует захват в отдельном потоке. Раз есть примеры его использования для стереокамер. Пробовал получать jpeg`и через http, но это получается очень медленно.
-
Добрый день! В программе необходимо работать с кадрами, получаемыми с разных ip камер. Если использовать класс VideoCapture и расширить "канонический" пример: #include "opencv2/opencv.hpp" using namespace cv; int main(int, char**) { VideoCapture cap1("ip-address1"); // open the 1. camera VideoCapture cap2("ip-address2"); // open the 2. camera if(!cap1.isOpened()||!cap2.isOpened()) // check if we succeeded return -1; namedWindow("frame1",1); namedWindow("frame2",1); for(; { Mat frame1, frame2; cap1 >> frame1; // get a new frame from camera cap2 >> frame2; // get a new frame from camera imshow("frame1", frame1); imshow("frame2", frame2); if(waitKey(30) >= 0) break; } // the camera will be deinitialized automatically in VideoCapture destructor return 0; }[/code] То в случае двух камер, приложение еще будет работать, а вот если число камер 3-4 (а вообще-то нужно 10), то через некоторое время программа виснет. Виснет, как я понимаю из-за того, что просто не успевает обрабатывать такой объем данных. Как можно выйти из положения? Первое, что мне пришло на ум - использовать фирменное SDK (в моем случае axis). Там можно ставить потоки на паузу и с помощью этого опрашивать камеры в цикле. Постоянно запуская только один поток. Решение медленное (с 10 камер где-то 3-4 кадра в секунду), но хотя бы рабочее. Но хотелось бы уйти от фирменного SDK и получать фреймы сразу в формате OpenCV. VideoCapture, как я понимаю, не имеет возможности постановки захвата на "паузу". Там нужно останавливать и перезапускать поток. А это очень долго. Как быть? Как организовать такой вот захват с нескольких камер?
-
Всем привет! Вопрос, наверное, несколько простоватый, так что приношу свои извинения! Суть в следующем. Мне нужно внести изменения в исходники. Переписать stitcher.hpp и stitcher.cpp, добавить туда свою функцию. Могу ли я потом пересобрать только эту библиотеку без пересборки всей opencv? Может быть кто-нибудь даст ссылку на инструкцию, как это делать. Потому, что сколько не пытался пересобирать сам с помощью cmake - все время ошибки какие-то. То CUDA не подключится, то еще что-нибудь... А мне по сути-то надо только этот модуль изменить. Как это сделать? P.S. использую VS 2010, opencv 2.4
-
Ну да, я по этому пути и пошел. Времени жрет, естественно, много. А у меня и разрешения большие, да и в динамике надо это все обрабатывать. Короче говоря, буду какой-то другой подход просто применять. Кстати, в развитие темы Я все не могу найти, как средствами opencv произвести само объединение изображений! То есть посчитали гомографию, через findHomograpy, потом warpPerspective, а как потом объединить-то эффективно два изображения (опорное и "warped")?
-
Вот в том-то и дело. И просто так x,y на вход вычислялке не подать. Конечно, есть вариант подать, как в примере, вот эту структуру: KeyPoint kp; kp.angle=0; kp.octave=0; kp.pt.x=c; kp.pt.y=r; kp.size=surfradius; keypoints.push_back(kp); Но это тогда какой-то ущербный кейпойнт. Ведь при сопоставлении точек (и, я так понимаю, вычислении дескрипторов) там же все учитывают. И масштаб, и направление. А тут мы все обнуляем. Нужно как-то детектор принудительно заставить посчитать полную структуру Keypoint для заданной точки. Но, вроде как, такого инструмента нет... Вот, что интересно - по кейпойнту вычисляется дескриптор. Но что тогда дескриптор-то? Просто фрагмент пикселей? Но по теории вот эта вся "требуха" типа направления итп входит именно в дескриптор. Но врядли в opencv все реализовано так, что одно и тоже считается и в кейпойнтах, и в дескрипторах. Скорее всего, например, алгоритм смотрит на октаву кейпойнта и для нее считает дескриптор. Как-то так и для остального. Задавая угол и октаву нулевыми мы повлияем на вычисление дескриптора. И потом их будет просто некорректно сопоставлять. Блин, печаль какая-то... Стоп...а вот у класса KeyPoint есть такой конструктор: KeyPoint(float x, float y, float _size). Это может помочь? Тут просто size зададим от балды, 8, скажем...Интересно, программа рассчитает остальное? Хотя врядли. Если там изначально, например, нет особенности, то что будет записано во все поля?
-
Спасибо, понял! Вот еще хочу задать вопрос. Напишу здесь, чтобы темы не плодить. Если что (дискуссия пойдет), то перенести можно. Можно ли как-то получить Keypoint для заданных координат изображения. Ну, то есть, грубо говоря, нажал на изображение, получил координаты и из них Keypoint каким-нибудь детектором (Surf,Sift...)? Имея кейпойнты уже понятно, как считать дескрипторы и так далее. Но вот как заставить детектор принудительно рассчитать характерную точку?
-
Здравствуйте! Необходимо перевести изображение из контрола pictureBox в cv::Mat. Если кто-нибудь сталкивался, то подскажите пожалуйста, как это проще всего сделать. Спасибо!
-
Здравствуйте! Использую для задачи классификации (2 класса) в том числе метод SVM из opencv. Код: void buildSVM(cv::Mat& setN, cv::Mat& setC, cv::SVM &svm) { Mat responses (setN.rows+setC.rows,1,CV_32S); Mat trainData (setN.rows+setC.rows,setN.cols,CV_32F); for (int i=0;i<setN.rows;i++) { for (int j=0;j<setN.cols;j++) trainData.at<float>(i,j)=setN.at<float>(i,j); responses.at<int>(i,0)=0; } for (int i=0;i<setC.rows;i++) { for (int j=0;j<setC.cols;j++) trainData.at<float>(i+setN.rows,j)=setC.at<float>(i,j); responses.at<int>(i+setN.rows,0)=1; } CvSVMParams params; params.svm_type = SVM::C_SVC; //SVM::NU_SVC; params.kernel_type = CvSVM::RBF; //CV::LINEAR;//CvSVM::POLY; //CvSVM::SIGMOID; svm.train_auto(trainData,responses,Mat(), Mat(), params, 10, CvSVM::get_default_grid(CvSVM::C), CvSVM::get_default_grid(CvSVM::GAMMA), CvSVM::get_default_grid(CvSVM:),CvSVM::get_default_grid(CvSVM::NU), CvSVM::get_default_grid(CvSVM::COEF), CvSVM::get_default_grid(CvSVM::DEGREE),false); }[/code] Так вот, для пары параметров SVM::C_SVC и CvSVM::RBF все прекрасно работает. Аналогично и для SVM::C_SVC + CV::LINEAR, SVM::C_SVC+ CvSVM::SIGMOID; Но по какой-то причине программа падает с "runtime eroor" при попытке построить классификатор типа SVM::NU_SVC с любым ядром. А также вылетает при C_SVC + CV::POLY; Я думал, может причина в типе данных матрицы trainData. Но уже все перепробовал - не помогает. Пробовал разные базы данных - все равно безрезультатно. В чем может быть ошибка?
-
Ага... Я,главное, это же наблюдал, но выводы неправильные сделал! Спасибо за помощь!
-
Добрый день! Может кто-нибудь прояснить ситуацию с обращением матрицы средствами OpenCV...Вот код: Mat VecT(2,1,CV_64F); Mat VecY(2,1,CV_64F); Mat MatSamp (2,2,CV_64F); Mat Covar,Mean,InvCovar; VecT.at<double>(0,0)=28.7; VecT.at<double>(1,0)=16.3; VecY.at<double>(0,0)=64.4; VecY.at<double>(1,0)=21.52; MatSamp.at<double>(0,0)=VecT.at<double>(0,0); MatSamp.at<double>(1,0)=VecT.at<double>(1,0); MatSamp.at<double>(0,1)=VecY.at<double>(0,0); MatSamp.at<double>(1,1)=VecY.at<double>(1,0); calcCovarMatrix(MatSamp,Covar,Mean,CV_COVAR_NORMAL+CV_COVAR_ROWS+CV_COVAR_SCALE); //Covar.at<double>(0,0)=38.44; //Covar.at<double>(0,1)=132.92; //Covar.at<double>(1,0)=132.92; //Covar.at<double>(1,1)=459.67; invert(Covar,InvCovar,DECOMP_SVD); double IC11=InvCovar.at<double>(0,0); double IC12=InvCovar.at<double>(0,1); double IC21=InvCovar.at<double>(1,0); double IC22=InvCovar.at<double>(1,1); Ковариационная матрица считается верно, это я проверял. Но вот ее обращение дает совершенно неправильный реультат (смотрю по IC11-IC22). То есть, единичной матрицы при перемножении Covar*InvCovar не получается. В то же время, если получившиеся значения ковариационной матрицы задать напрямую перед обращением (закомментированные строчки), то обратная матрица рассчитывается абсолютно верно. В чем может быть дело? Интуитивно мне кажется, что что-то не так с типами данных, но что - понять не могу. Подскажите, пожалуйста! *updated: Похоже, дело в том, что при количестве значащих знаков у double-чисел после запятой более трех - детерминант рассчитывается, как нулевой, то есть матрица начинает считаться сингулярной. До трех знаков - все в порядке. Грубо говоря, если подставлять округленные до целых значения - то все считается нормально... Что-то я совсем запутался
-
Еще вопрос появился по feature detectors. Решил здесь написать, чтобы новые темы не плодить. А можно ли как-то задавать "радиус" согласованных характерных точек при матчинге. То есть, чтобы найденные совпадения были преимущественно равномерно распределены по изображению. Иначе, например, в одном углу 100 соответствий, а в других по 2. И это "утянет" в сторону RANSAC при решении системы уравнений. В хэлпе искал - не видел...
-
Точно, спасибо! На 2012 студии пытался использовать либы, созданные под 2010.
-
#include <stdio.h> #include "cv.h" #include "highgui.h" #include "opencv2/opencv.hpp" #include "opencv2/core/core.hpp" #include "opencv2/nonfree/features2d.hpp" #include "opencv2/features2d/features2d.hpp" #include <vector> using namespace std; using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { Mat image = imread( "C:\\input.jpg",0 ); //Загрузить изображение с диска int minHessian = 400; SurfFeatureDetector detector( minHessian ); std::vector<KeyPoint> keypoints; detector.detect(image, keypoints); drawKeypoints(image,keypoints,image,0,0); imshow("image", image ); return 0; } При выполнении данный код, который был взят из примера выдает ошибку "_CrtIsValidHeapPointer(pUserdata)" Причем, если продолжать выполнение программы, то в результате все получится правильно, характерные точки выделятся и будут отображены. Но как победить эту беду?
-
Понятно, но тут вот, что получается. Я переписал весь свой нехитрый "проект" в синтаксисе типа: CvMat *img, *imggauss , *edges; img=cvLoadImageM("input.bmp",0); edges=cvCloneMat(img); imggauss=cvCloneMat(img); cvSmooth(img,imggauss,CV_GAUSSIAN,3,3,1); cvCanny(imggauss,edges,100,20,3); cvShowImage("inputGaus",imggauss); cvShowImage("edges",edges); Все работает без замечаний. Но, ведь, если я правильно понимаю, получается, что я использую старые функции OpenCV, чуть ли не версии 1.1 ? В тоже время, использовать вместо CvMat новый класс Mat, и , соответственно, новые функции у меня не получается: cv::Mat *mat; mat->create(3,3,img->type); Выдает ошибку "Unresolved external cv::Mat::create"