반응형

충돌 감지 영역을 원으로 지정하고 스프라이트 충돌을 확인해 보자.

 

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
105
106
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
 
class Player(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.direction = -1
        self.speed = 4
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*1.5self.image.get_height()*1.5)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        # rectangle이 아닌 circle을 이용해 충돌 감지하기 위한 반지름 속성 설정.
        self.radius = 40
        # 충돌 감지 circle 표시
        pygame.draw.circle(self.image, "red"self.image.get_rect().center, self.radius, 2)
 
    def flip_image(self):
        self.image = pygame.transform.flip(self.image, TrueFalse)
        
    def update(self):
        pass
# 플레이어 클래스
 
class Bubble(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.image = pygame.image.load("bubble.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*6self.image.get_height()*6)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        self.collided = False
        # rectangle이 아닌 circle을 이용해 충돌 감지하기 위한 반지름 속성 설정.
        self.radius = 40
        # 충돌 감지 circle 표시
        pygame.draw.circle(self.image, "red"self.image.get_rect().center, self.radius, 2)
 
    def update(self):
        if self.collided == True:
            self.rect.top -= 1
# 버블 클래스
# 충돌(self.collided)을 감지하면 위치(self.rect.top)가 변한다.
 
def main():
    player = Player((screen.get_width()/2, screen.get_height()/2))
    player_sprite = pygame.sprite.Group(player)
    # 플레이어 스프라이트 그룹
 
    bubbles = [
        Bubble((40, screen.get_height()/2)),
        Bubble((160, screen.get_height()/2)),
        Bubble((480, screen.get_height()/2)),
        Bubble((600, screen.get_height()/2))]
    bubble_sprites = pygame.sprite.Group(bubbles)
    # 버블 스프라이트 그룹
 
    running = True
 
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                running = False
 
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            if player.direction > 0:
                player.flip_image()
                player.direction = -1
            player.rect.move_ip(-player.speed, 0)
        if keys[pygame.K_RIGHT]:
            if player.direction < 0:
                player.flip_image()
                player.direction = 1
            player.rect.move_ip(player.speed, 0)
 
        # spritecollide()의 마지막 인수 collided에 collide_circle()를 대입한다.
        collision = pygame.sprite.spritecollide(player, bubble_sprites, False, pygame.sprite.collide_circle)
        for bubble in collision:
            bubble.collided = True
        # 플레이어와 버블의 충돌을 감지하고 충돌한 버블의 collided 값을 True로 바꾼다.
        
        player_sprite.update()
        bubble_sprites.update()
                 
        screen.fill("black")
         
        player_sprite.draw(screen)
        bubble_sprites.draw(screen)
    
        pygame.display.flip()
        clock.tick(60)
 
    pygame.quit()
 
if __name__ == '__main__':
  main()
 

 

 

공룡과 버블의 충돌 감지 영역이 빨간 원으로 표시된다.

 

좀 더 확실한 확인을 위해 공룡과 버블의 충돌 감지 circle의 radius를 20으로 바꾸고 다시 실행해 보자.

 

스프라이트는 충돌 했지만 원은 충돌하지 않았기 때문에 충돌로 판정되지 않는다.

 

 

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

스프라이트 그룹의 충돌을 감지해 보자.

 

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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
 
class Player(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.direction = -1
        self.speed = 4
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*1.5self.image.get_height()*1.5)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
 
    def flip_image(self):
        self.image = pygame.transform.flip(self.image, TrueFalse)
        
    def update(self):
        pass
# 플레이어 클래스
 
class Bubble(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
 
        self.image = pygame.image.load("bubble.png").convert()
        self.image.set_colorkey(self.image.get_at((00)))
        self.size = (self.image.get_width()*6self.image.get_height()*6)
        self.image = pygame.transform.scale(self.image, self.size)
        self.rect = self.image.get_rect(center=position)
        self.collided = False
 
    def update(self):
        if self.collided == True:
            self.rect.top -= 1
# 버블 클래스
# 충돌(self.collided)을 감지하면 위치(self.rect.top)가 변한다.
 
def main():
    player = Player((screen.get_width()/2, screen.get_height()/2))
    player_sprite = pygame.sprite.Group(player)
    # 플레이어 스프라이트 그룹
 
    bubbles = [
        Bubble((40, screen.get_height()/2)),
        Bubble((160, screen.get_height()/2)),
        Bubble((480, screen.get_height()/2)),
        Bubble((600, screen.get_height()/2))]
    bubble_sprites = pygame.sprite.Group(bubbles)
    # 버블 스프라이트 그룹
 
    running = True
 
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                running = False
 
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            if player.direction > 0:
                player.flip_image()
                player.direction = -1
            player.rect.move_ip(-player.speed, 0)
        if keys[pygame.K_RIGHT]:
            if player.direction < 0:
                player.flip_image()
                player.direction = 1
            player.rect.move_ip(player.speed, 0)
 
        collision = pygame.sprite.spritecollide(player, bubble_sprites, False)
        for bubble in collision:
            bubble.collided = True
        # 플레이어와 버블의 충돌을 감지하고 충돌한 버블의 collided 값을 True로 바꾼다.
 
        player_sprite.update()
        bubble_sprites.update()
 
        screen.fill("black")
        player_sprite.draw(screen)
        bubble_sprites.draw(screen)
    
        pygame.display.flip()
        clock.tick(60)
 
    pygame.quit()
 
if __name__ == '__main__':
   main()
 

 

 

공룡과 충돌한 버블은 하늘로 올라간다.

※ 참고

pygame.sprite.spritecollideany()
Simple test if a sprite intersects anything in a group.
● spritecollideany(sprite, group, collided = None) -> Sprite Collision with the returned sprite.
● spritecollideany(sprite, group, collided = None) -> None No collision
If the sprite collides with any single sprite in the group, a single sprite from the group is returned. On no collision None is returned.

If you don't need all the features of the pygame.sprite.spritecollide() function, this function will be a bit quicker.

The collided argument is a callback function used to calculate if two sprites are colliding. It should take two sprites as values and return a bool value indicating if they are colliding. If collided is not passed, then all sprites must have a "rect" value, which is a rectangle of the sprite area, which will be used to calculate the collision.

 

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

캐릭터의 충돌을 감지하고 표시해 보자.

 

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
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
running = True
# pygame 세팅
 
player = pygame.image.load("player.png").convert()
player.set_colorkey(player.get_at((00)))
player_size = (player.get_width()*1.5, player.get_height()*1.5)
player = pygame.transform.scale(player, player_size)
player_pos = player.get_rect()
player_pos.center = (screen.get_width()/2, screen.get_height()/2)
player_speed = 4
player_direction = -1
# player 세팅
 
enemy = pygame.image.load("enemy.png").convert()
enemy.set_colorkey(enemy.get_at((00)))
enemy_size = (enemy.get_width()*1.5, enemy.get_height()*1.5)
enemy = pygame.transform.scale(enemy, enemy_size)
enemy_pos = enemy.get_rect(center=(500, screen.get_height()/2))
# enemy 세팅
 
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
 
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        if player_direction > 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = -1            
        player_pos.move_ip(-player_speed, 0)
    if keys[pygame.K_RIGHT]:
        if player_direction < 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = 1
        player_pos.move_ip(player_speed, 0)
 
    hitbox = player.get_rect(center=player_pos.center)
    hitbox = hitbox.inflate(-10-10)
    # 분명한 충돌 판정을 위해 player hitbox의 범위를 줄여준다.
 
    clip = None
    if hitbox.colliderect(enemy.get_rect(center=enemy_pos.center)):
        print("collide")
        clip = hitbox.clip(enemy.get_rect(center=enemy_pos.center))
        print(clip)
    # player와 enemy가 충돌하면 "collide" 메세지를 출력하고 충돌 영역은
    # clip에 저장한다.
 
    screen.fill("black")
    screen.blit(player, player_pos)
    screen.blit(enemy, enemy_pos)
    if clip is not None:
        pygame.draw.rect(screen, "blue", clip)
    # player와 enemy가 충돌한 영역이 clip에 저장되었다면 파란 사각형으로
    # 표시힌다.
 
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
 

 

 

player.png

 

enemy.png

 

충돌 영역이 파란 사각형으로 표시된다.

 

충돌 영역 좌표가 표시된다.

 

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

2022.04.05 - [C#] - C# Joystick(Gamepad) Input Check - 조이스틱(게임패드) 입력 확인 1 의 내용을 참고하여 조금 더 간단히 조이스틱(게임패드) 입력을 확인해 보자.

 

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using System.Threading;
using System.Diagnostics;
 
using HidSharp;
using HidSharp.Utility;
using HidSharp.Reports;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            HidSharpDiagnostics.EnableTracing = true;
            HidSharpDiagnostics.PerformStrictChecks = true;
 
            DeviceList list = DeviceList.Local;
            list.Changed += (sender, e) => Console.WriteLine("Device list changed.");
 
            HidDevice[] hidDeviceList = list.GetHidDevices().ToArray();
 
            foreach (HidDevice dev in hidDeviceList)
            {
                if (!dev.ToString().Contains("gamepad"))
                {
                    Console.WriteLine(dev.GetProductName() + " is not a gamepad.");
                    continue;
                }
 
                try
                {
                    ReportDescriptor reportDescriptor = dev.GetReportDescriptor();
 
                    Debug.Assert(dev.GetMaxInputReportLength() == reportDescriptor.MaxInputReportLength);
                    Debug.Assert(dev.GetMaxOutputReportLength() == reportDescriptor.MaxOutputReportLength);
                    Debug.Assert(dev.GetMaxFeatureReportLength() == reportDescriptor.MaxFeatureReportLength);
 
                    foreach (DeviceItem deviceItem in reportDescriptor.DeviceItems)
                    {
                        {
                            HidStream hidStream;
                            if (dev.TryOpen(out hidStream))
                            {
                                Console.WriteLine(dev.GetProductName() + " opened.");
                                hidStream.ReadTimeout = Timeout.Infinite;
 
                                using (hidStream)
                                {
                                    byte[] inputReportBuffer = new byte[dev.GetMaxInputReportLength()];
                                    HidSharp.Reports.Input.HidDeviceInputReceiver inputReceiver =
                                        reportDescriptor.CreateHidDeviceInputReceiver();
                                    HidSharp.Reports.Input.DeviceItemInputParser inputParser =
                                        deviceItem.CreateDeviceItemInputParser();
 
                                    inputReceiver.Start(hidStream);
 
                                    while (true)
                                    {
                                        if (inputReceiver.WaitHandle.WaitOne(1000))
                                        {
                                            if (!inputReceiver.IsRunning) { break; } // Disconnected?
 
                                            Report report;
                                            while (inputReceiver.TryRead(inputReportBuffer, 0out report))
                                            {
                                                if (inputParser.TryParseReport(inputReportBuffer, 0, report) && inputParser.HasChanged)
                                                {
                                                    //inputParser.HasChanged는 버튼을 누르거나 놓는 등 상태가 변경되는 경우를 뜻한다.
 
                                                    //Console.WriteLine(BitConverter.ToString(inputReportBuffer));
 
                                                    if (inputReportBuffer[3== 0x00)
                                                    {
                                                        Console.WriteLine("Left");
                                                    }
                                                    else if (inputReportBuffer[3== 0xFF)
                                                    {
                                                        Console.WriteLine("Right");
                                                    }
                                                    else if (inputReportBuffer[4== 0x00)
                                                    {
                                                        Console.WriteLine("Up");
                                                    }
                                                    else if (inputReportBuffer[4== 0xFF)
                                                    {
                                                        Console.WriteLine("Down");
                                                    }
                                                    else if (inputReportBuffer[5== 0x1F)
                                                    {
                                                        Console.WriteLine("X");
                                                    }
                                                    else if (inputReportBuffer[5== 0x2F)
                                                    {
                                                        Console.WriteLine("A");
                                                    }
                                                    else if (inputReportBuffer[5== 0x4F)
                                                    {
                                                        Console.WriteLine("B");
                                                    }
                                                    else if (inputReportBuffer[5== 0x8F)
                                                    {
                                                        Console.WriteLine("Y");
                                                    }
                                                    else if (inputReportBuffer[6== 0x01)
                                                    {
                                                        Console.WriteLine("L Shoulder");
                                                    }
                                                    else if (inputReportBuffer[6== 0x02)
                                                    {
                                                        Console.WriteLine("R Shoulder");
                                                    }
                                                    else if (inputReportBuffer[6== 0x10)
                                                    {
                                                        Console.WriteLine("Select");
                                                    }
                                                    else if (inputReportBuffer[6== 0x20)
                                                    {
                                                        Console.WriteLine("Start");
                                                    }
                                                }
                                            }
                                        }
 
                                        if (Console.KeyAvailable)
                                        {
                                            ConsoleKeyInfo consoleKeyInfo = Console.ReadKey(true);
 
                                            if (consoleKeyInfo.Key == ConsoleKey.Escape)
                                            {
                                                Console.WriteLine("User stopped.");
                                                break;
                                                //hidStream.Close();
                                            }
                                        }
                                    }
                                }
 
                                Console.WriteLine("Gamepad closed.");
                            }
                            else
                            {
                                Console.WriteLine("Failed to open device.");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

 

프로그램을 실행하고 게임패드의 버튼을 누르면 어떤 버튼이 눌리는지 표시된다.

 

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

예전 영화에서 종종 볼 수 있던 레이저 침입 감지 시스템은 간단한 작동 원리에도 불구하고 레이저를 이용 한 방식이 뭔가 있어 보이는지 아직까지도 영화나 드라마에서 심심치 않게 볼 수 있다. 작동 원리가 간단한 만큼 저렴한 부품으로도 비슷하게 만들어 볼 수 있다.


침입 감지 시스템을 회피하기 위한 Catherine Zeta-Jones의 피나는 노력 (영화 Entrapment)


The Big Bang Theory


약 $0.4 짜리 레이저 모듈. 5V로 작동하고 출력 5mW, 파장 650nm의 붉은색 레이저를 발생 시킨다.


Red 

625 - 740nm

Orange

590 - 625nm

Yellow

565 - 590nm

Green

520 - 565nm

Cyan

500 - 520nm

Blue

435 - 500nm

Violet

380 - 435nm


약 $0.7 짜리 레이저 수신 모듈. 5V로 작동하고, 레이저가 수신 될때는 HIGH 시그널을, 수신 되지 않을때는 LOW 시그널을 출력 한다. 수신하려는 레이저 외, 태양이나 다른 강한 빛이 없는 실내용.



레이저 리시버 센서는 방향에 주의 한다. 반대로 연결하면 뜨거울 정도로 열이 발생 한다.


위 다이어그램과 같이 구성 한다.


레이저 모듈에서 레이저가 발생되고 수신 모듈에서 이 레이저를 감지하면 HIGH 시그널을 출력 한다.


중간에 장애물이 생겨 레이저를 수신하지 못하게 되면 수신 모듈에서 LOW 시그널을 출력하고 아두이노는 디지털 4번 핀으로 HIGH를 출력해 Buzzer를 작동 시킨다.



실제 부품의 연결 방식은 다이어그램과 다르지만 기본 구성은 동일 하다. 


소스를 컴파일하고 아두이노에 업로드 한다.


제작 과정 및 테스트


Serial Monitor에도 적의 침입 기록이 남는다.


반응형
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
:
반응형

Detects motions in the vision and saves an image of it as a PNG file. Adjust the sensitivity value if needed.


카메라 영상의 움직임을 감시하고 움직임이 감지된 순간의 영상을 저장한다. sensitivity 값으로 감도를 조절한다.


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
#include <opencv2/opencv.hpp>
 
using namespace std;
using namespace cv;
 
int main(int argc, char** argv)
{
    VideoCapture cap(0);
 
    Mat frameNew;
    Mat frameOld;
    Mat frameDiff;
 
    double min, max;
    int sensitivity = 100;
    int detectionCount = 0;
 
    cap >> frameOld;
 
    while (true)
    {
        cap >> frameNew;
        if (frameNew.empty())
            break;
 
        // Calculates the per-element absolute difference
        // between two arrays or between an array and a scalar.
        absdiff(frameNew, frameOld, frameDiff);
        cvtColor(frameDiff, frameDiff, COLOR_BGR2GRAY);
        minMaxLoc(frameDiff, &min, &max);
 
        if (max > sensitivity)
        {
            cout << "Motion detected. (Max: " << max << ")" << endl;
 
            // For PNG, it can be the compression level from 0 to 9.
            // A higher value means a smaller size and longer compression time.
            vector<int> compression_params;
            compression_params.push_back(IMWRITE_PNG_COMPRESSION);
            compression_params.push_back(3);
            if (imwrite(format("detection_%03d.png", detectionCount++), frameNew, compression_params))
                cout << "Image saved." << endl;
            else
                cout << "Image not saved." << endl;
        }
 
        imshow("Motion Detectoion", frameDiff);
        
        frameNew.copyTo(frameOld);
 
        if (waitKey(10== 27)
            break;
    }
 
    return 0;
}
cs



<frameDiff>


<Detection_XXX.png>




반응형
Posted by J-sean
: