2016-04-19 31 views
0

OPENCV Destop Captureとこのhwnd2matの機能に加えて、opencvのソースとしてデスクトップをキャプチャする方法は、このhwnd2mat機能を使用して画面イメージからビットマップを作成します。完了しました。 この機能は既に画面イメージからビットマップを作成しています。しかし、ビデオ内に後ろのような奇妙なエフェクトを与えます。普通のビデオソースのほうがthis oneのようになります。私はすでに原因を見つけることを試みたが、私はもはや知らない。OPENCVデスクトップキャプチャパートII

#include "opencv2/imgproc.hpp" 
#include "opencv2/highgui.hpp" 
#include <Windows.h> 
#include <iostream> 

using namespace std; 
using namespace cv; 

Mat hwnd2mat(HWND hwnd) 
{ 
    HDC hwindowDC, hwindowCompatibleDC; 

    int height, width, srcheight, srcwidth; 
    HBITMAP hbwindow; 
    Mat src; 
    BITMAPINFOHEADER bi; 

    hwindowDC = GetDC(hwnd); 
    hwindowCompatibleDC = CreateCompatibleDC(hwindowDC); 
    SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR); 

    RECT windowsize; // get the height and width of the screen 
    GetClientRect(hwnd, &windowsize); 

    srcheight = windowsize.bottom; 
    srcwidth = windowsize.right; 
    height = windowsize.bottom/1; //change this to whatever size you want to resize to 
    width = windowsize.right/1; 

    src.create(height, width, CV_8UC4); 

    // create a bitmap 
    hbwindow = CreateCompatibleBitmap(hwindowDC, width, height); 
    bi.biSize = sizeof(BITMAPINFOHEADER); //http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx 
    bi.biWidth = width; 
    bi.biHeight = -height; //this is the line that makes it draw upside down or not 
    bi.biPlanes = 1; 
    bi.biBitCount = 32; 
    bi.biCompression = BI_RGB; 
    bi.biSizeImage = 0; 
    bi.biXPelsPerMeter = 0; 
    bi.biYPelsPerMeter = 0; 
    bi.biClrUsed = 0; 
    bi.biClrImportant = 0; 

    // use the previously created device context with the bitmap 
    SelectObject(hwindowCompatibleDC, hbwindow); 
    // copy from the window device context to the bitmap device context 
    StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 0, 0, srcwidth, srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors ! 
    GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO *)&bi, DIB_RGB_COLORS); //copy from hwindowCompatibleDC to hbwindow 

    // avoid memory leak 
    DeleteObject(hbwindow); 
    DeleteDC(hwindowCompatibleDC); 
    ReleaseDC(hwnd, hwindowDC); 

    return src; 
} 

int main(int argc, char **argv) 
{ 
    HWND hwndDesktop = GetDesktopWindow(); 
    namedWindow("output", CV_WINDOW_NORMAL); 
    int key = 0; 

    while (key != 30) 
    { 
     Mat src = hwnd2mat(hwndDesktop);   
     // you can do some image processing here 
     imshow("output", src); 
     key = waitKey(30); // you can change wait time 
    } 
    ReleaseCapture(); 
    destroyAllWindows(); 
    return 0; 
} 
+0

奇妙なエフェクトは次のようなものです:https://www.youtube.com/watch?v=RQePoFEUS3A&feature=youtu.be、あなたは何が起こったのか教えてもらえますか? –

+1

あなたは画面全体をキャプチャしたくないですがただ1つのウィンドウ?画面全体をキャプチャすると、明らかに出力イメージをキャプチャして、その無限ミラー効果につながります。 GetDesktopWindowの代わりに、キャプチャしたいウィンドウのハンドルにアクセスしてください。 – Micka

+0

@Micka ok、私はアイデアを得る、私はキャプチャしたいウィンドウのハンドルを見つける必要がありますが、それは 'GetDesktopWindow'ではなく何ですか? –

答えて

0
キャプチャを望むものウィンドウ使用して、無限のミラー効果を作り、代わりにそのうGetDesktopWindow()を使用

、と私は、私はFindWindowEx()を使用しています、そして、あなたがしたいものを窓見つけるために、++スパイを使用しますキャプチャ、それは動作するはずです。しかし、もちろんそれは次のバグに行くでしょう:)。