欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c#基于opencv,開發(fā)攝像頭播放程序

 更新時(shí)間:2021年03月08日 11:45:15   作者:源之緣  
這篇文章主要介紹了c#基于opencv,開發(fā)攝像頭播放程序的示例,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下

前言 

Windows下實(shí)現(xiàn)攝像視頻捕捉有多種實(shí)現(xiàn)方式;各種方式的優(yōu)劣,本文不做對比。但是,opencv是一款老牌開發(fā)庫,在圖像處理領(lǐng)域聲名顯赫。采用opencv來處理攝像視頻,在性能和穩(wěn)定性上,是有保障的。并且,opencv包含很多圖像處理函數(shù),可以更方便的對視頻處理。

  執(zhí)行程序是用wpf開發(fā)的,所以先將opencv封裝成c語言接口,以供調(diào)用。opencv也不可能提供現(xiàn)成的控件供wpf使用,兩種不同的開發(fā)語言“溝通”起來有些困難。其實(shí)稍作變通,就可以實(shí)現(xiàn)攝像頭播放功能。

1 對opencv封裝

opencv的類VideoCapture封裝了對攝像頭的操作,使用起來也非常簡單。

 bool open(int device); device為攝像頭設(shè)備序號。

如果有多個(gè)攝像頭,怎么知道哪個(gè)攝像頭的序號那?可以通過如下函數(shù),獲取攝像頭列表。攝像頭在list中索引即為設(shè)備序號。

int GetCameraDevices(vector<wstring>& list)
{
  ICreateDevEnum *pDevEnum = NULL;
  IEnumMoniker *pEnum = NULL;
  int deviceCounter = 0;
  CoInitialize(NULL);
  HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
    CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
    reinterpret_cast<void**>(&pDevEnum));

  if (SUCCEEDED(hr))
  {
    // Create an enumerator for the video capture category.
    hr = pDevEnum->CreateClassEnumerator(
      CLSID_VideoInputDeviceCategory,
      &pEnum, 0);

    if (hr == S_OK) {

      //if (!silent)printf("SETUP: Looking For Capture Devices\n");
      IMoniker *pMoniker = NULL;

      while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {

        IPropertyBag *pPropBag;
        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
          (void**)(&pPropBag));

        if (FAILED(hr)) {
          pMoniker->Release();
          continue; // Skip this one, maybe the next one will work.
        }

        // Find the description or friendly name.
        VARIANT varName;
        VariantInit(&varName);
        hr = pPropBag->Read(L"Description", &varName, 0);

        if (FAILED(hr))
          hr = pPropBag->Read(L"FriendlyName", &varName, 0);

        if (SUCCEEDED(hr)) {

          hr = pPropBag->Read(L"FriendlyName", &varName, 0);

          int count = 0;
          wstring str2 = varName.bstrVal;
          list.push_back(str2);
        }

        pPropBag->Release();
        pPropBag = NULL;

        pMoniker->Release();
        pMoniker = NULL;

        deviceCounter++;
      }

      pDevEnum->Release();
      pDevEnum = NULL;

      pEnum->Release();
      pEnum = NULL;
    }
  }
  return deviceCounter;
}

總之,使用opencv打開攝像頭非常簡單。

打開之后,就是獲取攝像頭圖像。視頻其實(shí)就是圖像的集合;每秒鐘獲取25幅圖像,將其在控件上顯示,就是視頻。

Mat cameraImg;
_pCapture >> cameraImg;

Mat類封裝了對圖像的操作。c#不可能操作Mat,需要將Mat中純圖像部分?jǐn)?shù)據(jù)傳遞出來,圖像才能被c#利用。

int Camera_GetImgData(INT64 handle, char* imgBuffer)
{
  CameraInfo *pCameraInfo = (CameraInfo*)handle;

  Mat cameraImg;
  *(pCameraInfo->_pCapture) >> cameraImg;

  if (!cameraImg.empty())
  {
    int height = cameraImg.rows;int dataLen = height * cameraImg.step;
    memcpy(imgBuffer, cameraImg.data, dataLen);

    return 0;
  }
  else
  {
    return 1;
  }
}

cameraImg.data中存有圖像數(shù)據(jù),data的大小可以根據(jù)圖像的高度、每行圖像的步幅計(jì)算出來。c#調(diào)用此函數(shù)后,imgBuffer存放圖像數(shù)據(jù)。對數(shù)據(jù)imgBuffer處理后,就可以在控件上顯示。

c語言對opencv封裝函數(shù)列表如下:

extern "C"
{
  OpenCVCamera_API int Camera_GetCameraName(char* listName);

  OpenCVCamera_API INT64 Camera_CreateHandle();
  OpenCVCamera_API void Camera_CloseHandle(INT64 handle);

  OpenCVCamera_API BOOL Camera_IsOpen(INT64 handle);
  OpenCVCamera_API int Camera_Open(INT64 handle, int index);
  OpenCVCamera_API int Camera_Close(INT64 handle);

  OpenCVCamera_API int Camera_GetImgInfo(INT64 handle,int& width,int& height,int& channel,
    int& step, int& depth);
  OpenCVCamera_API int Camera_GetImgData(INT64 handle, char* imgBuffer);

  //flipCode >0: 沿y-軸翻轉(zhuǎn), 0: 沿x-軸翻轉(zhuǎn), <0: x、y軸同時(shí)翻轉(zhuǎn)
  OpenCVCamera_API int Camera_GetImgData_Flip(INT64 handle, char* imgBuffer, int flipCode);
  OpenCVCamera_API int Camera_ImgData_Compress(int rows, int cols, int type, void* imgBuffer,
    int param,void* destBuffer,int* destLen);
}

