如何获取EVF LiveView图像的尺寸和格式?

时间:2016-09-10 16:52:13

标签: c++ image opengl edsdk

首先,让我发布一些我通过谷歌发现的类似SO问题的链接。第一个链接确实有一个有效的答案,但它并没有直接解决我的问题。第二个链接直接解决了我的问题,但gdh的回复似乎对我没有帮助。

Canon LiveView: image convertion to OpenCV Mat

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

我正在尝试使用Canon的EDSDK在实时查看模式下从Canon Rebel下载图像。我能够打开流并不断下载数据流,但我感到难过的是如何将数据转换为可用的图像。最终我的目标是通过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 个答案:

答案 0 :(得分:1)

据我所知,没有获取实时视图大小的功能,也没有必要。 您下载的实时视图框架是标准的jpg,因此您可以通过阅读其标题来查找大小。 我不知道OpenCV或OpenGL如何使用jpg图像,但我确信如果它们支持读取该格式,则会有一些功能。 否则,您可以使用众多jpg库中的一个。 jpg压缩还解释了为什么图像大小在帧之间变化。

通过使用kEdsPropID_Evf_CoordinateSystem调用EdsGetPropertyData实际获得的是实时视图坐标系统大小。这绝对不是实时视图的大小。我认为它更接近照片尺寸,但我并不完全确定。