質問をする前に、私は主に Linux C++ 開発者であり、Windows アプリケーションを作成した経験があまりないことを述べておく必要があります。Microsoft コンパイラではなく、g++ を使用してすべてのコードをコンパイルします。
バックグラウンド
しばらくの間、私はさまざまな専門カメラをサポートする科学画像アプリケーションに取り組んできました。これらのカメラのほとんどには、開発を容易にするメーカー提供の SDK があります。ただし、私のアプリケーションがサポートするカメラの一部は、標準の UVC カメラです。最近まで、このアプリケーションは Linux 専用でしたが、現在は macOS と Windows に移植されています。
- Linux ポートは、Video4Linux を介して UVC サポートを実装し、非常にうまく機能します。
- macOS ポートは、libuvc ( https://github.com/libuvc/libuvc ) を介して UVC サポートを実装し、非常にうまく機能します。
問題: Windows UVC サポート
Windows での UVC カメラの実装に問題があります。私は DirectShow と Media Framework プロセッサの両方を作成しました。これらは十分に機能し、ゲイン、明るさ、コントラストなどのパラメータと、まさに必要としている V4L2 を制御できます。ただし、露出制御を実装しようとすると問題が発生します。
1 ミリ秒から 1000 ミリ秒の露光範囲が文書化されている特定の UVC カメラを使用する場合、V4L2_CID_EXPOSURE_ABSOLUTE を使用して、Video4Linux で全露光範囲を使用できます。新しい露出が適用されると、出力された画像に線形の変化が見られます。macOS で libuvc を使用すると、同じことがわかります。
Windows で DirectShow または Media Foundation を使用して同じカメラを使用すると、露出範囲が大きく異なります。次のコードを使用して、露出制御の範囲を照会します。
HRESULT hr;
IAMCameraControl *cam_ctrl = NULL;
long lmin, lmax, lstep, ldft, lcap;
hr = m_imf_media_source->QueryInterface(IID_IAMCameraControl, (void**) &cam_ctrl);
if (FAILED(hr))
{
throw_error(hr);
}
hr = cam_ctrl->GetRange(CameraControl_Exposure, &lmin, &lmax, &lstep, &ldft, &lcap);
if (FAILED(hr))
{
if (hr == E_PROP_ID_UNSUPPORTED)
{
*min = 0;
*max = 0;
*value = 0;
return false;
}
else
{
throw_error(hr);
}
}
*min = static_cast<int>(lmin);
*max = static_cast<int>(lmax);
*value = static_cast<int>(ldft);
return true;
proc_amp->GetRangeから検出された値は、ドキュメントに記載されているように、リアルタイム単位ではありません。値は、たとえば -11 ~ -3 で、1000 ミリ秒を超える露出をサポートする一部の UVC カメラでは、値は正です。露出をストリームに適用すると、ステップが非常に粗くなります。すでに述べたように、Linux でのこの特定のカメラの露光ステップは線形であり、何百ものステップがあります。Windows では、約 14 個しかありません。
私の主な質問は次のとおりです。DirectShow または Media Foundations のリアルタイム ユニットで UVC カメラを使用することは可能ですか。誰かがアイデアを持っている場合は、別のアプローチを検討していただければ幸いです。残念ながら、このような粗い露出ステップは受け入れられません。
libuvc が Windows でサポートされていることは知っていますが、特定のドライバーをインストールする必要があります。これは、ユーザーに実行してほしくないことです。
すべてのヘルプは大歓迎です。
アマンダ。