반응형

실행중인 모든 프로세스와 현재 포커스를 갖고 있는 프로세스를 조사하고 각 프로세스의 윈도우 사이즈를 구해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.Diagnostics;
using System.Runtime.InteropServices;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string className, string windowName);
        // 이 예제에서는 쓰이지 않았지만 Findwindow()는 아래와 같이 사용하면 된다.
        // IntPtr hwnd = FindWindow(className, windowName);
        // windowName = proc.ProcessName;
        // className = proc.MainWindowTitle;
 
        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
 
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
 
        [DllImport("user32.dll")]
        private static extern int GetWindowRect(IntPtr hWnd, out Rectangle rect);
 
        [DllImport("dwmapi.dll")]
        private static extern int DwmGetWindowAttribute(IntPtr hWnd, int dwAttribute, out Rectangle pvAttribute, int cbAttribute);
        
        public Form1()
        {
            InitializeComponent();
 
            timer1.Interval = 5000// 5초마다 갱신
        }
        
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Process[] processes = Process.GetProcesses();            
            Rectangle rect;
            // GetWindowRect(), DwmGetWindowAttribute()에 의해 rect에는 아래와 같은 값이 들어간다.
            // rect.X = 좌상단 X 좌표
            // rect.Y = 좌상단 T 좌표
            // rect.Width = 우하단 X 좌표 (너비가 아니다)
            // rect.Height = 우하단 Y 좌표 (높이가 아니다)
            int rectangleSize = Marshal.SizeOf(typeof(Rectangle));
            int index;  // Process.GetProcesses()로 조사된 모든 프로세스 중 몇 번째 인지 나타낼 인덱스.
            int row = 0;    // 내용 표시 Y 위치
            string str;
 
            foreach (Process p in processes)
            { 
                // A process has a main window associated with it only if the process has a graphical interface. If the associated process
                // does not have a main window, the MainWindowHandle value is zero. The value is also zero for processes that have been hidden,
                // that is, processes that are not visible in the taskbar. This can be the case for processes that appear as icons in the
                // notification area, at the far right of the taskbar.
                // 테스크 바에 표시되는(보이는) 프로세스만 조사. 윈도우 핸들이 0(IntPtr.Zero)이 아닌 윈도우인데 그렇다고 다 보이는 건 아니다.
                if (p.MainWindowHandle != IntPtr.Zero)
                {
                    index = Array.IndexOf(processes, p); // 비효율적인 배열의 인덱스 가져오기. foreach()말고 for(;;)를 쓰는게 낫다.
                    DwmGetWindowAttribute(p.MainWindowHandle, 9out rect, rectangleSize);
                    // 9 = DWMWA_EXTENDED_FRAME_BOUNDS
                    str = string.Format("[{0}] {1}: ({2}, {3}, {4}, {5})", index, p.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
                    e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
                    row += 15;
                }
            }
            
            // 포커스를 갖고 있는 윈도우(Foreground window) 조사
            uint foregroundProcessID = 0;
            IntPtr foregroundHWnd = GetForegroundWindow(); // Get foreground window handle
            uint threadID = GetWindowThreadProcessId(foregroundHWnd, out foregroundProcessID); // Get PID from window handle
            Process foregroundProcess = Process.GetProcessById(Convert.ToInt32(foregroundProcessID)); // Get it as a C# obj.
 
            // 윈도우 사이즈 조사
            DwmGetWindowAttribute(foregroundHWnd, 9out rect, rectangleSize);
            // 9 = DWMWA_EXTENDED_FRAME_BOUNDS            
            str = string.Format("[Foreground] {0}: ({1}, {2}, {3}, {4})", foregroundProcess.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
            e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
            row += 30;
 
            // Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing.
            // The borders might look like this: 7, 0, 7, 7(left, top, right, bottom)
            // 윈도우 사이즈 조사 시 예전과 같이 GetWindowRect()를 사용하면 보통 7픽셀의 resizing을 위한 테두리가 포함된다.
            e.Graphics.DrawString("[Foreground window with invisible border]", Font, Brushes.Red, 0, row);
            row += 15;
            GetWindowRect(foregroundHWnd, out rect);
            str = string.Format("[Foreground] {0}: ({1}, {2}, {3}, {4})", foregroundProcess.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
            e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            Invalidate();
        }
    }
}
 

 

소스를 입력하고 실행한다.

 

인덱스를 확인하면 수백개의 프로세스가 실행중임을 알 수 있다.

 

GetWindowRect()로 윈도우 사이즈를 구하면 resizing을 위한 보이지 않는 테두리가 포함 되므로 눈에 보이는 정확한 사이즈는 DwmGetWindowAttribute()로 구하자.

 

반응형
Posted by J-sean
:
반응형

Windows 10을 다운로드 하기 위해 Microsoft 소프트웨어 다운로드 페이지로 이동하면 아래와 같은 화면이 나온다.

 

미디어 생성 도구를 다운로드하고 Windows 10을 설치 할 수 있는 화면이다. Windows 10을 바로 다운로드 할 수 있는 링크는 없다.

 

F12키를 누른다(크롬). 개발자 도구 상단 왼쪽 Elements탭 옆 아이콘(Toggle device toolbar)을 클릭한다.

 

화면 상단 중간에 Responsive를 클릭하고 iPad Pro를 선택한다. 화면이 너무 작다면 적당한 크기로 확대(75%) 한다.

 

F5키를 눌러 페이지를 새로 고친다.

 

Windows 10 디스크 이미지 다운로드 페이지가 표시된다. 이 웹페이지는 현재 접속한 기기가 iPad Pro라고 생각하는 것이다. iPad에서는 미디어 생성 도구를 실행 할 수 없기 때문에 Windows 10 디스크 이미지를 바로 다운 받을 수 있게 해 준다.

 

 

버전 선택에서 Windows 10을 선택하고 확인을 클릭한다.

 

제품 언어 선택에서 한국어를 선택하고 확인을 클릭한다.

 

원하는 bit를 선택 한다.

 

다운로드가 진행 된다.

 

반응형
Posted by J-sean
:
반응형

Screen capture with Windows API and OpenCV.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <Windows.h>
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
 
using namespace std;
using namespace cv;
 
class hWnd2Mat
{
public:
    hWnd2Mat(HWND hWindow, float scale = 1);
    virtual ~hWnd2Mat();
    virtual void Read();
    Mat capture;
 
private:
    HWND hWnd;
    HDC hWindowDC, hWindowCompatibleDC;
    int height, width, srcHeight, srcWidth;
    HBITMAP hBitmap;
    BITMAPINFOHEADER bi;
};
 
hWnd2Mat::hWnd2Mat(HWND hWindow, float scale)
{
    hWnd = hWindow;
    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 = (int)(windowsize.bottom * scale);
    width = (int)(windowsize.right * scale);
 
    capture.create(height, width, CV_8UC4);
 
    // create a bitmap
    hBitmap = 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, hBitmap);
};
 
void hWnd2Mat::Read()
{
    // copy from the window device context to the bitmap device context
    StretchBlt(hWindowCompatibleDC, 00, width, height, hWindowDC, 00, srcWidth, srcHeight, SRCCOPY);
    //change SRCCOPY to NOTSRCCOPY for wacky colors!
    GetDIBits(hWindowCompatibleDC, hBitmap, 0, height, capture.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
    //copy from hWindowCompatibleDC to hBitmap
};
 
hWnd2Mat::~hWnd2Mat()
{
    DeleteObject(hBitmap);
    DeleteDC(hWindowCompatibleDC);
    ReleaseDC(hWnd, hWindowDC);
};
 
int main()
{
    HWND hWndDesktop = GetDesktopWindow();
    hWnd2Mat desktop(hWndDesktop, 1);    // scale = 1
 
    cout << "Screen capure in 3 seconds." << endl;
    
    for (int i = 3; i > 0; i--)
    {
        cout << i << ".." << endl;
        Sleep(1000);
    }
 
    desktop.Read();
    imshow("Capture", desktop.capture);
 
    waitKey();
 
    return 0;
}



It captures your desktop image in 3 seconds.


반응형
Posted by J-sean
:
반응형

Build a Windows dialog-based OpenCV program.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <Windows.h>
#include <gdiplus.h>
#include <opencv2/opencv.hpp>
#include "resource.h"
 
#pragma comment(lib, "gdiplus")
 
using namespace cv;
using namespace Gdiplus;
 
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
HWND hDlgMain;
 
VideoCapture cap;
Mat frame;
RECT invalidateRect;


Prepare necessities.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    ULONG_PTR gpToken;
    GdiplusStartupInput gpsi;
 
    if (GdiplusStartup(&gpToken, &gpsi, NULL!= Ok) {
        MessageBox(NULL, TEXT("GDI+ start-up error."), TEXT("GDI+ Error"), MB_OK);
    }
 
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
    
    GdiplusShutdown(gpToken);
 
    return 0;
}


Start GDI+ and create a modal dialog box from a dialog template resource.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool initCamera()
{
    cap.open(0);
    if (cap.isOpened()) {
        invalidateRect = { 00, cvRound(cap.get(CAP_PROP_FRAME_WIDTH)), cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) };
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("Camera open failed."), TEXT("Camera Error"), MB_OK);
 
        return false;
    }    
}


