セクション2画像とビデオの読み取りと保存
前述のように、OpenCVライブラリのimgcodecsモジュールの画像の読み取り、保存、エンコード、デコード、およびhighguiモジュールの基本的な操作について詳しく説明します。次に、画像や動画へのhighguiモジュールの表示動作について詳しく説明します。
1.画像表示
cv :: imshow:指定したウィンドウに画像を表示します。
void cv :: imshow(const String&winname、InputArray mat)
imshow関数は、指定されたウィンドウに画像を表示します。ウィンドウがcv :: WINDOW_AUTOSIZEフラグで作成されている場合、画像は元のサイズで表示されますが、それでも画面の解像度によって制限されます。それ以外の場合、画像はウィンドウに合わせて拡大縮小されます。この関数は、深度に応じて画像を拡大縮小する場合があります。
- 画像が8ビット符号なしの場合、そのまま表示されます。
- 画像が16ビットの符号なし整数または32ビット整数の場合は、ピクセルを256で除算します。つまり、値の範囲[0,255 * 256]は[0,255]にマップされます。
- 画像が32ビットまたは64ビットの浮動小数点の場合は、ピクセル値に255を掛けます。つまり、値の範囲[0,1]は[0,255]にマップされます。
ウィンドウがOpenGLをサポートして作成されている場合、cv :: imshowはogl :: Buffer、ogl :: Texture2D、およびcuda :: GpuMatも入力としてサポートします。
ウィンドウが作成される前にこの関数が呼び出された場合、cv :: WINDOW_AUTOSIZEを使用して新しいウィンドウが作成されたと見なされます。
画面の解像度よりも大きい画像を表示する必要がある場合は、imshowの前にnamedWindow( ""、WINDOW_NORMAL)を呼び出す必要があります。
注:
この関数の後には、指定されたミリ秒単位で画像を表示するcv :: waitKey関数が続く必要があります。それ以外の場合は、画像が表示されません。たとえば、waitKey(0)は、いずれかのキーが押されるまでウィンドウを無期限に表示します(画像表示に適しています)。waitKey(25)は25ミリ秒の間フレームを表示し、その後、表示は自動的にオフになります。(ビデオを読むためにループに入れると、フレームごとにビデオが表示されます)
Windowsシステムでは、OpenCVは次の操作もサポートしています。
- Ctrl + Cを押して、画像をクリップボードにコピーします。
- Ctrl + Sを押すと、画像を保存するためのダイアログボックスが表示されます。
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 创建窗口
cv::namedWindow("image",cv::WINDOW_NORMAL);
cv::Mat src = cv::imread("d:/develop/machine-vision-workbench/resources/images/f1.jpg");
// 调整窗口大小
cv::resizeWindow("image",640,480);
cv::imshow("image",src);
cv::waitKey();
cv::destroyAllWindows();
return 0;
}
2.ビデオの読み取り、表示、保存
1)、cv :: VideoCapture:ビデオファイル(ローカルまたはネットワークストリーム)、画像シーケンス、およびカメラからビデオをキャプチャするクラス。
-
cv :: VideoCapture()
-
cv :: VideoCapture :: VideoCapture(const String&filename、int apiPreference = CAP_ANY)
-
cv :: VideoCapture :: VideoCapture(int index、int apiPreference = CAP_ANY)
VideoCaptureの2番目と3番目のコンストラクターが頻繁に使用されます。filenameがローカルビデオファイルパスまたはネットワークビデオストリーム(rtsp、rtmp、hlsなど)の場合、パラメータインデックスはローカルカメラデバイスのシリアル番号で、通常は0から始まります。
VideoCaptureは、いくつかのシンプルで効率的な機能を提案しています。
-
cv :: VideoCapture :: get:ビデオの属性を照会します。詳細については、cv :: VideoCapturePropertiesを参照してください。
仮想ダブルcv :: VideoCapture :: get(int propId)const
-
cv :: VideoCapture :: getBackendName:使用されているバックエンドAPIの名前を返します(通常、デフォルトはFFMPGです)
文字列cv :: VideoCapture :: getBackendName()const
-
cv :: VideoCapture :: grab:ビデオファイルまたはカメラデバイスの次のフレームを取得します。成功した場合はtrueを返します。
仮想ブールcv :: VideoCapture :: grab()
この機能の主な用途は、マルチカメラ環境で、特にカメラにハードウェア同期がない場合です。つまり、カメラごとにVideoCapture :: grab()を呼び出してから、低速のメソッドVideoCapture :: retrieve()を呼び出して、各カメラからフレームをデコードして取得します。このようにして、デモザイキングまたはモーションjpeg解凍のオーバーヘッドが排除され、さまざまなカメラから取得されたフレームが時間的に近くなります。
さらに、接続されているカメラがマルチヘッドカメラ(ステレオカメラやKinectデバイスなど)の場合、カメラからデータを取得する正しい方法は、最初にVideoCapture :: grab()を呼び出してから、VideoCapture ::を呼び出すことです。異なるチャネルパラメータを使用したretrieve()値を1回以上。
-
cv :: VideoCapture :: isOpened:ファイルの準備ができているかどうか、またはカメラデバイスが正常に初期化されているかどうかを確認します。成功した場合はtrueを返します。
-
cv :: VideoCapture :: open:ビデオファイルまたはカメラデバイスを開きます。この効果は、関連するパラメーターを渡すVideoCaptureコンストラクターの初期化と同等です。
-
**演算子>>:**画像の次のフレームを取得して戻ります。
-
cv :: VideoCapture :: read:キャプチャ、デコードして、画像の次のフレームに戻ります。
virtual bool cv :: VideoCapture :: read(OutputArray image)
-
cv :: VideoCapture :: release:開いているファイルまたはカメラ機器を閉じます。
-
cv :: VideoCapture :: retrieve:キャプチャされたビデオフレームをデコードして返します。
virtual bool cv :: VideoCapture :: retrieve(OutputArray image、int flag = 0)
-
cv :: VideoCapture :: set:VideoCaptureのプロパティ設定。
virtual bool cv :: VideoCapture :: set(int propId、double value)
propId:cv :: VideoCapturePropertiesを参照してください
-
cv :: VideoCapture :: waitAny:静的関数。VideoCaptureからの準備完了フレームを待機しています。
static bool cv :: VideoCapture :: waitAny(const std :: vector <VideoCapture>&streams、std :: vector <int>&readyIndex、int64 timeoutNs = 0)
パラメータstreamsは入力ストリームリスト、readyIndexはレディデバイスリストのシーケンス番号、timeoutNsはタイムアウト期間です。
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 打开一个网络视频流
const std::string webstream = "http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8";
cv::VideoCapture cap(webstream);
if(!cap.isOpened()){
cerr << "cannot open rtsp stream.\n";
exit(0);
}
// 查询后端支持的API
cout << "backend name:" << cap.getBackendName();
// 获取视频流的帧宽度和高度
int width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
cout << "width = " << width << ",height = " << height << endl;
cv::Mat frame;
int key = -1;
while(true){
cap >> frame;
if(frame.empty()){
cerr << "cannot grab frame from video stream\n";
break;
}
cv::imshow("video",frame);
key = cv::waitKey(10);
if(key == 27){
break;
}
}
cv::destroyAllWindows();
cap.release();
return 0;
}
2)cv :: VideoWriter:ビデオまたは画像シーケンスをファイルに書き込みます。
- VideoWriter()
- VideoWriter(const String&filename、int fourcc、double fps、Size frameSize、bool isColor = true)
- VideoWriter(const String&filename、int apiPreference、int fourcc、double fps、Size frameSize、bool isColor = true)
- VideoWriter(const String&filename、int fourcc、double fps、const Size&frameSize、const std :: vector <int>&params)
- VideoWriter(const String&filename、int apiPreference、int fourcc、double fps、const Size&frameSize、const std :: vector <int>&params)
その中で、パラメータfourccは、VideoWriter ::などのビデオまたは画像シーケンスのエンコード形式です。fourcc( 'P'、 'I'、 'M'、 '1')はMPEG-1コーデック、VideoWriter ::です。 fourcc( 'M'、 'J'、 'P'、 'G')はスポーツjpegコーデックなどです。パラメータfpsはフレームレート、パラメータframeSizeはフレームサイズ、パラメータisColorはそれに応じてエンコードするかどうかです。画像に色を付けるために; 2番目のものはしばしばコンストラクターとして使用されます。
cv :: VideoCapture :: write関数は、ビデオフレームまたは画像シーケンスのファイルへの書き込みを実装します。
virtual void cv :: VideoWriter :: write(InputArray image)
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
int main()
{
// 从本地摄像头创建VideoCapture
cv::VideoCapture cap(0);
if(!cap.isOpened()){
cerr << "cannot open camera.\n";
exit(0);
}
// 获取视频流的帧宽度、高度和帧率
int width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
int rate = cap.get(cv::CAP_PROP_FPS);
cout << "video info:width = " << width << ",height = " << height << ",frame rate = " << rate << endl;
// 创建一个MPEG-4编码 视频Writer
cv::VideoWriter writer("e:/temp/output.mp4",
cv::VideoWriter::fourcc('D','I','V','X'),rate,
cv::Size(width,height));
cv::Mat frame;
int key = -1;
while(cap.isOpened()){
cap >> frame;
if(frame.empty()){
cout << "cannot grab frame from camera.\n";
break;
}
// TODO:对图像进行各种处理
// 对图像进行取反,实现底片效果
cv::imshow("video",frame);
frame -= 255;
// 保存视频
writer.write(frame);
cv::imshow("video:invert",frame);
key = cv::waitKey(10);
if(key == 27){
break;
}
}
cv::destroyAllWindows();
cap.release();
writer.release();
return 0;
}
一般的なビデオ形式のエンコーディングは次のとおりです。
-
CV_FOURCC( 'P'、 'I'、 'M'、 '1')= MPEG-1コード
-
CV_FOURCC( 'M'、 'J'、 'P'、 'G')= motion-jpegコーデック
-
CV_FOURCC( 'M'、 'P'、 '4'、 '2')= MPEG-4.2コーデック
-
CV_FOURCC( 'D'、 'I'、 'V'、 '3')= MPEG-4.3コーデック
-
CV_FOURCC( 'D'、 'I'、 'V'、 'X')= MPEG-4コーデック
-
CV_FOURCC( 'U'、 '2'、 '6'、 '3')= H263コーデック
-
CV_FOURCC( 'I'、 '2'、 '6'、 '3')= H263Iコーデック
CV_FOURCC( 'F'、 'L'、 'V'、 '1')= FLV1コーデックMPEG-1は、CDディスクメディア用にカスタマイズされたビデオおよびオーディオ圧縮形式です。MotionJPEGは、各フレームの画像がそれぞれJPEGを使用してエンコードされます。MPEG-4は非常に狭い帯域幅を使用し、フレーム再構成テクノロジーを介してデータを圧縮および送信し、最小量のデータで最高の画質を取得します。
詳しくはfourccをご覧ください