カメラからビデオ フレームをキャプチャするには、MS DirectShow を使用する必要があります (生のピクセル データが必要なだけです)。
グラフ/フィルター ネットワーク (キャプチャ デバイス フィルターと ISampleGrabber) を構築し、コールバック (ISampleGrabberCB) を実装することができました。適切なサイズのサンプルを受け取ります。
ただし、それらは常に逆さまであり (垂直方向に反転、つまり回転していない)、カラー チャネルは BGR 順 (RGB ではありません) です。
BITMAPINFOHEADER の biHeight フィールドを正と負の両方の値に設定しようとしましたが、効果がありません。MSDN のドキュメントによると、ISampleGrapper::SetMediaType() はとにかくビデオ データのフォーマット ブロックを無視します。
これが私が見たもの(DSではなく別のカメラで記録されたもの)で、DirectShow ISampleGrabberが私に与えたものです:「RGB」は実際にはそれぞれ赤、緑、青です:
私が使用しているコードのサンプル、少し簡略化:
// Setting the media type...
AM_MEDIA_TYPE* media_type = 0 ;
this->ds.device_streamconfig->GetFormat(&media_type); // The IAMStreamConfig of the capture device
// Find the BMI header in the media type struct
BITMAPINFOHEADER* bmi_header;
if (media_type->formattype != FORMAT_VideoInfo) {
bmi_header = &((VIDEOINFOHEADER*)media_type->pbFormat)->bmiHeader;
} else if (media_type->formattype != FORMAT_VideoInfo2) {
bmi_header = &((VIDEOINFOHEADER2*)media_type->pbFormat)->bmiHeader;
} else {
return false;
}
// Apply changes
media_type->subtype = MEDIASUBTYPE_RGB24;
bmi_header->biWidth = width;
bmi_header->biHeight = height;
// Set format to video device
this->ds.device_streamconfig->SetFormat(media_type);
// Set format for sample grabber
// bmi_header->biHeight = -(height); // tried this for either and both interfaces, no effect
this->ds.sample_grabber->SetMediaType(media_type);
// Connect filter pins
IPin* out_pin= getFilterPin(this->ds.device_filter, OUT, 0); // IBaseFilter interface for the capture device
IPin* in_pin = getFilterPin(this->ds.sample_grabber_filter, IN, 0); // IBaseFilter interface for the sample grabber filter
out_pin->Connect(in_pin, media_type);
// Start capturing by callback
this->ds.sample_grabber->SetBufferSamples(false);
this->ds.sample_grabber->SetOneShot(false);
this->ds.sample_grabber->SetCallback(this, 1);
// start recording
this->ds.media_control->Run(); // IMediaControl interface
すべての関数の戻り値の型をチェックしていますが、エラーは発生しません。
ヒントやアイデアに感謝します。
私がすでに試したこと:
キャプチャ デバイス フィルターまたはサンプル グラバーのいずれか、または両方、またはどちらにも負の値を biHeight フィールドに設定しても、効果はありません。
IGraphBuilder を使用してピンを接続する - 同じ問題。
メディアの種類を変更する前にピンを接続する - 同じ問題。
メディア タイプがフィルターによって実際に適用されたかどうかを再度クエリして確認しますが、明らかに適用されているか、少なくとも保存されています。
画像を合計バイトが反転したものとして解釈すると (最後のバイトが最初、最初のバイトが最後)、水平方向に反転されます。
ビデオ カメラに問題があるかどうかを確認しています。VLC (DirectShow キャプチャ) でテストすると、正常に見えます。