DY N DY

opencvsharp WPF연동하여 webcam출력 본문

PARK/영상처리 관련

opencvsharp WPF연동하여 webcam출력

손세지 2016. 12. 1. 00:05

개인적으로 WPF를 잠깐 써본적도 있고... 툴도 만들 계획이므로 opencv wrapper인 opencvsharp을 연동해 보았다.


Visual Studio 2015 / opencvsharp 3.1기준


아마 2015버전의 VS를 사용한다면 nuget 패키지 매니저가 설치되어 있을 것이다.

(아마 설치할때 디폴트 옵션을 사용했던가.. 추가로 설치한 적은 없으니 아마... 그럴 것..)


opencvsharp github (https://github.com/shimat/opencvsharp)를 들어가 보면(2016.11월 기준) 

3.1까지 지원을 한다. 

opencv최신버전을 모두 지원한다.


nuget을 이용하여 설치를 누르면 설치하는 방법이 나오는데 아래와 같다. 



한글 VS 기준으로 도구 -> NuGet 패키지 관리자 -> 패키지 관리자 콘솔을 눌러 패키지 관리자 콘솔을 연다.


콘솔에 다음과 같이 입력한다.

1
Install-Package OpenCvSharp3-AnyCPU
cs



설치 및 프로젝트 세팅 완료



영상을 imshow를 이용한 것과 Grid안에 둘다 띄어보기 위해 xaml파일에 image와 button을 추가하고 

button click, window loded, closing 이벤트를 추가한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Window x:Class="opencv_wpf_conn_test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:opencv_wpf_conn_test"
        mc:Ignorable="d"
        Title="MainWindow" Height="503.538" Width="691.839"
        Loaded="Window_Loaded" Closing="Window_Closing">
    <Grid>
        <Image x:Name="image" Height="411" Margin="16,10,6,0" VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="583,443,0,0" VerticalAlignment="Top" Width="74" Click="button_Click"/>
 
    </Grid>
</Window>
 
cs



코드는 아래와 같이 OpencvSharp, OpencvSharp.Extensions를 using해준다. 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
using OpenCvSharp;
using OpenCvSharp.Extensions;
 
namespace opencv_wpf_conn_test
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : System.Windows.Window
    {
        VideoCapture cap;
        WriteableBitmap wb;
        const int frameWidth = 640;
        const int frameHeight = 480;
        bool loop = false;
 
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (InitWebCamera())
            {
                MessageBox.Show("웹캠켜짐.");
            }
            else
            {
                MessageBox.Show("웹캠에 문제가 있습니다.");
            }
        }
 
        private bool InitWebCamera()
        {
            try
            {
                cap = VideoCapture.FromCamera(CaptureDevice.Any, 0);
                cap.FrameWidth = frameWidth;
                cap.FrameHeight = frameHeight;
                cap.Open(0);
                wb = new WriteableBitmap(cap.FrameWidth, cap.FrameHeight, 9696, PixelFormats.Bgr24, null);
                image.Source = wb;
 
                return true;
            }
            catch
            {
                return false;
            }
        }
 
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            loop = false;
            if (cap.IsOpened())
            {
                cap.Dispose();
            }
        }
 
     
 
        private void button_Click(object sender, RoutedEventArgs e)
        {
            Mat frame = new Mat();
            Cv2.NamedWindow("1", WindowMode.AutoSize);
            loop = true;
            while (loop)
            {
 
 
                if (cap.Read(frame))
                {
                    Cv2.ImShow("1", frame);
                    WriteableBitmapConverter.ToWriteableBitmap(frame, wb);
                    image.Source = wb;
                }
 
                int c = Cv2.WaitKey(10);
                if (c != -1)
                    break;
 
            }
        }
    }
}
 
cs


24라인에서 Window를 명시적으로 써준 것은 OpencvSharp과 충돌이 나기 때문이다.

OpencvSharp에서는 기존의 Opencv함수들을 Cv2 Class를 이용해 사용할 수 있는것 같다. 

*MSI노트북의 경우 웹캠을 켜주는 버튼(이 노트북의 경우 Fn+f6이었다.)을 먼저 눌러 웹캠을 켜야 한다..(한참 헤멤..)

VideoCapture를 이용해 웹캠에서 영상을 받아오고

WriteableBitap으로 받아온 Mat을 바꿔준 후 image에 넣어주고, Mat을 imshow로 보여주면 아래와 같은 실행화면을 볼 수 있다.