使用 OpenCv 和多线程从 IP 摄像机提供实时视频

Posted

技术标签:

【中文标题】使用 OpenCv 和多线程从 IP 摄像机提供实时视频【英文标题】:Live Video feed from IP camera using OpenCv and multithreading 【发布时间】:2013-12-18 09:53:08 【问题描述】:

感谢您抽出时间阅读我的帖子。 我有一个应用程序,它接受 IP 摄像机的用户名、密码和 IP 地址并显示视频源(这是通过使用计时器完成的),我还有一个名为“Capture”的按钮,单击该按钮会将图像保存到我的磁盘。我也同时尝试了两台 IP 摄像机,但是当添加另一台摄像机时,第一台摄像机的流会减慢。所以我的问题是“他们是否可以通过在我的应用程序中使用线程来解决这个减速问题”。我是 MFC 和 C++ 和 OpenCV 的新手。我正在使用 OpenCV 显示来自 IP cam 的视频源。请专家帮助我获得正确的解决方案。 这是我为获取视频提要而实现的代码。

void CStaticEx::OnPaint()

CPaintDC dc(this); // device context for painting

CRect rect;
GetClientRect(&rect);

m_pFrameImg = cvQueryFrame(m_pCamera);
//If camera is disconnected, control goes
//in if condition and displays message in 
//picture control
if(m_pFrameImg == NULL)
    KillTimer( ONE);
    CString sCamName;
    sCamName.Format(_T(CAM_ID_TXT),m_IpAddr);
    CString sDviceLost = _T(CONNECTION_LOST_TXT);
    sCamName.Append(sDviceLost);
    dc.SetBkMode(OPAQUE);
    dc.SetBkColor(BACKBRND_COLOR_TXTOUT);
    dc.SetTextColor(ERR_TXT_COLOR);// BGR(0xbbggrr);
    dc.TextOut(ERR_TXT_XAXIS,ERR_TXT_YAXIS,sCamName,sCamName.GetLength());
    return;//check after removinf return;

BITMAPINFO bitmapInfo;
bitmapInfo.bmiHeader.biSize             =   sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biPlanes           =   ONE;
bitmapInfo.bmiHeader.biCompression      =   BI_RGB;
bitmapInfo.bmiHeader.biXPelsPerMeter    =   PELSPERMETER;
bitmapInfo.bmiHeader.biYPelsPerMeter    =   PELSPERMETER;
bitmapInfo.bmiHeader.biClrUsed          =   ZERO;
bitmapInfo.bmiHeader.biClrImportant     =   ZERO;
bitmapInfo.bmiHeader.biSizeImage        =   ZERO;
bitmapInfo.bmiHeader.biWidth            =   m_pFrameImg->width;
bitmapInfo.bmiHeader.biHeight           =   -m_pFrameImg->height;
IplImage* tempImage;

if(m_pFrameImg->nChannels == THREE) //Number of color channels (1,2,3,4)

    tempImage = (IplImage*)cvClone(m_pFrameImg);
    bitmapInfo.bmiHeader.biBitCount=tempImage->depth * tempImage->nChannels;

else if(m_pFrameImg->nChannels ==  ONE) //Number of color channels (1,2,3,4)

    tempImage =  cvCreateImage(cvGetSize(m_pFrameImg), IPL_DEPTH_8U, THREE);
    cvCvtColor(m_pFrameImg, tempImage, CV_GRAY2BGR);
    bitmapInfo.bmiHeader.biBitCount=tempImage->depth * tempImage->nChannels;
    
dc.SetStretchBltMode(COLORONCOLOR);
::StretchDIBits(dc.GetSafeHdc(), rect.left, rect.top, rect.right, rect.bottom,
    ZERO, ZERO, tempImage->width, tempImage->height, tempImage->imageData, &bitmapInfo,
    DIB_RGB_COLORS, SRCCOPY);
cvReleaseImage(&tempImage);
//String for giving Camera name
CString sCamName;
sCamName.Format(_T("Video Stream IP Cam-%s"), m_IpAddr);
dc.SetBkMode(OPAQUE);
dc.SetBkColor(MSG_BGCOLOR);
dc.SetTextColor(WHITE);// BGR(0xbbggrr);
dc.TextOut(MSG_TXT_XAXIS, MSG_TXT_YAXIS, sCamName, sCamName.GetLength());
ReleaseDC(&dc);
SetTimer( ONE,30, NULL);

 
void CStaticEx::OnTimer(UINT_PTR nIDEvent)

// TODO: Add your message handler code here and/or call default
if(nIDEvent =  ONE)

    Invalidate();


 CStatic::OnTimer(nIDEvent);

提前致谢。祝你有美好的一天。

【问题讨论】:

【参考方案1】:

请参阅以下内容以从实时相机中捕获帧。 http://www.codeproject.com/Questions/442770/Connect-to-IP-Camera-in-Cplusplus

【讨论】:

感谢您的回答,我在捕获图像时没有任何问题,我在从 IP 摄像机获取的视频源中遇到延迟问题。 如果您想从 IP 摄像机获取实时帧,您可以使用套接字通信来检索帧。你有网络摄像机的规格(文件)吗?

以上是关于使用 OpenCv 和多线程从 IP 摄像机提供实时视频的主要内容,如果未能解决你的问题,请参考以下文章

在python中使用线程运行无限循环

通过opencv和c ++从ip摄像头流式传输视频

OpenCV 无法流式传输 IP 摄像机

OpenCV 在不同线程上从网络摄像头运行视频

使用 OpenCV、Boost 线程和多个摄像头

使用 opencv 从 ip camera 获取高分辨率图像