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

nhr

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

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

  • Посещение

Сообщения, опубликованные пользователем nhr


  1. В общем мне сказали, что надо использовать кластеризацию к-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;
    }
    }

  2. 
    
    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
     и так для каждого аргумента

     

    Что надо подкорректировать?


  3. Пишу программу для определения траекторий движения. Ниже представлен код программы. Проблема в следующем, она написана на С, у меня многие функции просто не воспринимаются. Переписываю под синтаксис С++, что мог, то исправил, помогите исправить оставшееся. Проблема в 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


  4. Ну не знаю, в программке, где я писал классификатор он работает, вот ниже ссылка на него

    Моя ссылка

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

    оттуда и взял txt. А как еще можно классификатор создать, покидайте ссылки


  5. параметры были следующие: 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


  6. вот классификатор

    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


  7. Написал код, по инструкции 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);


  8. Написал я свои классификатор для 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);


  9. Вообщем при попытке скомпилировать приложение, у меня вылезает ошибка, т.е. исключение. Покурив проблему, был найден выход:

    Для подключения оперативной (JIT) отладки файл .config данного

    приложения или компьютера (machine.config) должен иметь

    значение jitDebugging, установленное в секции system.windows.forms.

    Приложение также должно быть скомпилировано с включенной

    отладкой.

    Например:

    <configuration>

    <system.windows.forms jitDebugging="true" />

    </configuration>

    При включенной отладке JIT любое необрабатываемое исключение

    пересылается отладчику JIT, зарегистрированному на данном компьютере,

    вместо того чтобы обрабатываться данным диалоговым окном.

    Нашел я этот конфиг, написал, но без изменений:

    <?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>
    
    


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


  11. Да, это Невский(:

    Как переучить, это я понимаю, вот только не совсем понял фразу :"И подавать на классиифиикатор вместо вызова getDefaultPeopleDetector()"

    Сюда : hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); ???

    Т.е. hog.setSVMDetector("мой классификатор")


  12. В предыдущей теме мне подсказали, что лучше всего для поиска людей в толпе поможет метод 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;
    
    }

    Картинка, например, такая вот:

    post-6878-0-99717900-1396262026_thumb.jp

×