Меню
Войти Войти
Поиск
Главная
Главная
Категории
Категории
Сообщество
Сообщество
Написать статью
Написать

Как получить изображение с IP камеры в Windows Forms + OpenCV

Как получить изображение с IP камеры в Windows Forms + OpenCV.jpg

В предыдущей статье мы рассмотрели, как связать OpenCV и Windows Forms .NET. Теперь пришло время связать это приложение с IP-камерой.


Что будет представлять из себя приложение

Так, как у меня не получилось получить RTSP поток с помощью библиотеки ffmpeg с моих IP-камер, то был найден оригинальный способ получения изображений с камеры. С помощью функции

URLDownloadToFileA(NULL,LPCSTR(chIpAddress),LPCSTR(filename),0,NULL)==S_OK);
мы скачиваем jpeg изображение с камеры. Например моя камера Arecont Vision AV2105DN отдает jpeg по адресу
http://192.168.1.111/image\?res=full&x0=0&y0=0&x1=1600&y1=1200.jpg
в котором мы можем указать дополнительные параметры, что делает такой способ получения изображений весьма привлекательным. Затем с помощью функции
DeleteUrlCacheEntryA(LPCSTR(chIpAddress));
мы подчищаем кэш и делаем возможным получение свежего кадра.

В итоге мы должны получить изображение с IP-камеры, загрузить его в cv::Mat, затем привести к формату .NET, вывести на PictureBox, в качестве бонуса - запись видео с помощью cv::VideoWriter.

Подготовка проекта

Сначала создадим новый проект Windows Forms и свяжем его с OpenCV, как показано в статье Как создать приложение Windows Forms + OpenCV 2.4.3

Дополнительные зависимости

Помимо этого, добавим:

  1. Выберите Проект → Свойства (Project → Properties)
    • В левой части выберите "Свойства конфигурации" → "Компоновщик" → "Ввод" (Configuration Properties → Linker → Input)
      • В переменную "Дополнительные зависимости" (Additional Dependencies) добавьте:
      • "Wininet.lib Urlmon.lib"

Блок include

В файле form1.h:


#include "Utils.h"
#include 
#include 
#include 
#include 

Добавление элементов

  • В дизайнере формы добавляем элементы PictureBox, Timer, Button, и TextBox для ввода IP-адреса.
  • Действие кнопки


private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
  // Если таймер уже запущен
  if (timer1->Enabled == true){
    // Останавливаем таймер
    timer1->Enabled=false;
    btnStart->Text="Старт";
  // Если таймер остановлен, то запускаем его
  }else{
    // Запускаем таймер
    timer1->Enabled=true;
    btnStart->Text="Стоп";
    checkBox1->Enabled=false;  
  }
}

Действие таймера


private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) {

  // Задаем имя для временного файла (буфер)
  const char *filename = "img.jpg";

  //  Очищаем Image ^img;
  img=nullptr;  

  // Получаем IP-адрес в String ^ipaddress;
  ipaddress=ipAdress->Text;
  // Standard C++ string declaration
  std::string str;  
  // Convert Managed (.Net) String to standard C++ string
  // (Look in the Utils.cpp file of the project)
  ToStdString(ipaddress,str);
  // Convert to const char
  const char *chIpAddress=str.c_str();

  //Если скачивание с камеры успешно, то...
  if (URLDownloadToFileA(NULL,LPCSTR(chIpAddress),LPCSTR(filename),0,NULL)==S_OK){

    //Считываем скаченный кадр с IP-камеры
    cv::Mat frame=cv::imread("img.jpg");
    int size=frame.elemSize();
    int step=frame.step;

    //Преобразуем в .NET
    img = gcnew Bitmap(frame.cols, frame.rows,step,PixelFormat::Format24bppRgb, IntPtr(frame.data));  
      
    //Выводим на pictureBox1
    this->pictureBox1->Image=img;
    this->pictureBox1->Refresh();

    //освобождаем память (не обязательно для cv::Mat)
    //frame.release();

    //Очищаем кэш для следующего кадра
    DeleteUrlCacheEntryA(LPCSTR(chIpAddress));

  //Если не удалось подключиться к камере и получить кадр, то тормозим процесс
  }else{
    timer1->Enabled=false;
    btnStart->Enabled=true;
    btnStart->Text="Старт";
    MessageBox::Show("Не могу подключиться к камере");
    DeleteUrlCacheEntryA(LPCSTR(chIpAddress));    
  }
}

Utils.h

Функции для конвертирования в StdString


#pragma once

#include 

namespace WinformsIPcamera2 {

  using namespace System;

  void ToStdString ( String ^s, std::string& os );
  void ToStdString ( String ^s, std::wstring& os );
}

Utils.cpp


#include "stdafx.h"
#include "Utils.h"

namespace WinformsIPcamera2 {

  void ToStdString ( String ^s, std::string& os )
  {
    using namespace Runtime::InteropServices;
    const char *chars = 
      (const char *)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
    os = chars;
    Marshal::FreeHGlobal(IntPtr((void *)chars));
  }


  void ToStdString ( String ^s, std::wstring& os )
  {
    using namespace Runtime::InteropServices;
    const wchar_t *chars = 
      (const wchar_t *)(Marshal::StringToHGlobalUni(s)).ToPointer();
    os = chars;
    Marshal::FreeHGlobal(IntPtr((void *)chars));
  }
}

Заключение

Вы можете предложить более адекватные способы получения изображений с IP-камеры, с удовольствием размещу ваше решение на этом сайте. Успехов вам в освоении компьютерного зрения и OpenCV!

Источники

  1. http://1-pp.ru

Сводка

  • Авторы: Василий Лазаренко
  • Дата создания: 2013-03-01 13:02
  • Теги: OpenCV Visual studio Windows forms
  • Количество просмотров: 10400
  • Оценить статью:
     
     
     
     
     
  • Всего оценок:  
  • Рейтинг: 13
  • Поделиться:
    Share on Google+Добавить в закладки

0 999 0
OpenCV Visual studio Windows forms

2013-03-01 13:02


Комментарии



Яндекс.Метрика
Статистика
Яндекс.Метрика
Реклама