Socket、OpenCV、MFC に基づくネットワーク リアルタイム ビデオ監視



1 件の概要

OpenCV はよく知られているクロスプラットフォームのコンピューター ビジョン ライブラリとして、さまざまな分野で使用されていますが、ネットワーク ビデオ監視への適用はほとんどありません。このプロジェクトは OpenCV と Socket を組み合わせ、TCP プロトコルを使用してクライアントからサーバーへのリアルタイムの画像転送を実現し、MFC を UI インターフェイスとして使用します。

この記事では、クライアントとサーバーの設計と実装について、OpenCV 画像処理と Socket ネットワーク接続の側面から紹介します。続いて、この記事では、プロジェクトの MFC インターフェイス設計と、ローカル エリア ネットワークおよびローカル エリア ネットワークでのプログラム テスト結果を紹介します。最後に、この論文では、このプロジェクトの長所と短所を分析します。

2 概要

プロジェクトはクライアントとサーバーの 2 つの部分に分割され、その全体的なフレームワークが図に示されています。クライアントの役割は、リアルタイムの画像情報を収集し、MFC のピクチャー コントロール コントロール画像にリアルタイムで表示し、OpenCV 圧縮エンコーディングを使用して、画像データ ストリームを Socket 経由でサーバーに送信することです。サーバーの役割は、データ ストリームを受信し、受信したデータ ストリームをデコードして表示することです。
このプロジェクトの全体的な枠組み
次に、この記事では主にクライアント側、サーバー側、MFC インターフェイス設計側から詳細に説明します。

3 クライアントの設計と実装

クライアントの主な機能は、カメラから画像ストリームを取得し、それを圧縮してエンコードし、TCP 接続を開始して、データ ストリームを送信することです。以下では、OpenCV 画像処理と Socket ネットワーク通信からそれを実装する方法についてさらに説明します。

3.1 OpenCV 画像処理

クライアント側での OpenCV 画像処理のフローチャートを図に示します。
クライアント画像処理部のフローチャート

3.1.1 cv::VideoCapture クラス

cv::VideoCapture クラスは、ビデオ ファイルからの読み取りをサポートするだけでなく、カメラからの画像ストリームの読み取りもサポートします。その前に、最初に VideoCapture オブジェクトを作成する必要があります。このオブジェクトは、メンバー関数 isOpened() を呼び出して、開封が成功したかどうかを確認し、成功した場合は true を返します。

cv::VideoCapture オブジェクトは、ビデオ ファイル (.mpg または .avi 形式) を呼び出して、次の形式でビデオを読み取ります。

//从视频文件读取
cv::VideoCapture capture(const string& filename);
cv::VideoCapture capture("路径");

cv::VideoCapture オブジェクトはカメラを呼び出して、リアルタイム ビデオ形式を次のように読み取ります。

//从摄像头读取
cv::VideoCapture capture(int device);

このうち、device はカメラの識別子です。カメラが 1 つしかない場合、デバイスには値 0 が割り当てられます。コンピューターに複数のカメラがある場合は、徐々に増やしてください。

デフォルトのカメラを開き、そこから画像ストリームを読み取り、画像ストリームを cv:Mat 画像に割り当てます。そのコード ブロックは次のとおりです。

Mat image; 
VideoCapture capture;
while(capture.isOpened()){
    
    
capture.open(0);
capture >> image;
imshow(image);
waitKey(3);
}

3.1.2 画像圧縮符号化

画像送信の場合、多くのスキームはピクセル送信に基づいています。つまり、送信されるデータのサイズは、画像の解像度とチャネル数に直接等しくなります。解像度 640480 を例に取ると、1 チャンネルのグレースケール画像を送信する場合、1 つの画像で送信されるデータ量は 307200 バイトであり、3 チャンネルの RGB 画像を送信する場合、1 つの画像で 921600 バイトを送信する必要があります。画像には 900,000 バイトを超えるデータ量があり、これは明らかにネットワーク リソースの膨大な浪費です。このピクセルベースの画像伝送を採用すると、ビデオのフリーズが発生しやすくなります。今回は、OpenCV の imencode と imdecode の 2 つの関数を導入して、ピクセルのバイナリ圧縮エンコードとデコードをそれぞれ実行します。