2 WPF實(shí)現(xiàn)視頻播放

WPF的Image控件實(shí)現(xiàn)圖像的顯示。實(shí)現(xiàn)視頻播放的邏輯為:設(shè)定一個(gè)定時(shí)器(時(shí)間間隔為40毫秒),每隔一段時(shí)間從opencv獲取圖像,在控件中顯示。

 <Image x:Name="imageVideoPlayer" Stretch="Uniform" ></Image>

實(shí)現(xiàn)圖像顯示代碼

 BitmapSource bitmapSource = _openCVCamera.GetBitmapSource();
      if (bitmapSource == null)
        return false;

 imageVideoPlayer.Source = bitmapSource;

實(shí)現(xiàn)圖像顯示的關(guān)鍵是構(gòu)建BitmapSource,暨:如何從opencv中獲取圖像數(shù)據(jù)構(gòu)建BitmapSource。

//獲取圖像數(shù)據(jù)
  if (!GetImgData(out byte[] imgData))
          return null;

  //構(gòu)建WriteableBitmap
  WriteableBitmap img = new WriteableBitmap(_imgWidth, _imgHeight, 96, 96, PixelFormats.Bgr24, null);
  img.WritePixels(new Int32Rect(0, 0, _imgWidth, _imgHeight),
          imgData, img.BackBufferStride, 0);
  img.Freeze();

至此,就可以顯示攝像頭圖像了。

以上就是c#基于opencv,開發(fā)攝像頭播放程序的詳細(xì)內(nèi)容,更多關(guān)于c# opencv攝像頭播放的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談Unity腳本生命周期與執(zhí)行順序

    淺談Unity腳本生命周期與執(zhí)行順序

    在Unity中,腳本可以理解為附加在游戲?qū)ο笊系挠糜诙x游戲?qū)ο笮袨榈闹噶畲a。必須綁定在游戲?qū)ο笊喜拍荛_始它的生命周期。游戲?qū)ο罂梢岳斫鉃槟苋菁{各種組件的容器,游戲?qū)ο蟮乃薪M件一起決定了這個(gè)對象的行為和游戲中的表現(xiàn)
    2021-06-06
  • WPF實(shí)現(xiàn)帶篩選功能的DataGrid

    WPF實(shí)現(xiàn)帶篩選功能的DataGrid

    在默認(rèn)情況下,WPF提供的DataGrid僅擁有數(shù)據(jù)展示等簡單功能,如果要實(shí)現(xiàn)像Excel一樣復(fù)雜的篩選過濾功能,則相對比較麻煩。本文以一個(gè)簡單的小例子,簡述如何通過WPF實(shí)現(xiàn)DataGrid的篩選功能,僅供學(xué)習(xí)分享使用,如有不足之處,還請指正
    2023-03-03
  • .NET垃圾回收器(GC)原理淺析

    .NET垃圾回收器(GC)原理淺析

    這篇文章主要介紹了.NET垃圾回收器(GC)原理淺析,本文先是講解了一些基礎(chǔ)知識如托管堆(Managed Heap)、CPU寄存器(CPU Register)、根(Roots)等,然后講解了垃圾回收的基本原理、算法等,需要的朋友可以參考下
    2015-01-01
  • C#基于基姆拉爾森算法計(jì)算指定日期是星期幾的方法

    C#基于基姆拉爾森算法計(jì)算指定日期是星期幾的方法

    這篇文章主要介紹了C#基于基姆拉爾森算法計(jì)算指定日期是星期幾的方法,實(shí)例分析了基姆拉爾森算法的原理與使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#將Sql數(shù)據(jù)保存到Excel文件中的方法

    C#將Sql數(shù)據(jù)保存到Excel文件中的方法

    這篇文章主要介紹了C#將Sql數(shù)據(jù)保存到Excel文件中的方法,文中的ExportExcel可起到將sql數(shù)據(jù)導(dǎo)出為Excel的作用,需要的朋友可以參考下
    2014-08-08
  • c# 如何實(shí)現(xiàn)一個(gè)簡單的json解析器

    c# 如何實(shí)現(xiàn)一個(gè)簡單的json解析器

    這篇文章主要介紹了c# 如何實(shí)現(xiàn)一個(gè)簡單的json解析器,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C#圖像亮度調(diào)整的方法

    C#圖像亮度調(diào)整的方法

    這篇文章主要介紹了C#圖像亮度調(diào)整的方法,涉及C#操作圖像亮度的相關(guān)技巧,需要的朋友可以參考下
    2015-04-04
  • C#正則表達(dá)式Regex類用法實(shí)例分析

    C#正則表達(dá)式Regex類用法實(shí)例分析

    這篇文章主要介紹了C#正則表達(dá)式Regex類用法,實(shí)例分析了其中比較常見的幾類用法,具有一定的實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • .NET企業(yè)級項(xiàng)目中遇到的國際化問題和解決方法

    .NET企業(yè)級項(xiàng)目中遇到的國際化問題和解決方法

    這篇文章主要介紹了.NET企業(yè)級項(xiàng)目中遇到的國際化問題和解決方法,說明了理國際化問題的一些典型例子和經(jīng)驗(yàn)之談,需要的朋友可以參考下
    2014-07-07
  • C#使用讀寫鎖三行代碼簡單解決多線程并發(fā)的問題

    C#使用讀寫鎖三行代碼簡單解決多線程并發(fā)的問題

    本文主要介紹了C#使用讀寫鎖三行代碼簡單解決多線程并發(fā)寫入文件時(shí)提示“文件正在由另一進(jìn)程使用,因此該進(jìn)程無法訪問此文件”的問題。需要的朋友可以參考借鑒
    2016-12-12

最新評論