首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Visual C++ 視訊影像處理實戰:採集卡整合與畫中畫技術

     編輯:VC 教學

前言:影像處理的廣泛應用

隨著軟硬體飛速發展,人類進入高速資訊時代,約 80% 資訊源自影像。軍事、醫療、工業監控、自動辨識等領域均需即時、逼真的動態影像。本文分享基於 VC 開發平台整合影像採集卡的實戰經驗,並實作「畫中畫」功能。

系統架構:採集卡為核心的影像處理平台

電腦影像系統分高中低三檔,普及型為低階:CCD 攝影機 + 影像採集卡 + 電腦。結構簡單、應用方便、影像清晰。筆者採用台灣 BENTECH CV-155L 白黑攝影機 (752×582) 與中科院科技嘉 CA-MPE1000 PCI 白黑採集卡。

採集卡整合三步驟

  1. 安裝驅動程式,將 VxD.vxd 複製至 Windows SYSTEM 目錄。
  2. VC 專案連結廠商提供的 mpew32.dll / mpew32.lib,引用初始化硬體、採集影像等函式。
  3. 設定系統調色板並顯示處理。採集卡輸出裸影像資料 (無格式與調色板),需自行建立 BITMAPINFO、邏輯調色板,再以 SetDIBitsToDevice 繪製。

關鍵程式碼片段

// 建構子初始化採集卡
W32_Init_MPE1000();
W32_Modify_Contrast(50);
W32_Modify_Brightness(45);
W32_Set_HP_Value(945);
W32_Set_Input_Source(1);
W32_CACardParam(AD_SETHPFREQ, hpGrabFreq);
W32_Set_PAL_Range(1250, 1024);
W32_Set_VGA_Mode(1);

// 採集迴圈 (雙擊滑鼠停止)
void CTestView::OnGraboneframe() {
    W32_CACardParam(AD_SETGRABDEST, CA_GRABMEM);
    if (lpDib) { GlobalUnlock(hglbDIB); GlobalFree(hglbDIB); }
    hglbDIB = GlobalAlloc(GHND, (DWORD)wImgWidth * wImgHeight);
    lpDib = (BYTE*)GlobalLock(hglbDIB);
    hdc = GetDC()->GetSafeHdc();
    SetLogicPal(hdc, cxDib, cyDib, 8);
    SetStretchBltMode(hdc, COLORONCOLOR);
    bGrabMark = TRUE;
    while (bGrabMark) {
        if (msg.message == WM_LBUTTONDBLCLK) bGrabMark = FALSE;
        W32_ReadXMS2Buf(wCurrent_Frame, lpDib);
        SetDIBitsToDevice(hdc, 0, 0, cxDib, cyDib, 0, 0, 0, cyDib,
                          (LPSTR)lpDib, bmi, DIB_RGB_COLORS);
    }
    W32_CAStopCapture();
    ::ReleaseDC(GetSafeHwnd(), hdc);
}

// 邏輯調色板建立
void WINAPI InitLogicPal(HDC hdc, short width, short height, WORD bitCount) {
    LOGPALETTE *pLogPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + 256*sizeof(PALETTEENTRY));
    pLogPal->palVersion = 0x300; pLogPal->palNumEntries = 256;
    for (int i=0; i<256; i++) {
        pLogPal->palPalEntry[i].peRed = pLogPal->palPalEntry[i].peGreen = pLogPal->palPalEntry[i].peBlue = i;
        pLogPal->palPalEntry[i].peFlags = 0;
    }
    hPal = CreatePalette(pLogPal);
    SelectPalette(hdc, hPal, 0); RealizePalette(hdc);
    // 建立 BITMAPINFO ...
}

畫中畫技術:雙緩衝合成消除閃爍

傳統先畫大圖再疊小圖會導致嚴重閃爍。改進採用記憶體裝置內文 (Memory DC) 合成:先將大圖繪至記憶體 DC,再疊加小圖,最後一次性 StretchBlt 輸出至螢幕,實現流暢畫中畫。

void pictureinpicture() {
    // 讀取大圖、小圖資料至 pData1, pData2
    // 設定 BITMAPINFO m_pBMI1, m_pBMI2
    CDC MemDC; MemDC.CreateCompatibleDC(&dc);
    CBitmap bitmap; bitmap.CreateCompatibleBitmap(&dc, biWidth, biHeight);
    CBitmap* oldmap = MemDC.SelectObject(&bitmap);
    // 大圖
    StretchDIBits(MemDC.m_hDC, 0,0, biWidth,biHeight, 0,0, biWidth,biHeight,
                  pData1, m_pBMI1, DIB_RGB_COLORS, SRCCOPY);
    // 小圖 (右上角 20,20)
    StretchDIBits(MemDC.m_hDC, 20,20, biWidth1,biHeight1, 0,0, biWidth1,biHeight1,
                  pData2, m_pBMI2, DIB_RGB_COLORS, SRCCOPY);
    // 一次輸出螢幕
    StretchBlt(dc.m_hDC, 0,0, bih.biWidth,bih.biHeight,
               MemDC.m_hDC, 0,0, bih.biWidth,bih.biHeight, SRCCOPY);
    MemDC.SelectObject(oldmap);
    // 釋放記憶體 ...
}

結語

本文完整示範從採集卡驅動整合、調色板處理到進階畫中畫合成的 VC 影像開發實戰技巧,可直接應用於視訊監控、醫療影像等系統開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved