最初に、私が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変数が一定でないことです(これは毎回比較的少量で変化するようです)。実際の画像サイズが一定のままであると思われる場合
とにかく、この問題のお手伝いをいただければ幸いです。ライブラリーベースのソリューションを試してみることもできますが、私は可能な限りレイテンシを低く抑えようとしています。これ以上の情報を提供できない場合や、実際のコードを表示したい場合は(問題がある場合など)、教えてください。
おかげで、
ジョン
ありがとうございます。答えは、それがjpgイメージであり、生のバイトを取得するためには、最初に解凍する必要があります。 OpenCVにはその機能がありますが、OpenGL自体ではできません。しかし、私はOpenGLのコンテキストを作成するためにSDL2を使用しているので、おそらくSDLイメージには私が必要なものがあります。 – user1973454
@ user1973454はい、正しいです。 jpgの読み込みに問題がある場合は、いつでもlibjpegのようなものを使うことができます。それは非常に速くなければならず、OpenCVがフードの下でそれを使用するなら、私は驚くことはありません。 –