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

nhr

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

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

  • Посещение

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

  1. Оптический поток

    Пишу программу для определения траекторий движения. Ниже представлен код программы. Проблема в следующем, она написана на С, у меня многие функции просто не воспринимаются. Переписываю под синтаксис С++, что мог, то исправил, помогите исправить оставшееся. Проблема в resize(frame, frame1, Size(200, 200)); не воспринимает frame #include "opencv/cv.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include "opencv2/objdetect/objdetect.hpp" #include <fstream> #include <math.h> #include <stdlib.h> #include <stdio.h> using namespace std; using namespace cv; CvCapture* g_capture = NULL; //IplImage* frame; //IplImage* frame1 = 0; int main(int argc, char** argv) { Mat video, gray, frame, prevgray, flow, cflow; bool frame1 = true; cvNamedWindow("Testing", CV_WINDOW_AUTOSIZE); string fname = "D:/miting_Kharkov.mp4"; // получение следующего кадра while (1) { // получаем следующий кадр VideoCapture cam(fname); cam >> frame; // показываем кадр imshow("Testing", frame); // уменьшаем размер изображения для убыстрения работы if (frame1) { //CvSize c = cvGetSize(frame); //аналоги ли это frame.size() CvSize c = frame.size(); c.height = c.height / 2; c.width = c.width / 2; frame1 = cvCreateImage(c, 8, 3); // серое изображение } resize(frame, frame1, Size(200, 200)); cvtColor(frame1, gray, CV_BGR2GRAY); // вычисление оптического потока if (prevgray.data) { calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2,0); cvtColor(prevgray, cflow, CV_GRAY2BGR); //drawOptFlowMap(flow, cflow, 16, 1.5, CV_RGB(0, 255, 0)); imshow("flow", cflow); } //Ожидание нажатия ESCAPE char c = cvWaitKey(10); if (c == 27) break; //i++; //onTrackbarSlide(i); swap(prevgray, gray); } cvReleaseCapture(&g_capture); cvDestroyWindow("Testing"); return 0; } При отладке выскакивают следующие ошибки: 1>Source.cpp(58): warning C4800: 'IplImage *' : forcing value to bool 'true' or 'false' (performance warning) 1>Source.cpp(62): error C2664: 'void cv::resize(cv::InputArray,cv::OutputArray,cv::Size,double,double,int)' : cannot convert argument 2 from 'bool' to 'cv::OutputArray' 1> Reason: cannot convert from 'bool' to 'const cv::_OutputArray' 1> No constructor could take the source type, or constructor overload resolution was ambiguous 1>Source.cpp(68): error C3861: 'calcOpticalFlowFarneback': identifier not found
  2. Оптический поток

    В общем мне сказали, что надо использовать кластеризацию к-means. Проблема в том, что при реализации, которая представлена ниже выводится только один кадр. Как сделать, чтобы шел непрерывный видеопоток? using namespace std; using namespace cv; void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, double scale, const Scalar& color) { for (int y = 0; y < cflowmap.rows; y += step) for (int x = 0; x < cflowmap.cols; x += step) { const Point2f& fxy = flow.at<Point2f>(y, x); line(cflowmap, Point(x, y), Point(cvRound(x + fxy.x), cvRound(y + fxy.y)), 1); //circle(cflowmap, Point(x, y), 2, color, -1); } } int main(int argc, char** argv) { int s = 2; // масштабирующий коэффициент Mat frame, flow, cflow, bestlabels, centers, dst; Mat img1, img2, img1_gray, img2_gray; Mat framepoints; vector<Vec4i> hierarchy; vector<vector<Point> > contours; vector<vector<Point> > p; Point center; RNG rng(12345); int win_size = 21; string capture = "video1.avi"; VideoCapture cam(capture); if (!(cam.read(frame))) return 0; resize(frame, img1, Size(frame.size().width / s, frame.size().height / s)); cvtColor(img1, img1, CV_BGR2GRAY); while (1) { if (!(cam.read(frame))) break; resize(frame, img2, Size(frame.size().width / s, frame.size().height / s)); cvtColor(img2, img2, CV_BGR2GRAY); calcOpticalFlowFarneback( img1, img2, flow, 0.5, //Определяет масштаб изображения.0.5 означает классическую пирамиду 5, //Количество уровней пирамиды, включая начальное изображение 15, //Средний размер окна 3, //Количество итераций алгоритма на каждом уровне пирамиды 7, //Размер окрестностей пикселей для нахождения расширенного полиномиала(polyN) 1.5, //Стандартное отклонение Гауссиана, которое используется для сглаживания в polyN. Для polyN=5 - polySigma=1.1, для polyN=7 - polySigma=1.5 0 ); cvtColor(img1, cflow, CV_GRAY2BGR); drawOptFlowMap(flow, cflow, 8, 2, CV_RGB(0, 255, 0)); Mat bin(cflow.size(), CV_8UC3); Canny(cflow, bin, 50, 200, 3); //------------------------------------ char c = waitKey(2); if (c == 'c') break; //------------------------------------ imshow("cvCanny", bin); // ищем контуры findContours(bin, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0)); //рисуем контуры Mat drawing = Mat::zeros(bin.size(), CV_8UC3); for (int i = 0; i < contours.size(); i++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point()); } cvtColor(bin, dst, CV_GRAY2BGR); imshow("Contours", drawing); imshow("Testing", cflow); Mat points(drawing.rows * drawing.cols, 3, CV_32F); for (int y = 0; y < drawing.rows; y++) for (int x = 0; x < drawing.cols; x++) for (int z = 0; z < 3; z++) points.at<float>(y + x*drawing.rows, z) = drawing.at<Vec3b>(y, x)[z]; int k = 21; int attempts = 5; Mat centers; kmeans(points, k, bestlabels, TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10000, 0.0001), attempts, KMEANS_PP_CENTERS, centers); Mat clustered(drawing.size(), drawing.type()); for (int y = 0; y < drawing.rows; y++) for (int x = 0; x < drawing.cols; x++) { int cluster_idx = bestlabels.at<int>(y + x*drawing.rows, 0); clustered.at<Vec3b>(y, x)[0] = centers.at<float>(cluster_idx, 0); clustered.at<Vec3b>(y, x)[1] = centers.at<float>(cluster_idx, 1); clustered.at<Vec3b>(y, x)[2] = centers.at<float>(cluster_idx, 2); } clustered.convertTo(clustered, CV_8U); imshow("clustered", clustered); //Ожидание нажатия ESCAPE char c1 = cvWaitKey(10); if (c1 == 27) break; } }
  3. Оптический поток

    using namespace std; using namespace cv; void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, double scale, const Scalar& color) { for (int y = 0; y < cflowmap.rows; y += step) for (int x = 0; x < cflowmap.cols; x += step) { const Point2f& fxy = flow.at<Point2f>(y, x); line(cflowmap, Point(x, y), Point(cvRound(x + fxy.x), cvRound(y + fxy.y)), color); circle(cflowmap, Point(x, y), 2, color, -1); } } int main(int argc, char** argv) { int s = 2; // масштабирующий коэффициент Mat frame, flow, cflow; Mat prvs, next, gray; Mat framepoints; cv::flann::KMeansIndexParams fln_idx = cv::flann::KMeansIndexParams(); cvNamedWindow("Testing", 1); char fname[100] = "miting_Kharkov.mp4"; VideoCapture cam(fname); if (!(cam.read(frame))) return 0; resize(frame, prvs, Size(frame.size().width / s, frame.size().height / s)); cvtColor(prvs, prvs, CV_BGR2GRAY); while (1) { if (!(cam.read(frame))) break; resize(frame, next, Size(frame.size().width / s, frame.size().height / s)); cvtColor(next, next, CV_BGR2GRAY); calcOpticalFlowFarneback( prvs, next, flow, 0.5, //Определяет масштаб изображения.0.5 означает классическую пирамиду 5, //Количество уровней пирамиды, включая начальное изображение 15, //Средний размер окна 3, //Количество итераций алгоритма на каждом уровне пирамиды 7, //Размер окрестностей пикселей для нахождения расширенного полиномиала(polyN) 1.5, //Стандартное отклонение Гауссиана, которое используется для сглаживания в polyN. Для polyN=5 - polySigma=1.1, для polyN=7 - polySigma=1.5 0 ); cvtColor(prvs, cflow, CV_GRAY2BGR); drawOptFlowMap(flow, cflow, 8, 2, CV_RGB(0, 255, 0)); imshow("Testing", cflow); imshow("prvs", prvs); imshow("next", next); Mat centers(flow.size(), 4, CV_32FC1); int count; count = cv::flann::hierarchicalClustering(flow, ceners, fln_idx); //Ожидание нажатия ESCAPE char c = cvWaitKey(10); if (c == 27) break; prvs = next.clone(); } } Вот на данный момент код выглядит так. Функция cv::flann::hierarchicalClustering выделена красным и написано, что что-то не так с параметрами, кстати вот ошибкa: Error 1 error C2783: 'int cv::flann::hierarchicalClustering(const cv::Mat &,cv::Mat &,const cvflann::KMeansIndexParams &)' : could not deduce template argument for 'ELEM_TYPE' D:\Visual Studio 2013\Projects\opticalflow\ConsoleApplication2\Source.cpp 130 1 ConsoleApplication2 и так для каждого аргумента Что надо подкорректировать?
  4. Оптический поток

    Алгоритм к-means подойдет в данном случае?
  5. Оптический поток

    Подскажите, а можно как-нибудь сгруппировать данные снятые оптическим потоком и определить, куда движется объект?
  6. Оптический поток

    Спасибо за столь быстрый ответ. Вот только UMat gray, prevgray, uflow; у меня нет такого оператора
  7. Оптический поток

    Такс, одну ошибку исправил, добавил библиотеку video.hpp и calcOpticalFlowFarneback теперь воспринимается программой.
  8. Ну не знаю, в программке, где я писал классификатор он работает, вот ниже ссылка на него Моя ссылка Я так понимаю, что проблему можно избежать, если накидать больше примеров в классификатор? оттуда и взял txt. А как еще можно классификатор создать, покидайте ссылки
  9. Ошибка вылетает. https://www.dropbox.com/s/oulvn5uhi9xqk2x/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202014-04-14%2017.26.03.png а именно ругается на 89 строку в hog.cpp: CV_Assert( checkDetectorSize() );
  10. параметры были следующие: winsize 32*32, blockStride 4*4, blocksize 8*8, cellsize 8*8, hit 0.9,scale 1.03, thresh 4.0 все остальные стандартные параметры, ничего не менял. Возможно все дело в классификаторе. я его делал через программку, которую isseks написал, здесь на форуме есть ссылка на нее. Вот результат работы: https://www.dropbox.com/s/xuqie16k1eaqd53/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202014-04-14%2016.34.18.png
  11. вот классификатор https://www.dropbox.com/s/3tk7g1u2e160tyc/1.txt и изображение https://www.dropbox.com/s/40p5ccqskqfrzbm/15.jpg а вто оптимальные характеристики hit 0.9 scale 1.03 win 4*4 pad 32*32 thresh 4 blockStride 4*4 blocksize 8*8 cellsize 8*8 Nbins 9 winsigma -1 Detiv Aperature 1
  12. Написал код, по инструкции Nuzhny. Все компилится, но людей не находит, хотя в правильности классификатора уверен std::ifstream clas ("1.txt", std::ifstream::binary); //if (clas) //{ //узнаем длину фаила clas.seekg(0, clas.end); int length = clas.tellg(); clas.seekg(0, clas.beg); char * buffer = new char[length]; cout << "Reading " << length << " characters... "; //считывание данных в виде блока clas.read(buffer, length); if (clas) std::cout << "all characters read successfully.\n"; else std::cout << "error: only " << clas.gcount() << " could be read"; //clas.close(); // текст ХОГа HOGDescriptor hog; //записываем 1.txt в вектор found vector<Rect> found, found_filtered; vector<int> vec; //copy(istream_iterator<Rect>(clas), istream_iterator<Rect> (),back_inserter(found)); std::copy( std::istream_iterator<int>(clas), std::istream_iterator<int>(), std::inserter(vec,vec.begin())); hog.setSVMDetector(vec); fflush(stdout); double t = (double)getTickCount(); Size padding(Size(32, 32)); Size winStride(Size(4, 4)); hog.detectMultiScale(gray, found, 0.9, winStride, padding, 1.03, 4); delete[] buffer; t = (double)getTickCount() - t; printf("tdetection time = %gms\n", t*1000. / cv::getTickFrequency()); std::cout << "found: " << found.size() << std::endl; size_t i, j; for (i = 0; i < found.size(); i++) { Rect r = found[i]; for (j = 0; j < found.size(); j++) if (j != i && (r & found[j]) == r) break; if (j == found.size()) found_filtered.push_back(r); } for (i = 0; i < found_filtered.size(); i++) { Rect r = found_filtered[i]; r.x += cvRound(r.width*0.1); r.width = cvRound(r.width*0.8); r.y += cvRound(r.height*0.07); r.height = cvRound(r.height*0.8); rectangle(gray, r.tl(), r.br(), cv::Scalar(0, 255, 0), 3); } imshow("people detector", gray);
  13. С помощью данной программы написал классификатор, пишу н плюсах, как теперь его скормить HOG ?? Пробовал с помощью svmlight, не получилось. Есть у кого-нибудь наглядные примеры?
  14. А нет ни у кого наглядного примера, как свой классификатор добавить в Hog ну или в каскад Хаара?
  15. Написал я свои классификатор для HOG - 1.txt. Мне его теперь нужно поместить в код, пишу на с++, для с# есть функция ReadAllText(). Какая аналогичная функция есть для с++ ? Лучше всего наглядный пример. Вот код: HOGDescriptor hog; //поиск объекта на изображении метод hog+svm hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); namedWindow("people detector",1 );//CV_WINDOW_AUTOSIZE fflush(stdout); vector<Rect> found, found_filtered; double t = (double)getTickCount(); // детекрирование объектов с параметрами по умолчанию hog.detectMultiScale(gray, found, 0, Size(8, 8), Size(160,160), 1.001, 1.01);
  16. jitDebugging

    Вообщем при попытке скомпилировать приложение, у меня вылезает ошибка, т.е. исключение. Покурив проблему, был найден выход: Нашел я этот конфиг, написал, но без изменений: <?xml version="1.0"?> <configuration> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> </startup> <configuration> <system.windows.forms jitDebugging="false" /> </configuration> </configuration>
  17. jitDebugging

    все, разобрался с ошибкой.
  18. поиск людей, HOG

    В предыдущей теме мне подсказали, что лучше всего для поиска людей в толпе поможет метод HOG Кое-как написал я его, но возникает проблема, что на нужных мне снимках не находит он людей или находит 1 из скажем 20. Что нужно изменить в коде, а то свой собственный классификатор писать не охота. int main(int argc, char** argv) { Mat img, gray, locations, weights; img = imread("image3.jpg", CV_LOAD_IMAGE_UNCHANGED); if (img.empty()) { cout << "Error : Image cannot be loaded..!!" << endl; system("pause"); //wait for a key press return -1; } cvtColor(img, gray, CV_BGR2GRAY);//hog работает только с gray HOGDescriptor hog; //поиск объекта на изображении метод hog+svm hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); namedWindow("people detector", CV_WINDOW_AUTOSIZE); fflush(stdout); vector<Rect> found, found_filtered; double t = (double)getTickCount(); // детектирование объектов с параметрами по умолчанию hog.detectMultiScale(gray, found, 0, Size(8, 8), Size(32, 32), 1.05, 2); t = (double)getTickCount() - t; printf("tdetection time = %gms\n", t*1000. / cv::getTickFrequency()); std::cout << "found: " << found.size() << std::endl; size_t i, j; for (i = 0; i < found.size(); i++) { Rect r = found[i]; for (j = 0; j < found.size(); j++) if (j != i && (r & found[j]) == r) break; if (j == found.size()) found_filtered.push_back(r); } for (i = 0; i < found_filtered.size(); i++) { Rect r = found_filtered[i]; // the HOG detector returns slightly larger rectangles than the real objects. // so we slightly shrink the rectangles to get a nicer output. // сокращение выводимых прямоугольников r.x += cvRound(r.width*0.1); r.width = cvRound(r.width*0.8); r.y += cvRound(r.height*0.07); r.height = cvRound(r.height*0.8); rectangle(gray, r.tl(), r.br(), cv::Scalar(0, 255, 0), 3); } imshow("people detector", gray); waitKey(5000); system("pause"); destroyAllWindows(); return 0; } Картинка, например, такая вот:
  19. поиск людей, HOG

    Появился вопрос, в классификатор добавлять фотографии одинакового размера в плане ширины/высоты ??
  20. поиск людей, HOG

    Ну что же, сначала попробую написать классификатор как можно более полный, результат выложу, как напишу!
  21. поиск людей, HOG

    Если на естественном фоне, то тогда разве программа не станет рабочей только под одну фотографию? Грубо говоря, если шаблоны сделаны с фотографии одной толпы людей, то на данной толпе все будет отлично работать, а если, например, окружающая обстановка сменится, тогда как быть?
  22. поиск людей, HOG

    Я правильно понимаю, что лучше всего, в качестве, шаблонов людей использовать человека на белом фоне?
  23. поиск людей, HOG

    Да, это Невский(: Как переучить, это я понимаю, вот только не совсем понял фразу :"И подавать на классиифиикатор вместо вызова getDefaultPeopleDetector()" Сюда : hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); ??? Т.е. hog.setSVMDetector("мой классификатор")
  24. поиск людей, HOG

    вот на этой фотографии уже 5 "человек" HOG
  25. Доброго времени суток. Пишу программку для распознования людей в толпе. Как мне кажется самый простой из способов, это использовать функцию HoughCircles. Однако возникает проблема, заключающаяся в том, что программа находит много лишнего. Скажите, как можно минимизировать погрешность и оставить только то, что мне нужно?? Может фильтр какой-нибудь есть? int main(int argc, char* argv[]) { Mat img, gray; img = imread("image1.jpg", CV_LOAD_IMAGE_UNCHANGED); if (img.empty()) { cout << "Error : Image cannot be loaded..!!" << endl; system("pause"); //wait for a key press return -1; } namedWindow("original", CV_WINDOW_AUTOSIZE); imshow("original", img); //рисуем рабочую область ROI-------------------------- Rect roi(93, 4, 400, 400); Mat image_roi = img(roi); //---------------------------------------------------- //градация серого cvtColor(image_roi, gray, CV_BGR2GRAY); Mat blurred,blurred1; //GaussianBlur(gray, blurred, Size(5, 5), 0,0,4);// с размытием хуже //imshow("Smoothed Image", blurred); //резкость------------------------------- double delta = 0; int ddepth = -1; float kernel[9]; // увеличение чёткости kernel[0] = -0.1; kernel[1] = -0.1; kernel[2] = -0.1; kernel[3] = -0.1; kernel[4] = 2; kernel[5] = -0.1; kernel[6] = -0.1; kernel[7] = -0.1; kernel[8] = -0.1; // матрица Mat kernel_matrix = Mat(3, 3, CV_32FC1, kernel); filter2D(gray, blurred, ddepth, kernel_matrix, Point(-1, -1)); //imshow("filter2d", blurred); //-------------------------------------- //поиск кругов-------------------------- vector<Vec3f> circles; HoughCircles(blurred, circles, CV_HOUGH_GRADIENT, 10, // разрешение сумматора, используемое для детектирования центров кругов 30, // минимальная дистанция между двумя кругами 60, // верхнее пороговое значение, передаваемое детектору границ Кенни (нижнее пороговое значение будет в 2 раза меньше) 10, // суммирующее пороговое значение детектированя центров 2, 15); // минимальный и максимальный радиус // пробегаемся по кругам и рисуем их на оригинальном изображении for (size_t i = 0; i < circles.size(); i++) { Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); int radius = cvRound(circles[i][2]); // рисуем центр окружности circle(blurred, center, 3, Scalar(0, 255, 255), -1, CV_AA, 0); // рисуем контур окружности circle(blurred, center, radius, Scalar(0, 255, 255), 3, CV_AA, 0); } // показываем---------------------------------------------------- namedWindow("HoughCircles", 1); imshow("HoughCircles", blurred); waitKey(5000); system("pause"); destroyAllWindows(); return 0; } Ну и пример работы:
×