imencode() の定義形式は次のとおりです。

bool imencode(
const String& ext,
InputArray img, 
vector<uchar>& buf,
const vector<int>& params=vector<int>())

各パラメータの説明を表に示します。

パラメータ 説明
外線 出力ファイル形式の拡張子を定義します
画像 エンコードする画像
バフ 出力バッファ
パラメータ エンコード形式と圧縮率

このプロジェクトでは、圧縮率 50% の jpg 形式にエンコードされます。

3.2 ソケットネットワーク通信

ネットワーク通信に関して、このプロジェクトのクライアントは、CAsyncSocket クラスから継承されたカスタム ClientSocket クラスを採用しています。プログラムのフローチャートを下図に示します。
クライアントソケットネットワーク通信部のプログラムフローチャート
ユーザーが MFC インターフェイスから宛先 IP とポート番号を入力し、[接続] ボタンをクリックすると、ClientSocket クラスのオブジェクトが Create() を呼び出してソケットを作成し、Connect() が TCP 接続を開始し、Send() がメッセージを送信します。接続が成功した後、サーバーへのデータ ストリーム。ユーザーが「切断」ボタンをクリックすると、Close() がソケットを閉じ、capture.release() がカメラを閉じます。

4 サーバーサイドの設計と実装

サーバー側の役割は、まずクライアントとの TCP 接続を実現し、クライアントからのデータ ストリームを受信し、リアルタイム画像をデコードして表示することです。そこで、次に筆者はサーバーサイドをSocketネットワーク通信とOpenCV画像処理の2つの側面から紹介します。

4.1 ソケットネットワーク通信

サーバー側のネットワーク通信であるこのプロジェクトでは、CAsyncSocket クラスから継承されたカスタムの ListenSocket クラスと ServerSocket クラスを使用します。これらは、それぞれ監視サービスと接続サービスに使用されます。

サーバーの Socket ネットワーク通信部分のプログラム フロー チャートを図に示します。
サーバー側Socketネットワーク通信部のプログラムフローチャート
ユーザーは、「Local Loopback Test」をクリックして IP アドレスを 127.0.0.1 に設定し、「Get Local IP」をクリックして、マシンの IP アドレスを自動的に取得して設定します。このプロジェクトがローカル IP を自動的に取得する方法は、winsock2.h ライブラリを参照し、gethostname() 関数を呼び出してローカル ホスト名を取得し、gethostbyname() 関数を使用してホスト名を使用して IP を取得します。 . IP アドレスを設定すると、MFC の IP コントロールに表示されます。

IPアドレスとポート番号を設定後、「Open Monitoring」をクリックすると、ListenSocketクラスのオブジェクトがCreate()を呼び出してリスニングソケットを作成します。Listen() は listen 状態に入り、クライアントからの接続要求があるかどうかを検出し、要求がない場合は引き続き listen し、要求があった場合は OnAccept() が要求を受け取り、TCP 接続を実装します。次に、ServerSocket クラスのオブジェクトを使用して Create() を呼び出し、サービス ソケットを作成します. OnReceive() は、クライアントからデータ ストリームを受信します. クライアントが切断されていない場合、リアルタイムの画像データ ストリームを受信し続けます.クライアントが切断されている場合、OnClose( )Disconnect.

サーバーが積極的に切断した場合、つまりユーザーが TCP 接続状態で「切断」をクリックした場合、ListenSocket クラスと ServerSocket クラスのオブジェクトは Close() を呼び出してソケットを閉じ、クライアントから切断します。

4.2 OpenCV 画像処理

サーバー側の画像処理部分は非常にシンプルで、受信したデータストリームを imdecode() でデコードし、デコードされた Mat 型の画像をリアルタイムでウィンドウに表示します。

