2016-09-10 15 views
0

最初に、私がGoogleで見つけた類似の質問にリンクを張りましょう。最初のリンクには有効な回答があるようですが、私の問題には直接触れません。 2番目のリンクは私の問題に直接対処していますが、gdhによる応答は私を助けてくれないようです。私はキヤノンのEDSDKを使用してライブビューモード時に私のキヤノン反乱からダウンロードイメージをやろうとしています何EVF LiveViewイメージの寸法とフォーマットを取得する方法は?

Canon LiveView: image convertion to OpenCV Mat

Canon EDSDK How can I get width and height of live view images?

。ストリームを開いて連続的にデータストリームをダウンロードすることができますが、私はそのデータを使用可能なイメージに変換する方法を困惑しています。最終的に私の目標は、glTexSubImage2Dを使ってライブビュー画像をOpenGLテクスチャに直接アップロードすることですが、画像のビット深度、カラーフォーマット、および寸法を取得する方法は不明です。

サンプルコードを投稿できます。これは私の作業コードの抜粋された例であることに留意してください - ストリームの開始、カメラの参照の取得、参照の解放などのいくつかの詳細は省略し、実際にはダウンロードとOpenGLの呼び出しは別のスレッドで行われます。

// All my variables 
EdsStreamRef evfStream = nullptr;  // evf datastream 
EdsImageRef evfImg = nullptr;   // image ref 
EdsCameraRef camRef = nullptr;  // camera ref 
void * pData = nullptr;    // Pointer to image data 
EdsUInt64 uLength(0);    // Size in bytes of image data 
GLuint uGLTexID(0);     // Handle to OpenGL texture 
EdsSize imgSize{0};     // Width, height of image 
GLuint uClrFmt = GL_RGB;    // Color format of image 
GLuint uClrType = GL_UNSIGNED_BYTE; // Color data type of image 

////////////////////////////////////////////////////////////////////// 
// Get image from camera 

// Create memory stream, init size to 1 byte for now 
EdsCreateMemoryStream(1, &evfStream); 

// Create an image ref from the streawm 
EdsCreateEvfImageRef(evfStream, &evfImg); 

// Download the image (which I believe resizes the stream) 
EdsDownloadEvfImage(camRef, evfImg); 

// Get data size and pointer 
EdsGetLength(evfStream, &uLength); 
EdsGetPointer(evfStream, &pData); 

////////////////////////////////////////////////////////////////////// 
// Get image info 

// This doesn't seem to be correct, using these dimensions causes a crash 
EdsGetPropertyData(m_WriteImg.imgRef, kEdsPropID_Evf_CoordinateSystem, 0, sizeof(EdsSize), &imgSize); 

// How do I get these two? 
uClrFmt = GL_RGB; 
uClrType = GL_UNSIGNED_BYTE; 

////////////////////////////////////////////////////////////////////// 
// Upload to GPU 

// If this is the first time, create the texture 
bool bFirstTime = true; 
if (bFirstTime) 
{ 
    //Generate the device texture and bind it 
    glGenTextures(1, &uGLTexID); 
    glBindTexture(GL_TEXTURE_2D, uGLTexID); 

    //Upload host texture to device 
    glTexImage2D(GL_TEXTURE_2D, 0, uClrFmt, imgSize.width, imgSize.height, 0, uClrFmt, uClrType, pData); 

    // Unbind 
    glBindTexture(GL_TEXTURE_2D, 0); 

    bFirstTime = false; 
} 
// Otherwise update the existing texture 
else 
{ 
    // Bind texture 
    glBindTexture(GL_TEXTURE_2D, uGLTexID); 

    // Upload image 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imgSize.width, imgSize.height, uClrType, uClrFmt, pData); 

    // Unbind 
    glBindTexture(GL_TEXTURE_2D, 0); 
} 

欠けている部分は、実際の画像とそのプロパティを取得する方法です。 EDSDKのサンプルおよびOpenCV関連の質問には、そのデータを使用可能なイメージに変換する方法の例がありますが、どちらも別のライブラリを使用してデータを使用可能なイメージに配置する必要があります。 EDSDK例において

は、GDI +は、のCImageオブジェクトを作成するために使用されます。デバッガでは、作成されたCImageのビット深度が24で、サイズが1056x704(またはそのようなもの)であることがわかりましたが、そのデータがどのように取得されるかはわかりません。

私を最も混乱させる原因は、データストリームのバイト数であるuLength変数が一定でないことです(これは毎回比較的少量で変化するようです)。実際の画像サイズが一定のままであると思われる場合

とにかく、この問題のお手伝いをいただければ幸いです。ライブラリーベースのソリューションを試してみることもできますが、私は可能な限りレイテンシを低く抑えようとしています。これ以上の情報を提供できない場合や、実際のコードを表示したい場合は(問題がある場合など)、教えてください。

おかげで、

ジョン

答えて

1

は、私の知る限りでは、ライブビューのサイズを取得するには何も機能はありません、それはまた、本当に必要はありません。 ダウンロードしたライブビューフレームは標準のjpgですので、ヘッダーを読んでサイズを確認できます。 OpenCVやOpenGLがjpgイメージでどのように動作するのかわかりませんが、そのフォーマットの読み込みをサポートしていれば機能があると思います。 そうでなければ、多くのjpgライブラリの1つを使用できます。 jpg圧縮でも、フレーム間でイメージサイズが異なる理由が説明されています。あなたが実際にkEdsPropID_Evf_CoordinateSystemでEdsGetPropertyDataを呼び出すことによって何を得る

は、システムのサイズを調整し、ライブビューです。間違いなくライブビューのサイズです。私はそれが写真のサイズに近いと思うが、私はそれについて完全には分かっていない。

+0

ありがとうございます。答えは、それがjpgイメージであり、生のバイトを取得するためには、最初に解凍する必要があります。 OpenCVにはその機能がありますが、OpenGL自体ではできません。しかし、私はOpenGLのコンテキストを作成するためにSDL2を使用しているので、おそらくSDLイメージには私が必要なものがあります。 – user1973454

+0

@ user1973454はい、正しいです。 jpgの読み込みに問題がある場合は、いつでもlibjpegのようなものを使うことができます。それは非常に速くなければならず、OpenCVがフードの下でそれを使用するなら、私は驚くことはありません。 –

関連する問題