간단한 cctv 프로그램이 필요해져서 관련기술을 찾아보니
웹 카메라를 제어하는 기술은 크게
openCV 와 directshow 등이 사용되고 있었다.
openCV는 오픈소스기반의 프로젝트로 자바, 파이썬 등등의 여러 언어에서 사용할 수 있으며,
directshow는 MS에서 제공하는 윈도우에서 사용하는 라이브러리 이다.
openCV는 관련책들이 c++ 과 python 에서 사용하는 방식으로 설명되어 있는데
닷넷(C#) 으로 개발된 프로젝트에 카메라 제어 기능을 넣기 위해서 다양한 방법을 알아보던 중,
최신버전(CV 4.0) 에서 실행되는 예제가 정리 되어 있는게 없어서 정리해 본다.
1. 준비물
MS Visual Studio Community 버전 ( 개인 및 교육용 무료 )
https://visualstudio.microsoft.com/ko/thank-you-downloading-visual-studio/?sku=Community&rel=15&rr=https%3A%2F%2Fdocs.microsoft.com%2Fko-kr%2Fvisualstudio%2Freleasenotes%2Fvs2017-relnotes
2. 개발환경
1) Visual Studio C# community 버전을 설치한 후 프로젝트를 하나 생성한다.
2) 프로젝트 메뉴 -> NuGet 패키지 관리로 들어간다.
3) 찾아보기 에서 opencv 를 검색하면 작성자 shimat 로 된 OpenCvSharp3 - AnyCPU 가 나올 것이다.
제일 최신버전인 v4.0 대로 설치 한다.
4) 폼 디자인 창에서 폼 디자인을 해주자
4.0 에서는 구버전에서 쓰던 pictureboxlpl 대신에 picture box 를 쓸수 있다.
폼에 picture box 와 command 버튼, text box 하나를 놓아주자
picturebox 의 size 속성을 680,480 으로 지정한다.
Button의 Text 속성을 Start로 지정한다.
textbox 의 multiline 속성을 True로 설정해준다.
폼 디자인을 대충 보면 이렇게 된다.
3. 코딩 시작
using 란에
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System.Threading;
을 추가해준다.
다음의 변수들을 추가한다.
VideoCapture capture;
Mat frame;
Bitmap image;
private Thread camera;
int isCameraRunning = 0;
openCV 4 에서는 VideoCapture 를 사용한다.
camera는 별도의 쓰레드를 이용하여 캡춰하여 pictureBox 에 그림을 뽑아내도록 하였다.
인터넷의 다른예제에서는 Timer 를 사용하여 Tick 마다 갱신하는 방법도 있으니
어느쪽이든 선택하면 되겠다.
별도의 쓰레드로 카메라를 캡춰하기 위해 콜백함수를 생성한다.
capture.Open(1) << 이 부분이 카메라 1번을 여는 부분이다.
내장된 usb 카메라가 1번이 될것이고, 새 카메라를 연결하면 2 , 3 이런식으로 증가한다.
Start 버튼을 누르면 캡처 하는 기능을 넣어주자
버튼의 클릭 이벤트에 아래의 코드를 넣어준다.
private void button1_Click(object sender, EventArgs e) { if (button1.Text.Equals("Start")) { CaptureCamera(); button1.Text = "Stop"; isCameraRunning = 1; } else { if (capture.IsOpened()) { capture.Release(); }
button1.Text = "Start"; isCameraRunning = 0; } } |
Start 상태일때 버튼을 누르면 카메라 화면이 나타난다
Stop 일때 버튼을 누르면 카메라 화면이 중단된다.
실행하면 이렇게 나타난다.
전체소스
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 OpenCvSharp;
using OpenCvSharp.Extensions;
using System.Threading;
namespace Simple_Web_Cam
{
public partial class Form1 : Form
{
VideoCapture capture;
Mat frame;
Bitmap image;
private Thread camera;
int isCameraRunning = 0;
private void CaptureCamera()
{
camera = new Thread(new ThreadStart(CaptureCameraCallback));
camera.Start();
}
private void CaptureCameraCallback()
{
frame = new Mat();
capture = new VideoCapture();
capture.Open(1);
while (isCameraRunning == 1)
{
capture.Read(frame);
if (!frame.Empty())
{
image = BitmapConverter.ToBitmap(frame);
pictureBox1.Image = image;
}
image = null;
}
}
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text.Equals("Start"))
{
CaptureCamera();
button1.Text = "Stop";
isCameraRunning = 1;
}
else
{
if (capture.IsOpened())
{
capture.Release();
}
button1.Text = "Start";
isCameraRunning = 0;
}
}
}
}