imdecode() は OpenCV の画像デコード関数です. imencode() とペアで使われます. 圧縮符号化の imencode() 関数は以前紹介しました. imdecode() を紹介しましょう.
imencode() には 2 つのオーバーロードがあります。

Mat imdecode(InputArray buf, int flags)
Mat imdecode(InputArray buf, int flags, Mat* dst)

  • buf: 解凍されたメモリ空間。
  • flags: 色空間、一般的に使用される CV_LOAD_IMOSE_COLOR は 3 チャンネルのカラー画像を参照し、CV_LOAD_IMAGE_GRAYSCALE は単一チャンネルのグレースケール画像を参照します; dst: デコード マトリックスのオプションの出力プレースホルダーで、入力されていない場合は NULL です。

5 MFCインターフェースの設計と解析

5.1 MFC の概要

このプロジェクトの UI インターフェイスは、VCL に似たアプリケーション フレームワークである MFC (Microsoft Foundation Classes、Microsoft Foundation Classes) を使用します。このクラス ライブラリは、開発者が使用する共通の再利用可能なクラス ライブラリのセットを提供し、ほとんどのクラスは CObject から直接的または間接的に派生します。

MFC アプリケーションの全体的な構造は、通常、開発者によって MFC クラスから派生したいくつかのクラスと、CWinApp クラス オブジェクト (アプリケーション オブジェクト) で構成されます。MFC は、MFC AppWizard 自動生成フレームワークを提供します。Windows アプリケーションでは、メインの MFC インクルード ファイルは Afxwin.h です。

5.2 クライアントとサーバーの MFC インターフェイス

クライアントの MFC インターフェイス:
クライアント側 MFC インターフェイス

サーバー側の MFC インターフェイス:
サーバー側 MFC インターフェイス

5.3 詳細分析

プログラムの実用性と堅牢性を向上させるために、このプロジェクトの MFC インターフェイス設計に関する次の 3 つの詳細が導入されています。

まず、画像を表示する機能は OpenCV の imshow() を使用して完成させますが、通常、表示されるウィンドウには別のサブウィンドウがあり、見苦しいだけでなく、使用するのも不便です。したがって、ここでのこのプロジェクトは、OpenCV ウィンドウと MFC ピクチャ コントロールを結合し、画像表示ウィンドウがメイン ウィンドウに埋め込まれていることを実現するものです。関連するコード ブロックは次のとおりです。

//将MFC的IDC_PIC1与OpenCV的src1绑定
CRect rect1;
CWnd* pWnd1 = GetDlgItem(IDC_PIC1);
pWnd1->GetClientRect(&rect1);
namedWindow("src1", WINDOW_AUTOSIZE);
resizeWindow("src1", Size(rect1.Width(), rect1.Height()));
HWND hWnd1 = (HWND)cvGetWindowHandle("src1");
HWND hParent1 = ::GetParent(hWnd1);
::SetParent(hWnd1, GetDlgItem(IDC_PIC1)->m_hWnd);
::ShowWindow(hParent1, SW_HIDE);

次に、現在のプログラムの実行状況をリアルタイムで反映するために、リスト コントロールがインターフェイスに追加されます。たとえば、IP/ポート番号が空の場合、[接続] ボタンをクリックすると、リストに「IP アドレスが空です。ターゲット IP アドレスを入力してください」というメッセージが表示され、カメラの電源を入れると、「カメラサーバーは、リッスンを開始するときにアドレスを出力し、ポート番号とプロンプト「ユーザー接続を待機しています」などを出力します。

第 3 に、プログラムの堅牢性を向上させ、プログラム エラーを防止するために、このプロジェクトでは、コントロール変数を使用して関数 EnableWindow (FALSE/TRUE) を呼び出し、コントロールを有効または無効にし、入力を厳密に制御します。クライアントインターフェースを例にとると、初期インターフェースでは、IPアドレスとポート番号を入力して「接続」ボタンをクリックできますが、「切断」ボタンは灰色でクリックできません。ただし、IP/ポート番号が空の場合、リストバーに「The IP address is empty, please enter the target IP address.」というメッセージが表示されます.TCP 接続が開始されると、IP コントロール、ポート番号の「接続」ボタンが有効になります。をクリックすることができます。

