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

privetvision

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

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

  • Посещение

  • Days Won

    2

Все публикации пользователя privetvision

  1. Увеличить скорость работы веб-камеры

    В opencv, можно выключить автоэкспозицию, с помощью mCapture.set(CAP_PROP_AUTO_EXPOSURE, -1); И настроить как надо, с помощью: mCapture.set(CAP_PROP_EXPOSURE, -6);
  2. Каким образом можно устранить резкий перепад яркости всего изображения? То есть камера снимает, руку подносим и иногда происходит засвет всего кадра. Как идея была, накапливать кадры и брать среднее, при резком скачке, например при 60% покрытия белыми пикселами. Как правильно сделать?
  3. Контраст изображения

    В c++ так. mCapture.set(CAP_PROP_CONTRAST, 30); mCapture >> mFrame; 30 - значение констраста В питоне константа CAP_PROP_CONTRAST по-другому называется вроде.
  4. Про моменты контура

    1. Центральный момент - это тоже самое, что если построить прямоугольную обводку контура и опустить 2 перпендикуляра из центра каждой стороны и найти пересечение? Как на картинке ниже. 2. Не до конца понимаю, что такое моменты, а статьи не раскрывают до конца сути. Вот есть формула: Понятно, что проходимся в цикле по всем пикселам контура, но не понятно что такое I(x,y) и зачем возводить в степень x и y?
  5. Найти центр ладони

    Как можно найти центр именно ладони, вместо текущего центра всего контура?
  6. Найти центр ладони

    Все-таки я бы хотел вернуться к "Найти наибольшую окружность, вписываемую в найденный контур", каким способом это можно сделать с помощью opencv? upd. Вроде что-то нашел pointPolygonTest, но оно во-первых тормозит, т.к. в цикле обходит все изображение. пробовал только roi контура, но также тормоза. Так как все-таки найти окружность ладони? (При условии поворота руки)
  7. Найти центр ладони

    Возникает проблемка, с тем, что локоть яркче оказывается, чем ладонь... Вот там черная точка радиусом 20 px.
  8. Найти центр ладони

    О, здорово! Как теперь можно получить точку с максимальной яркостью?
  9. Найти центр ладони

    Вот у меня имеется бинаризованное изображение руки mFgImageLab[0], применяю в потоке кадров cv::Mat dist; cv::distanceTransform(mFgImageLab[0], dist, CV_DIST_L2, 3); imshow("lab1", dist); И в итоге, ничего не поменялось. Я так понимаю distanceTransform должен вернуть уровень яркости до ближайшего черного пиксела, но у меня чет ничего не меняется.
  10. Анализ контуров

    1. Как можно различить контур ладони от контура лица (других контуров)? Моменты могут дать площадь, но она сильно варьируется. По дефектным точкам тоже не очень. Гистограмма яркости, если сменится освещение, то все насмарку. 2. Получил контур руки + ладони. Нужна только ладонь, как отрезать остальную часть?
  11. Детектирую руку Хааром, обвожу в прямоугольник, как найти контуры не на всем изображении, а только в этом прямоугольнике?
  12. Пример использования svm

    Скиньте пожалуйста литературы "для чайников с минимум математики" по svm, желательно на русском. Я еще плаванию в этих понятиях... особенно с параметрами в opencv, что где и кому скармливать и какие результаты ожидаем. Что я не понял: Суть метода, сухой текст из википедии мало чем помогает "перевод исходных векторов в пространство более высокой размерности и поиск разделяющей гиперплоскости с максимальным зазором в этом пространстве" ; что из себя представляет процесс обучения системы; как происходит процесс распознавания; что из себя представляет набор данных на котором svm обучается; можно ли использовать для видео потока? Все примеры показаны для картинок. Есть ли у кого, простой пример svm, объясняющий суть метода (на 20 строк, из примеров opencv трудно читать, там во-первых код громоздкий, во-вторых устаревший, часть функции не работает).
  13. Выделение по цвету кожи

    Хотел попробовать по примерам посмотреть работу gmm + em, но на двух примерах стопорится программа после em->train(), оно во-первых выполняется минут 5 и потом стопорится, в чем может быть проблема? Вот код: #include <iostream> #include <set> #include <opencv2/core/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/ml.hpp> #include <opencv/cv.h> using std::string; using std::cout; using std::cerr; using std::endl; using std::flush; using std::vector; using namespace std; using namespace cv; using namespace cv::ml; bool is_black(cv::Vec3b c1) { return c1[0] == 0 && c1[1] == 0 && c1[2] == 0; } std::vector<cv::Vec3b> get_colors(const int n) { vector<cv::Vec3b> vec; vec.push_back(cv::Vec3b(255,0,0)); vec.push_back(cv::Vec3b(0,255,0)); vec.push_back(cv::Vec3b(0,0,255)); vec.push_back(cv::Vec3b(0,255,255)); vec.push_back(cv::Vec3b(255,255,0)); vec.push_back(cv::Vec3b(255,0,255)); for(int i=6; i < n; i++) { cv::Vec3b color(cv::saturate_cast<uchar>(rand()*255), cv::saturate_cast<uchar>(rand()*255), cv::saturate_cast<uchar>(rand()*255)); vec.push_back(color); } return vec; } int main(int argc, char** argv) { string filename = "5.png"; int num_clusters = 15; if(argc > 1 && string(argv[1]) == "help") { cout << "Usage: gmm [data file] [number clusters]" << endl; return EXIT_SUCCESS; } if(argc > 1) filename = string(argv[1]); if(argc > 2) num_clusters = atoi(argv[2]); cv::Mat data = cv::imread(filename); cv::Mat patterns(0,0, CV_32F); for(int r=0; r < data.rows; r++) for(int c=0; c < data.cols; c++) { cv::Vec3b p = data.at<cv::Vec3b>(r,c); if(!is_black(p)) { cv::Mat pat = (cv::Mat_<float>(1,2) << c,r); patterns.push_back(pat); } } const int cov_mat_type = EM::COV_MAT_GENERIC; EM::Params params; params.nclusters = num_clusters; params.covMatType = cov_mat_type; params.termCrit = cv::TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 15000, 1e-6); Ptr<EM> gmm = EM::create(params); cout << "num samples: " << patterns.rows << endl; cv::Mat labels, posterior, logLikelihood; cout << "Training GMM... " << flush; gmm->train(patterns, logLikelihood, labels, posterior, params); cout << "Done!" << endl; cv::Mat display_img(data.size(), CV_8UC3); cv::Mat posterior_img(data.size(), CV_8U); vector<cv::Vec3b> colors = get_colors(num_clusters); // Draw points with labels for(int p=0; p < patterns.rows; p++) { cv::Mat pat = patterns.row(p); int r = pat.at<float>(0,1); int c = pat.at<float>(0,0); display_img.at<cv::Vec3b>(r,c) = colors[labels.at<int>(p,0)]; posterior_img.at<uchar>(r,c) = cv::saturate_cast<uchar>(posterior.at<float>(r,c)*255); } // draw components cv::Mat means = gmm->get<cv::Mat>("means"); vector<cv::Mat> covs = gmm->get<vector<cv::Mat> >("covs"); cv::Mat weights = gmm->get<cv::Mat>("weights"); for(int g=0; g < num_clusters; g++) { double cx = means.at<double>(g, 0); double cy = means.at<double>(g, 1); double w = weights.at<double>(0, g); cv::Mat cov = covs[g]; // draw centroid cv::circle(display_img, cv::Point(cx,cy), 2, cv::Scalar(255,255,255), CV_FILLED); // draw eigenvectors cv::Mat eigVal, eigVec; cv::eigen(cov, eigVal, eigVec); double eigVec1_len = sqrt(eigVal.at<double>(0,0)) * 3; double eigVec1_x = eigVec.at<double>(0,0) * eigVec1_len; double eigVec1_y = eigVec.at<double>(0,1) * eigVec1_len; double eigVec2_len = sqrt(eigVal.at<double>(1,0)) * 3; double eigVec2_x = eigVec.at<double>(1,0) * eigVec2_len; double eigVec2_y = eigVec.at<double>(1,1) * eigVec2_len; cv::line(display_img, cv::Point(cx,cy), cv::Point(cx+eigVec1_x, cy+eigVec1_y), cv::Scalar(255,255,255) ); cv::line(display_img, cv::Point(cx,cy), cv::Point(cx+eigVec2_x, cy+eigVec2_y), cv::Scalar(255,255,255) ); // draw ellipse along eigenvector 1 double angle = atan(eigVec1_y / eigVec1_x) * (180 / M_PI); cv::RotatedRect rect(cv::Point(cx, cy), cv::Size(eigVec1_len, eigVec2_len), angle); double min, max; cv::minMaxLoc(weights, &min, &max); uchar intensity = cv::saturate_cast<uchar>(w * 255.0 / max); cv::ellipse(display_img, rect, cv::Scalar(intensity,intensity,intensity), 1); } cv::namedWindow("display"); cv::namedWindow("posterior"); cv::imshow("display", display_img); cv::imshow("posterior", posterior_img); cv::waitKey(); return EXIT_SUCCESS; } Скрин отладки: А вот второй код, который тоже пробовал, но тоже самое стопорится после train #include <iostream> #include <opencv2/highgui/highgui.hpp> #include "opencv/cv.h" #include "opencv2/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <opencv2/opencv.hpp> #include "opencv2/imgproc.hpp" #include "opencv2/ml.hpp" using namespace std; using namespace cv; using namespace cv::ml; int main() { cv::Mat source = cv::imread("4.png"); //ouput images cv::Mat meanImg(source.rows, source.cols, CV_32FC3); cv::Mat fgImg(source.rows, source.cols, CV_8UC3); cv::Mat bgImg(source.rows, source.cols, CV_8UC3); //convert the input image to float cv::Mat floatSource; source.convertTo(floatSource, CV_32F); //now convert the float image to column vector cv::Mat samples(source.rows * source.cols, 3, CV_32FC1); cv::Mat samples1(source.rows * source.cols, 3, CV_32FC1); int idx = 0; for (int y = 0; y < source.rows; y++) { cv::Vec3f* row = floatSource.ptr<cv::Vec3f > (y); for (int x = 0; x < source.cols; x++) { samples.at<cv::Vec3f > (idx++, 0) = row[x]; } } //we need just 2 clusters EM::Params params(2); params.covMatType = EM::COV_MAT_SPHERICAL; params.termCrit.maxCount = 300; params.termCrit.epsilon = 0.1; params.termCrit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS; //cv::ExpectationMaximization em(samples, cv::Mat(), params); Ptr<EM> em = EM::create(params); em->train(samples); //the two dominating colors cv::Mat means = em->getMeans(); //the weights of the two dominant colors cv::Mat weights = em->getWeights(); //we define the foreground as the dominant color with the largest weight const int fgId = weights.at<float>(0) > weights.at<float>(1) ? 0 : 1; //now classify each of the source pixels idx = 0; for (int y = 0; y < source.rows; y++) { for (int x = 0; x < source.cols; x++) { //classify const int result = cvRound(em->predict(samples.row(idx++))); //get the according mean (dominant color) const double* ps = means.ptr<double>(result, 0); //set the according mean value to the mean image float* pd = meanImg.ptr<float>(y, x); //float images need to be in [0..1] range pd[0] = ps[0] / 255.0; pd[1] = ps[1] / 255.0; pd[2] = ps[2] / 255.0; //set either foreground or background if (result == fgId) { fgImg.at<cv::Point3_<uchar> >(y, x, 0) = source.at<cv::Point3_<uchar> >(y, x, 0); } else { bgImg.at<cv::Point3_<uchar> >(y, x, 0) = source.at<cv::Point3_<uchar> >(y, x, 0); } } } cv::imshow("Means", meanImg); cv::imshow("Foreground", fgImg); cv::imshow("Background", bgImg); cv::waitKey(0); return 0; }
  14. Выделение по цвету кожи

    Нашел вот такую статейку http://www.morethantechnical.com/2013/03/05/skin-detection-with-probability-maps-and-elliptical-boundaries-opencv-wcode/ Что это за метод (как на русском языке называется) и где можно о нем почитать (на русском)?
  15. Автоматический поиск цвета

    Попробовал, тоже самое..
  16. Автоматический поиск цвета

    Код немного устарел, выявлены проблемы с константами EVENT_LBUTTONDOWN и т.д. (используются без CV_) Но главная проблема с отсутствием CvSVM, почему не могу его использовать? Приходится через Ptr<ml::SVM> void find_decision_boundary_SVM( ml::SVM::Params params ) { img.copyTo( imgDst ); Mat trainSamples, trainClasses; prepare_train_data( trainSamples, trainClasses ); // Обучаем классификатор Ptr<ml::SVM> svm = ml::SVM::create(params); svm->train(trainSamples, 0, trainClasses); // Старый вызов //CvSVM svmClassifier( trainSamples, trainClasses, Mat(), Mat(), params ); // Сохраняем обученный классификатор (можно потом его грузить в другой программе) svm->save("Classifier.dat"); Не пойму в чем проблема? Скрин ошибки ниже. Кажись проблема здесь была classes=Mat(labels_vector.size(),1,CV_32FC1); сменить на: classes=Mat(labels_vector.size(),1,CV_32SC1); не врублюсь как пользоваться, если кликаю один раз левой мышкой и один раз правой, то норм, если например 7 раз левой и 7 раз правой то крашит, не понял пока при какой последовательности. И работает как-то странно, выбираю левой мышкой пикселы положительные, а правой отрицательные, в итоге получается хрень.
  17. Выделение по цвету кожи

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

    Что вы можете сказать по поводу вот этого По идеи, это тоже самое, что и кликать мышкой, только здесь упрощенный вариант?
  19. Выделение по цвету кожи

    Читал, но мне все-таки мышкой нельзя выделять. Как это можно сделать "не вручную"?
  20. Вычитание фона

    Не могли бы показать простой пример (без лишнего мусора) на c++ вычитания фона. Как вижу работу алгоритма: есть первый кадр frameBackground без объекта. Далее на сцене появляется новый объект, необходимо показать кадр только с ним. Пример: Пробовал делать так: Mat mMaskMOG; Ptr< BackgroundSubtractor> mpMOG = createBackgroundSubtractorMOG2(); // Получаем первый кадр mCapture >> frameBackground; // Тут мне не очень понятно что происходит mpMOG->apply(frameBackground, mMaskMOG); Цикл получения кадров() { // Получаем кадр mCapture >> frame; // Копируем кадр в vFrameLab с маской, по идеи тут должен отсеяться фон frame.copyTo(vFrameLab, mMaskMOG); // преобразование в CIELAB cvtColor( vFrameLab, vFrameLab, CV_BGR2Lab ); ... } Пока писал пост, нагуглил похожую проблему http://overcram.com/questions/?qid=167068 что надо добавлять 3-ий параметр в mpMOG->apply(vFrame, fgMaskMOG, 0.001); Но я всеравно не понимаю как оно работает. Со временем новые объекты пропадают (видимо заносятся в историю). Мне же надо, чтобы они не пропадали.
  21. Вычитание фона

    Спасибо, тестирую Vibe. Один момент, поясните пожалуйста аргументы конструктора: (int channels, int samples, int pixel_neighbor, int distance_threshold, int matching_threshold, int update_factor): channels - кол-во каналов, это понятно, а вот далее что идет? (перевод на русский не помогло понять)
  22. Выбрал темку интересную: ПО управления компьютером жестами (например показываем два пальца и делаем что-то в ПК, показываем средний палец и ПК выключается). Но застрял, прошу помочь! Дело такое, планируется использовать несколько камер, как я понял для стереозрения и возможности отсечения задних объектов, путем получения их координат. Но сейчас задача стоит такая (пока работа с одной камерой): 1. Получить с нее кадры в потоке; 2. Перевести в CIELAB формат; 3. Поиграться с ползунками L, A, B и выделить цвет кожи; 4. Дальше мне сказали сделать точки на пальцах или что-то в этом роде. Проблемы появились на 3 пункте, на скриншоте видно, что такого же цвета и книги сзади и дверь (правда на скриншоте она как по волшебству решила стать черной, хотя до этого была частями белой), в целом не получается выделить только руку. Подозреваю, что это не проблемой будет, при использовании нескольких камер или я не прав? Каким образом делать детектирование точек на пальцах мне не сказали, побегав по мануалам, пришел к выводу, что надо с контурами возиться, сделал поиск контуров, выбрал самый большой и он цепляется за другие объекты такого же цвета (на скрине видно). При дневном свете, параметры для порога LAB совершенно другие приходится искать, освещенность сильно играет роль. Вопрос как все-таки победить 3 пункт, чтобы нормально выделяло цвет кожи только и не цепляло остальное. И второй вопрос, в каком направлении двигаться, чтобы получить точки на пальцах? (опять же я не понимаю зачем, точнее что дальше после точек). Код: Mat vFrame, vFrameLab, vFrameLabSecond; vector < vector<Point> > vContours; vector<Vec4i> vHierarchy; Rect vRect; mCapture >> vFrame; cvtColor( vFrame, vFrameLab, CV_BGR2Lab ); cvtColor( vFrame, vFrameGRAY, CV_BGR2GRAY ); // этот кадр не используется // размытие по гауссу GaussianBlur( vFrameLab, vFrameLab, cv::Size( mGaussBlur, mGaussBlur ), 0 ); // диапазон для каналов inRange( vFrameLab, cv::Scalar(mLmin, mAmin, mBmin), cv::Scalar(mLmax, mAmax, mBmax), vFrameLab ); inRange( vFrameGRAY, cv::Scalar(mLmin, mAmin, mBmin), cv::Scalar(mLmax, mAmax, mBmax), vFrameGRAY ); // поиск контуров findContours( vFrameLab.clone(), vContours, vHierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE ); // сортировка контуров std::sort( vContours.begin(), vContours.end(), compareContourAreas); // аппроксимация самого большого контура approxPolyDP(Mat(vContours[vContours.size()-1]), vContours[vContours.size()-1], 3, true); // рисуем самый большой контур на оригинальный кадр Scalar vColor( 120, 0, 255 ); drawContours( vFrame, vContours, vContours.size()-1, vColor, CV_FILLED, 8, vHierarchy ); vRect = boundingRect(vContours[vContours.size()-1]); // Прямоугольная обводка контура rectangle(vFrame, vRect, Scalar(0,255,0), 1, 8, 0); ui->openCVviewerOriginal->showImage( vFrame ); ui->openCVviewerLab->showImage( vFrameLab ); ui->openCVviewerGRAY->showImage( vFrameGRAY );
  23. Спасибо, очень хороший пример!
  24. Да-да, вчера читал)) В этой презентации меня насторожил один момент, каким образом применяется адаптивная бинаризация для CIELAB формата? Пробовал не вышло. По поводу контуров нашел вот эту статейку http://locv.ru/wiki/8.6.5_Выпуклость_контура_и_дефекты_выпуклости
  25. По ссылкам прошелся, вот этот пример более менее по коду приятен. http://s-ln.in/2013/04/18/hand-tracking-and-gesture-detection-opencv/ ASM, STASM это ведь все готовые библиотеки? Мне все-таки самому желательно делать, без читов. Пока понял, что надо научиться выделять выпуклый многоугольник по руке, но пока не ясно как.
×