隨著軟硬體飛速發展,人類進入高速資訊時代,約 80% 資訊源自影像。軍事、醫療、工業監控、自動辨識等領域均需即時、逼真的動態影像。本文分享基於 VC 開發平台整合影像採集卡的實戰經驗,並實作「畫中畫」功能。
電腦影像系統分高中低三檔,普及型為低階:CCD 攝影機 + 影像採集卡 + 電腦。結構簡單、應用方便、影像清晰。筆者採用台灣 BENTECH CV-155L 白黑攝影機 (752×582) 與中科院科技嘉 CA-MPE1000 PCI 白黑採集卡。
VxD.vxd 複製至 Windows SYSTEM 目錄。mpew32.dll / mpew32.lib,引用初始化硬體、採集影像等函式。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 影像開發實戰技巧,可直接應用於視訊監控、醫療影像等系統開發。