如何获得EVF实时图像的尺寸和格式

How to get dimensions and format of EVF LiveView Image?

本文关键字:格式 图像 何获得 EVF 实时      更新时间:2023-10-16

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

佳能LiveView:图像转换为OpenCV Mat

佳能EDSDK如何获得实时视图图像的宽度和高度?

我想做的是使用佳能的EDSDK在实时观看模式下从佳能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(或类似的东西),但我不知道如何检索该数据。

最让我困惑的是,ullength变量,这是数据流的字节大小,并没有保持不变(它似乎每次变化相对较小)。如果实际图像大小保持不变,这怎么可能呢?

无论如何,任何对这个问题的帮助都将是感激的。我可以尝试使用基于库的解决方案,但我要尽量降低延迟。如果我能提供更多的信息,或者如果你想看到我的实际代码(万一问题可能存在),请让我知道。

谢谢,约翰

据我所知,没有函数来获得实时视图大小,它也不是真正必要的。您下载的实时视图框架是标准的jpg格式,因此您可以通过读取其标题来确定其大小。我不知道OpenCV或OpenGL如何处理jpg图像,但我肯定有一些功能,如果他们支持阅读这种格式。否则,您可以使用众多jpg库之一。jpg压缩也解释了为什么图像在不同帧之间大小不同。

你实际上通过调用EdsGetPropertyData和kedspropid_evf_coordinatessystem得到的是实时视图坐标系统的大小。这绝对不是实时视图的大小。我想它更接近照片的尺寸但我不完全确定