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

Не работает функция cvWriteFrame

Recommended Posts

Помогите разобраться почему не работает программа для записи видео с экрана.Программа компилируется,но при запуске выскакивает исключение System.Runtime.InteropServices.SEHException" в приложении ЗАГОТОВКА_OpenCV_WF.exe

Дополнительные сведения: Внешний компонент создал исключение.

В стеке вызовов: "указанные ниже фреймы могут быть неверны и(или) отсутствовать,символы для opencv_core220d.dll не загружены"

Проверяю frame - через cvShowImage( "original", frame ) - все в порядке.А записываться он не хочет. Вот код

	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
	
				 
	const char *filename = "C:\\Users\\валера\\Pictures\\Video.avi";
 
	
				 Graphics^ graph;			
  Bitmap^ bitmap;
	 //cvNamedWindow("original",CV_WINDOW_AUTOSIZE);
		 bitmap = gcnew Bitmap (Screen::PrimaryScreen->Bounds.Width,Screen::PrimaryScreen->Bounds.Height);  
	  CvSize size = cvSize(Screen::PrimaryScreen->Bounds.Width, Screen::PrimaryScreen->Bounds.Height);
	 
	 CvVideoWriter *writer = cvCreateVideoWriter(filename, CV_FOURCC('D','I','V','X'), 25, size, 1);
       
	 
	 assert(writer!=0);	 
   while(true){
	 
  
    graph = Graphics::FromImage(bitmap);	 
		 graph->CopyFromScreen(0,0,0,0,bitmap->Size); 
System::Drawing::Rectangle Rect(0,0,bitmap->Width,bitmap->Height);
		 
		Bitmap ^ bitmap1 = bitmap->Clone(Rect, Imaging::PixelFormat::Format32bppRgb);


		   System::Drawing::Imaging::BitmapData^ bmData = bitmap->LockBits(
			System::Drawing::Rectangle(0, 0, bitmap1->Width, bitmap1->Height) ,
			System::Drawing::Imaging::ImageLockMode::ReadWrite,bitmap1-> PixelFormat);
		
		    frame = cvCreateImage(cvSize(bitmap1->Width , bitmap1->Height) , IPL_DEPTH_8U , 4);
		frame->imageData = (char*)bmData->Scan0.ToPointer();
			cvNamedWindow("original",CV_WINDOW_AUTOSIZE);	 
             
		
		cvWriteFrame(writer, frame);
				 // cvShowImage( "original", frame );

				  cvWaitKey(5);
   bitmap->UnlockBits(bmData);
   }
				  cvReleaseCapture( &capture );
			 cvReleaseVideoWriter(&writer);
       // cvDestroyWindow("capture");
   
   }

Я в opencv (да и вообще в программировании) новичок, так что не очень критикуйте за допущенные ошибки

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

вопрос решил - 

Format32bppRgb поменял на Format24bppRgb и число каналов в cvCreateImage c 4 на 3

Есть новая проблема - вставил в цикл  для разрыва цикла  

сhar c;

if(c==27)

{ break;}

Не работает. Программа перестает отвечать через пару секунд после нажатия Button. При этом запись успешно продолжается, а остановить получается лишь через Диспетчер устройств

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

С формами такое не работает. Вам нужно сделать нормальный выход из программы, послать сообщение закрытия например.

Цикл крутите отдельным потоком?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вы имеете в виду this->Close()  ?

Я не знаю ,что не работает с формами. Дело в том ,что в моих предыдущих проектах я цикл спокойно разрывал (правда не через break, а через 

button1Click

while(N==k)

{ ...пошел цикл..)

button2_Click { N !=k}

Но сейчас этот метод не работает. Но ведь раньше с opencv на форме работал!

Правда,сам цикл был проще

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Упс, цикл у вас в обработчике нажатия кнопки. Не ну это так не делается. В обработчиках событий должен быть короткий быстро выполняющийся код, ну никак не вечный цикл. То что у вас сделано, это очень плохо. Посмотрите, на форуме есть примеры вывода видео на форму. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо,обязательно посмотрю. И еще один вопрос - у меня первоначально перегружалась память. Я решил в конце каждого цикла ее освобождать через cvReleaseImage. Но получаю ошибку - cvReleaseImage: невозможно преобразовать параметр 1 из "cli::interior_ptr<Type>" в "IplImage **"
Ту я не могу понять в чем дело. ведь frame объявлен как IplImage*frame

Когда я вместо этого написал frame = nullptr - ошибка исчезла.Если можете,объясните,в чем проблема ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не знаю, с cli + IplImage не работал. Может умны указатель убирает сам за собой ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сомневаюсь.что сам убирает, пока frame=nullptr не прописал память переполнялась.К тому же ,не зря ведь функцию cvReleaseImage для освобождения ресурсов в библиотеку добавили  

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Запустил цикл в компоненте BackgroundWorker.Теперь цикл прерывается . Однако закрыть Form не получается, причем не зависает ( в диспетчере задач "Работает",а не "Не отвечает" ).Может мусор за циклом убирается долго ? Или какая может быть причина ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Поток GUI работает в цикле WinMain, там обрабатываются сообщения системы, чтобы закрыть, нужно отправить соответствующее сообщение. Тогда программа завершит этот цикл и теоретически должна закрыться.  Но может надо просто камеру вначале закрыть, она тоже может держать программу. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

У меня не камера ( с камерой у меня было все просто и даже ОТЛИЧНО ).Там захват делал opencv ,а мне оставалось лишь или записать или отправить на форму в picturebox,что тоже не являлось проблемой ). Здесь у меня захват экрана ,передача в opencv и там запись.Но захват экрана происходит в цикле,который теперь (кстати,благодаря Вашей помощи) прерывается по команде. А форма не закрывается и что-то там себе отрабатывает,что хорошо слышно по звуку винта   

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вопрос закрытия приложения решил.Осталась одна проблема,которую решить не получается самому.Почему-то записанное видео имеет скорость значительно выше оригинала. Пробовал менять параметр cvWaitKey, пробовал менять fps - ничего не помогает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Решил проблему скорости.Возможно примитивно,но решение работает. Понимая,что не могу (или еще не умею) увеличить продолжительность воспроизведения каждого frame я решил просто увеличить количество одинаковых frame в каждом цикле.Т.е. в основном цикле создаю внутрений while в котором повторяется одна команда - 

cvWriteFrame(writer, frame);
Количество итераций этого цикла и изменяет скорость  записи-воспроизведения

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

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

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×