6 プログラムのテスト

6.1 ローカル ループバック テスト

サーバー側で、「ローカル ループバック テスト」をクリックします。つまり、IP アドレスを「127.0.0.1」に設定します。TCP 接続が実現された後、リアルタイムのビデオ伝送は正常であり、ネットワーク監視の基本機能は次のとおりです。ある瞬間の実験結果を図に示します。
ローカル ループバックのある時点でのテスト結果

6.2 LAN下の2台のPCのテスト

2 台のコンピューターを同じ WIFI に接続して、ワイヤレス ローカル エリア ネットワークを形成します。

1 台のコンピューターがサーバー側プログラムを実行し、1 台のコンピューターがクライアント側プログラムを実行します。サーバー側の「Get local IP」をクリックすると、取得したIPアドレスは「192.168.0.103」で、クライアントPCとのTCP接続を実現した後、リアルタイム映像伝送が正常、つまり、ネットワーク監視の基本機能も LAN の下で実現できます。ある時点でのテスト結果は次のとおりです。

LAN の下では、特定の時点でのクライアント側のテスト結果:
LAN でのクライアント テスト結果
LAN の下では、特定の時点でのサーバー側のテスト結果:
LAN下でのサーバー側のテスト結果

7 長所と短所の分析

7.1 このプロジェクトの利点

全体として、このプロジェクトの最大のイノベーションは、OpenCV 画像処理と Socket ネットワーク通信の組み合わせの実現にあります。したがって、このプロジェクトの利点は、基本的に OpenCV の利点に由来します。

まず、このプロジェクトの画像送信前処理では、OpenCV の画像エンコードおよびデコード機能を使用して、従来のピクセルベースの画像送信を置き換えます。これにより、送信データ量が大幅に圧縮され、ネットワーク リソースが解放され、リアルタイムのビデオが作成されます。より効率的に、スムーズに。

第二に、OpenCV には画像解析と処理およびマシン ビジョン機能の豊富なライブラリがあるため、このプロジェクトは、インテリジェントな画像伝送の観点から、二次開発に非常に便利な OpenCV インターフェイスを提供します。例えば、クライアントの画像を収集した後、OpenCV の顔認識機能ライブラリを搭載し、人事情報データベースと組み合わせて、ワーク パンチングや場所の入り口に適したモバイル人事情報をリアルタイムで登録するネットワーク ビデオを作成できます。および出口はすぐに開発することができます. 監視システム.

7.2 改善の余地

作成者のプログラミング能力が限られているため、このプロジェクトにはまだ改善が必要な多くの欠陥があります。

まず、ビデオを送信するとき、受信側 (サーバー側) で画面がぼやけることがあります。これは、このプロジェクトが TCP ネットワーク伝送プロトコルを使用しているためです。
TCP プロトコルは、接続指向で信頼性の高い伝送を提供し、通常、ファイル転送、テキスト転送、電子メールなど、高い精度と低いリアルタイム要件を必要とするシナリオで使用されます。UDP プロトコルは、コネクションレスで信頼性の低いネットワーク伝送を提供します。これは通常、Web サイトでのビデオの視聴、マルチプレイヤー オンライン ゲーム、その他のシナリオなど、データ量は多いが精度要件が低いデータ伝送で使用されます。

TCP と UDP の比較を通じて、UDP プロトコルがネットワーク ビデオ監視により適していることがわかりました。

第二に、プロジェクトは双方向のビデオ伝送を達成できませんでした.双方向のビデオとオーディオの伝送が実現され、ビデオとオーディオの同期とマルチスレッド技術が追加されれば、ネットワークビデオ通話が実現できます.

おすすめ

転載: blog.csdn.net/ZBC010/article/details/127142195