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

tilin

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

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

  • Посещение

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


  1. Проверил у себя - всё нормально (параллельно шагал по кадрам в VirtualDub). Может, видео сжато каким-нибудь потоковым кодеком и capture шагает только по ключевым кадрам? Чисто логически - из-за пути такого быть не может. Сохрани кусочек видео совсем без сжатия (хоть тем же VirtualDub), попробуй так.

    Точно видео. Взял с другим сжатием - от пути не зависит. Но именно с конкретным файлом четко зависит от пути: с коротким именем шагает по кадрам, с длинным - в Windows по 201 кадру, в Linux по 401 кадру. Такой вот прикол.

    Спасибо за помощь.


  2. Во втором случае немного не так как я описал. При полном пути до файла вместо перемещения на 1 кадр происходит перемещение на 201 кадр.

    OpenCV 2.3.1

    Windows 7 и OpenSUSE 11.3 (эффект одинаковый)

    Вот код набросал:

    #include <opencv/cv.h>
    
    #include <SDL.h>
    
    #include "opencv2/video/tracking.hpp"
    
    #include "opencv2/highgui/highgui.hpp"
    
    
    #include <stdio.h>
    
    
    using namespace cv;
    
    
    SDL_Surface* screen;
    
    SDL_Surface* image;
    
    int width;
    
    int height;
    
    CvCapture* capture;
    
    IplImage* frame; 
    
    
    void frameDisplay()
    
    {
    
    	IplImage* frame = cvQueryFrame(capture); 
    
    
    	SDL_Rect dst;
    
    
    	dst.x = 0;
    
    	dst.y = 0;
    
    	dst.w = width;
    
    	dst.h = height;
    
    
    	image->pixels = frame->imageData;
    
    	SDL_BlitSurface(image, NULL, screen, &dst);
    
    	SDL_UpdateRect(screen, dst.x, dst.y, dst.w, dst.h);
    
    	image->pixels = nullptr;
    
    	printf("%f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES));
    
    }
    
    
    
    int main (int argc, char** argv)
    
    {
    
    //	capture = cvCreateFileCapture("10.avi"); // так шагает по 1 кадру
    
    	capture = cvCreateFileCapture("d://10.avi"); // так шагает по 200 кадров
    
    
    	frame = cvQueryFrame(capture); 
    
    	width = frame->width;
    
    	height = frame->height;
    
    
    
    	if (SDL_Init(SDL_INIT_VIDEO) < 0)
    
    		return 0;
    
    
    	SDL_WM_SetCaption("capture - both fields", NULL);
    
    
    	int bpp = 24;
    
    
    	screen = SDL_SetVideoMode(width, height, bpp, SDL_SWSURFACE );
    
    
    	if (screen == NULL)
    
    		return 0;
    
    
    	unsigned int bmask = 0x000000ff;
    
    	unsigned int gmask = 0x0000ff00;
    
    	unsigned int rmask = 0x00ff0000;
    
    	unsigned int amask = 0xff000000;
    
    
    	image = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_DOUBLEBUF, width, height, bpp, rmask, gmask, bmask, amask);
    
    
    	if (image == NULL)
    
    		return 0;
    
    
    	SDL_SetAlpha(image, 0, 0);
    
    
    	bool process = true;
    
    
    	bool keyLeft = false;
    
    	bool keyRight = false;
    
    
    	while (process)
    
    	{
    
    		Sleep(20);
    
    		SDL_Event event;  
    
     		SDL_PollEvent(&event);
    
    		if (event.type == SDL_KEYDOWN)
    
    			switch (event.key.keysym.sym)
    
     			{
    
     				case SDLK_ESCAPE:
    
     					process = false; 
    
     					break;
    
     				case SDLK_LEFT:
    
    					if (!keyLeft)
    
    					{
    
    						keyLeft = true;
    
    						cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES) - 2);
    
    						frameDisplay();
    
    					}
    
     					break;
    
     				case SDLK_RIGHT:
    
    					if (!keyRight)
    
    					{
    
    						keyRight = true;
    
    						cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES));
    
    						frameDisplay();
    
    					}
    
     					break;
    
    				default:
    
    					break;
    
    			}
    
    		if (event.type == SDL_KEYUP)
    
    			switch (event.key.keysym.sym)
    
     			{
    
     				case SDLK_LEFT:
    
    					if (keyLeft)
    
    						keyLeft = false;
    
     					break;
    
     				case SDLK_RIGHT:
    
    					if (keyRight)
    
    						keyRight = false;
    
     					break;
    
    				default:
    
    					break;
    
    			}
    
    	}
    
    
    	return 0;
    
    }


  3. При старте приложения вызывается cvCreateFileCapture. В цикле вызывается cvQueryFrame. При этом видео нормально проигрывается. А при использовании cvSetCaptureProperty с CV_CAP_PROP_POS_FRAMES для перемещения на один кадр вперед/назад поведение зависит от имени файла.

    1. Если имя файла не содержит путь до него (имеет вид: имя.avi), то все нормально.

    2. Если имя файла содержит путь до него (имеет вид: D:\bababa\имя.avi), то cvSetCaptureProperty устанавливает позицию, либо в 0, либо в 201.

    Куда копать, подскажите пожалуйста.

×