Initiate a camera and set the windows update region.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void OnPaint(HDC hdc)
{
    Graphics G(hdc);
 
    cap >> frame;
    if (frame.empty()) {
        TextOut(hdc, 300240"No frame to show"8);
 
        return;
    }
 
    if (IsDlgButtonChecked(hDlgMain, IDC_CHECK1) == BST_CHECKED) {
        cvtColor(frame, frame, COLOR_BGR2GRAY);
        Canny(frame, frame, 50100);
        cvtColor(frame, frame, COLOR_GRAY2BGRA);
    }
    else {
        cvtColor(frame, frame, COLOR_BGR2BGRA);
    }
 
    Bitmap bitmap(frame.size().width, frame.size().height, frame.step1(), PixelFormat32bppARGB, frame.data);
    G.DrawImage(&bitmap, 00, bitmap.GetWidth(), bitmap.GetHeight());
}


Process each frame and draw it. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static HANDLE hTimer;
 
    switch (iMessage) {
    case WM_INITDIALOG:
        hDlgMain = hDlg;
        if (initCamera()) {
            hTimer = (HANDLE)SetTimer(hDlg, 110NULL);
        }
        else {
            hTimer = NULL;
        }
 
        return TRUE;
 
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
 
            return TRUE;
 
        case IDCANCEL:
            if (hTimer != NULL) {
                KillTimer(hDlg, 1);
            }
            EndDialog(hDlg, IDCANCEL);
 
            return TRUE;
        }
 
    case WM_PAINT:
        hdc = BeginPaint(hDlg, &ps);
        OnPaint(hdc);
        EndPaint(hDlg, &ps);
 
        return TRUE;
 
    case WM_TIMER:
        InvalidateRect(hDlg, &invalidateRect, FALSE);
        return 0;
    }
 
    return FALSE;
}


Create a timer and define the necessary variables and handle window messages.



Run the program.


Check 'Canny Edge Detection'.


반응형
Posted by J-sean
:
반응형

GDI+ Bitmap class inherits from the Image class. The Image class provides methods for loading and saving vector images (metafiles) and raster images (bitmaps). You can build Windows applications with GDI+ and OpenCV.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <windows.h>
#include <gdiplus.h>
#include <opencv2/opencv.hpp>
 
#pragma comment(lib, "gdiplus")
 
using namespace cv;
using namespace Gdiplus;
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCSTR lpszClass = "MatToBitmap";
 
Mat src;    // source image
Mat org;    // original image
Mat dst;    // processed image
 

Prepare necessities.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
 
    ULONG_PTR gpToken;
    GdiplusStartupInput gpsi;
    if (GdiplusStartup(&gpToken, &gpsi, NULL!= Ok) {
        MessageBox(NULL, TEXT("GDI+ start-up error."), TEXT("GDI+ Error"), MB_OK);
 
        return 0;
    }
 
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); //(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hInstance = hInstance;
    WndClass.lpfnWndProc = (WNDPROC)WndProc;
    WndClass.lpszClassName = lpszClass;
    WndClass.lpszMenuName = NULL;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&WndClass);
 
    hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,
        670340NULL, (HMENU)NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
 
    while (GetMessage(&Message, 000)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
 
    GdiplusShutdown(gpToken);
 
    return (int)Message.wParam;
}
 
 

Start GDI+ and change the background color to the radio button color and Window size.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool getFile(PTCHAR filename)
{
    OPENFILENAME ofn;
    memset(&ofn, 0sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    ofn.lpstrFilter = TEXT("all(*.*)\0*.*\0jpg(*.jpg)\0*.jpg\0png(*.png)\0*.png\0bmp(*.bmp)\0*.bmp\0");
    ofn.lpstrFile = filename;
    ofn.nMaxFile = MAX_PATH;
 
    if (GetOpenFileName(&ofn) != 0) {
        //MessageBox(NULL, filename, TEXT("File opened."), MB_OK);
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("File open failed"), TEXT("No file selected"), MB_OK);
 
        return false;
    }
}
 
 

Retrieve an image file name.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool ImageLoad()
{
    TCHAR filename[MAX_PATH] = "";
 
    if (getFile(filename)) {
        src = imread(filename);
        if (src.empty()) {
            MessageBox(NULL, TEXT("Image load failed"), TEXT("No image loaded"), MB_OK);
 
            return false;
        }
 
        return true;
    }
    else {
        return false;
    }
}
 
 

Read the image from the file.

 

