C++ ISampleGrabber::BufferCB到IplImage;OpenCV中的显示显示乱码图像-C++;
我正在使用DirectShow访问视频流,然后使用SampleGrabber过滤器和接口从每个帧获取样本,以便进一步进行图像处理。我正在使用回调,因此在每一个新帧之后都会调用它。我基本上刚刚从PlayCap示例应用程序开始工作,并在图形中添加了一个示例过滤器 我遇到的问题是,我试图在不同的OpenCV窗口上显示抓取的样本。然而,当我试图将缓冲区中的信息强制转换为IplImage时,我得到了一堆乱七八糟的像素。BufferCB调用的代码如下所示,没有任何正确的错误处理:C++ ISampleGrabber::BufferCB到IplImage;OpenCV中的显示显示乱码图像-C++;,c++,opencv,directshow,iplimage,C++,Opencv,Directshow,Iplimage,我正在使用DirectShow访问视频流,然后使用SampleGrabber过滤器和接口从每个帧获取样本,以便进一步进行图像处理。我正在使用回调,因此在每一个新帧之后都会调用它。我基本上刚刚从PlayCap示例应用程序开始工作,并在图形中添加了一个示例过滤器 我遇到的问题是,我试图在不同的OpenCV窗口上显示抓取的样本。然而,当我试图将缓冲区中的信息强制转换为IplImage时,我得到了一堆乱七八糟的像素。BufferCB调用的代码如下所示,没有任何正确的错误处理: STDMETHODIMP
STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen)
{
AM_MEDIA_TYPE type;
g_pGrabber->GetConnectedMediaType(&type);
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER *)type.pbFormat;
BITMAPINFO* bmi = (BITMAPINFO *)&pVih->bmiHeader;
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
int channels = bmih->biBitCount / 8;
mih->biPlanes = 1;
bmih->biBitCount = 24;
bmih->biCompression = BI_RGB;
IplImage *Image = cvCreateImage(cvSize(bmih->biWidth, bmih->biHeight), IPL_DEPTH_8U, channels);
Image->imageSize = BufferLen;
CopyMemory(Image->imageData, pBuffer, BufferLen);
cvFlip(Image);
//openCV Mat creation
Mat cvMat = Mat(Image, true);
imshow("Display window", cvMat); // Show our image inside it.
waitKey(2);
return S_OK;
}
我的问题是,我是否在这里做了一些错误的事情,使显示的图像看起来像这样:
是否缺少标题信息或其他信息?引用的代码是解决方案的一部分。您可以在此处创建具有特定宽度/高度的图像对象,其中包含8位像素数据和未知通道/组件计数。然后从另一个格式未知的缓冲区复制数据
它工作良好的唯一机会是,所有未知因素都能在没有你努力的情况下惊人地匹配。所以,您基本上需要从检查样本抓取器输入引脚上的媒体类型开始。然后,如果它不是您想要的,您必须分别更新您的代码。SG的下游连接是什么,特别是它是否连接到视频渲染器,这一点可能也很重要。好的,我已经开始了解图形是如何构建的。基本上,我给它一个源,添加一个示例抓取过滤器,然后在源上渲染pin。然后将图形构建为Source->Sample Grabber->MJPEG解压缩器->颜色空间转换器->视频渲染器。因此,本质上,从样本中获得的字节被编码为MJPEG。我使用GraphEdit工具查看是否可以重新排列过滤器,这样SampleGrabber工具就位于渲染器之前,而不是骰子。那么,是否有一种简写的方式来解码字节,或者是否应该更改过滤图?是的,这解释了效果:您使用JPEG字节并将其重新解释为RGB,这是一种非工作模式。实际上,您可以重新排列过滤器。然而,在编程方面,您通常会将示例抓取器设置为仅接受您感兴趣的RGB类型,例如,请参见“设置媒体类型”下的内容。太好了,这就是答案,谢谢!我不知道通过设置类型,图形会自动将SampleGrabber构建到正确的位置,以获取此类数据。谢谢!