首先,让我发布一些我通过谷歌发现的类似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变量,它是数据流的字节大小,不会保持不变(每次变化似乎相对较小。)如果可能的话实际图像大小似乎保持不变?
无论如何,对此问题的任何帮助将不胜感激。我可以尝试使用基于库的解决方案,但我试图尽可能降低延迟。如果我可以提供更多信息,或者您希望查看我的实际代码(如果问题可能存在),请告诉我。
谢谢,
约翰
答案 0 :(得分:1)
据我所知,没有获取实时视图大小的功能,也没有必要。 您下载的实时视图框架是标准的jpg,因此您可以通过阅读其标题来查找大小。 我不知道OpenCV或OpenGL如何使用jpg图像,但我确信如果它们支持读取该格式,则会有一些功能。 否则,您可以使用众多jpg库中的一个。 jpg压缩还解释了为什么图像大小在帧之间变化。
通过使用kEdsPropID_Evf_CoordinateSystem调用EdsGetPropertyData实际获得的是实时视图坐标系统大小。这绝对不是实时视图的大小。我认为它更接近照片尺寸,但我并不完全确定。