1
2
3
4
5
6
7
8
void ImageResize()
{
    // maximum image display size: 320 X 240 with original ratio
    double ratio = min((double)320 / (double)src.size().width, (double)240 / (double)src.size().height);
    resize(src, src, cv::Size(), ratio, ratio);
    org = src.clone();
    cvtColor(org, org, COLOR_BGR2BGRA);
}
 
 

Resize an image.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void ImageProcess(int direction)
{
    cvtColor(src, dst, COLOR_BGR2GRAY);
 
    float vertical[] = {
        -202,
        -202,
        -202
    };
 
    float horizontal[] = {
        -2-2-2,
        000,
        222
    };
 
    float diagonal[] = {
        -2-20,
        -202,
        022
    };
    
    Mat emboss;
    switch (direction)
    {
    case 0:
        emboss = Mat(33, CV_32FC1, vertical);
 
        break;
 
    case 1:
        emboss = Mat(33, CV_32FC1, horizontal);
 
        break;
 
    case 2:
        emboss = Mat(33, CV_32FC1, diagonal);
 
        break;
 
    default:
        emboss = Mat(33, CV_32FC1, vertical);
    }
    filter2D(dst, dst, -1, emboss, cv::Point(-1-1), 128);
    
    cvtColor(dst, dst, COLOR_GRAY2BGRA);
}
 
 

Process an image with embossing filter.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void OnPaint(HDC hdc)
{
    if (!dst.empty()) {
        Graphics G(hdc);
 
        Bitmap bitmapDst(dst.size().width, dst.size().height, dst.step, PixelFormat32bppARGB, dst.data);
        Bitmap bitmapOrg(org.size().width, org.size().height, org.step, PixelFormat32bppARGB, org.data);
        // stride(src.step): Integer that specifies the byte offset between the beginning of one scan line and
        // the next. This is usually(but not necessarily) the number of bytes in the pixel format(for example,
        // 2 for 16 bits per pixel) multiplied by the width of the bitmap. The value passed to this parameter
        // must be a multiple of four.
 
        G.DrawImage(&bitmapDst, 00, bitmapDst.GetWidth(), bitmapDst.GetHeight());
        G.DrawImage(&bitmapOrg, bitmapOrg.GetWidth() + 100, bitmapOrg.GetWidth(), bitmapOrg.GetHeight());
    }
    else {
        TextOut(hdc, 270110, TEXT("No image to display"), 19);
    }
}
 
 

Draw original and processed images.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
enum { ID_R1 = 101, ID_R2, ID_R3 };
HWND r1, r2, r3;
int x = 10;
int y = 270;
int w = 90;
int h = 20;
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;    
 
    switch (iMessage) {
    case WM_CREATE:
        if (ImageLoad()) {
            ImageResize();
            ImageProcess(0);
        }
        
        CreateWindow(TEXT("button"), TEXT("Filter type"), WS_CHILD | WS_VISIBLE |
            BS_GROUPBOX, 525029050, hWnd, (HMENU)0, g_hInst, NULL);
 
        r1 = CreateWindow(TEXT("button"), TEXT("Vertical"), WS_CHILD | WS_VISIBLE |
            BS_AUTORADIOBUTTON | WS_GROUP, x, y, w, h, hWnd, (HMENU)ID_R1, g_hInst, NULL);
 
        r2 = CreateWindow(TEXT("button"), TEXT("Horizontal"), WS_CHILD | WS_VISIBLE |
            BS_AUTORADIOBUTTON, x + 90, y, w, h, hWnd, (HMENU)ID_R2, g_hInst, NULL);
 
        r3 = CreateWindow(TEXT("button"), TEXT("Diagonal"), WS_CHILD | WS_VISIBLE |
            BS_AUTORADIOBUTTON, x + 180, y, w, h, hWnd, (HMENU)ID_R3, g_hInst, NULL);
 
        CheckRadioButton(hWnd, ID_R1, ID_R3, ID_R1);
 
        return 0;
 
    case WM_COMMAND:
        if (!dst.empty()) {
            switch (LOWORD(wParam)) {
            case ID_R1:
                ImageProcess(0);
                break;
 
            case ID_R2:
                ImageProcess(1);
                break;
 
            case ID_R3:
                ImageProcess(2);
                break;
            }
 
            InvalidateRect(hWnd, NULL, TRUE);
        }
 
        return 0;
 
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        OnPaint(hdc);
        EndPaint(hWnd, &ps);
 
        return 0;
 
    case WM_DESTROY:
        PostQuitMessage(0);
 
        return 0;
    }
 
    return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
 
 

Define the necessary variables and handle window messages.

 

 

Run the application and select an image file.

 

Processed and original image with a vertical filter.

 

Processed and original image with a horizontal filter.

 

Processed and original image with a diagonal filter.

 

 

반응형
Posted by J-sean
:
반응형

Build a windows dialog-based OpenCV perspective transform program.


Change Subsystem setting from Console to Windows if necessary.


Add a resource and create a dialog box.


Include and declare necessities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <Windows.h>
#include <opencv2/opencv.hpp>
#include "resource.h"
 
using namespace cv;
 
bool getFile(PTCHAR filename);
void onMouse(int event, int x, int y, int flags, void* userdata);
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
 
HWND hDlgMain;
 
Mat sourceImage;
Mat targetImage;
// TTC card ratio
int width = 850;
int height = 550;
Point2f srcQuad[4], dstQuad[4];



Define WinMain which calls getFile() and DialogBox().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    TCHAR filename[MAX_PATH] = "";
    if (!getFile(filename)) {
        return -1;
    }
 
    sourceImage = imread(filename);
    if (sourceImage.empty()) {
        MessageBox(NULL, TEXT("Image load failed"), TEXT("No image loaded"), MB_OK);
 
        return -1;
    }
 
    namedWindow("sourceImage");
    setMouseCallback("sourceImage", onMouse);
 
    imshow("sourceImage", sourceImage);
 
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
 
    return 0;
}



getFile() retrieves an image file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool getFile(PTCHAR filename)
{
    OPENFILENAME ofn;
    memset(&ofn, 0sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    ofn.lpstrFilter = TEXT("all(*.*)\0*.*\0jpg(*.jpg)\0*.jpg\0png(*.png)\0*.png\0bmp(*.bmp)\0*.bmp\0");
    ofn.lpstrFile = filename;
    ofn.nMaxFile = MAX_PATH;
 
    if (GetOpenFileName(&ofn) != 0) {
        //MessageBox(NULL, filename, TEXT("File opened."), MB_OK);
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("File open failed"), TEXT("No file selected"), MB_OK);
 
        return false;
    }
}



Define a mouse callback function that processes perspective transform.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void onMouse(int event, int x, int y, int flags, void* userdata)
{
    static int cnt = 0;
 
    if (event == EVENT_LBUTTONDOWN) {
        if (cnt < 4) {
            srcQuad[cnt++= Point2f(x, y);
 
            circle(sourceImage, Point2f(x, y), 3, Scalar(00255), -1);
            imshow("sourceImage", sourceImage);
 
            if (cnt == 4) {
                /*
                width = max(
                    sqrt(pow(srcQuad[0].x - srcQuad[1].x, 2)) + sqrt(pow(srcQuad[0].y - srcQuad[1].y, 2)),
                    sqrt(pow(srcQuad[2].x - srcQuad[3].x, 2)) + sqrt(pow(srcQuad[2].y - srcQuad[3].y, 2))
                );
                height = max(
                    sqrt(pow(srcQuad[1].x - srcQuad[2].x, 2)) + sqrt(pow(srcQuad[1].y - srcQuad[2].y, 2)),
                    sqrt(pow(srcQuad[3].x - srcQuad[0].x, 2)) + sqrt(pow(srcQuad[3].y - srcQuad[0].y, 2))
                );
                */            
 
                dstQuad[0= Point2f(00);
                dstQuad[1= Point2f(width - 10);
                dstQuad[2= Point2f(width - 1, height - 1);
                dstQuad[3= Point2f(0, height - 1);
 
                Mat perspectiveTransform = getPerspectiveTransform(srcQuad, dstQuad);
 
                warpPerspective(sourceImage, targetImage, perspectiveTransform, Size(width, height));
 
                cnt = 0;
                
                imshow("targetImage", targetImage);
            }
        }
    }
}



Dialog box procedure sets and/or retrieves target image width and height value from the dialog. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    switch (iMessage) {
    case WM_INITDIALOG:
        hDlgMain = hDlg;
        SetDlgItemInt(hDlg, IDC_WIDTH, width, FALSE);
        SetDlgItemInt(hDlg, IDC_HEIGHT, height, FALSE);
 
        return TRUE;
 
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
            width = GetDlgItemInt(hDlg, IDC_WIDTH, NULL, FALSE);
            height = GetDlgItemInt(hDlg, IDC_HEIGHT, NULL, FALSE);
 
            return TRUE;
 
        case IDCLOSE:
            EndDialog(hDlg, IDOK);
 
            return TRUE;
        }
    }
 
    return FALSE;
}




Run the program and select an image file.


You can change the target image size or just leave it.


Source image window.


Choose four corners from the left-top to clockwise.


Perspective transform processed image.


반응형
Posted by J-sean
: