OpenCVSharp 카메라 제어 #1 ( 카메라 영상 출력 )
Software/C#2023. 3. 5. 12:41
반응형
장비제어 프로그램에서 빠질수 없는 부분이 카메라 제어 입니다. 기존에 C++ Builder를 이용하여 장비제어를 했을때도 OpenCV를 사용했지만 OpenCV 버젼이 올라가고 클래스 기반으로 라이브러리가 변경되면서 C++ Builder의 구조적인 문제로 인해 더이상 상위 버젼의 OpenCV 릃 사용할 수가 없었고, C#으로 개발툴을 변경하면서 OpenCVSharp을 적용해 보았습니다. 이번장에서는 기본적으로 카메라 영상을 화면에 출력하는 방법에 대해 구현합니다.
카메라 영상 제어를 위한 클래스를 구현했고 Thread 로 영상을 화면에 출력하도록 했습니다.
1. Winform 프로젝트를 하나 만듭니다.
2. nuget 에서 openCVSharp 관련 컨트롤을 등록시켜 줍니다.
3. MainForm 에 pictureBox 1개(640 x 480)와 Button 2개(start, stop) 을 올려 줍니다.
* pictureBox의 크기는 카메라의 해상도에 맞추어 조정하시면 됩니다.
4. 아래는 구현된 카메라 클래스 입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace CameraControl
{
public class CameraThread
{
private delegate void SafeCallDelegate(Bitmap frame);
readonly private VideoCapture capture = new VideoCapture();
readonly private Mat sourceFrame = new();
private OpenCvSharp.Point displaySize;
public int cameraNumber { get; set; } = 0;
public bool isCameraRunning { get; set; } = false;
public PictureBox display;
public PictureBox Display
{
set
{
this.display = value;
this.displaySize.X = display.Width;
this.displaySize.Y = display.Height;
}
}
//-------------------------------------------------------------------------------------
public CameraThread(PictureBox pictureBox, int cameraNumber)
{
this.display = pictureBox;
displaySize.X = pictureBox.Width;
displaySize.Y = pictureBox.Height;
capture.FrameWidth = displaySize.X;
capture.FrameHeight = displaySize.Y;
this.cameraNumber = cameraNumber;
}
//-------------------------------------------------------------------------------------
public Int32 Initialize()
{
Int32 result = 1;
capture.Open(cameraNumber);
if (capture.IsOpened()) result = 0;
return result;
}
//-------------------------------------------------------------------------------------
public void Run()
{
capture.Open(cameraNumber); // 연결된 카메라를 Open 합니다.
using (Mat displayFrame = new()) // 영상 출력을 위한 Mat 생성
{
while (isCameraRunning)
{
capture.Read(sourceFrame); // 카메라에서 영상 Source Frame 으로 읽어옵니다.
if (!sourceFrame.Empty())
{
Cv2.CopyTo(sourceFrame, displayFrame); // source frame의 영상을 출력 영상 frame 롤 복사합니다.
UpdateFrame(BitmapConverter.ToBitmap(displayFrame)); // 출력영상을 화면에 보여 줍니다.
}
}
}
capture.Release();
GC.Collect();
}
//-------------------------------------------------------------------------------------
private void UpdateFrame(Bitmap frame)
{
if (display != null)
{
if (display.InvokeRequired)
{
var d = new SafeCallDelegate(UpdateFrame);
display.Invoke(d, new object[] { frame });
}
else
{
display.Image = frame;
}
}
}
//-------------------------------------------------------------------------------------
}
}
* 영상제어 클래스에서 source frame 와 display frame 을 분리한 이유는 source frame 에서 영상에 대한 제어를 활용하고 그 결과를 display frame를 통해 출력하기 위해 별도로 분리했습니다.
5. 위에 구현된 클래스를 이용하여 메인 화면에 영상을 출력합니다.
using OpenCvSharp;
using System;
using System.Windows.Forms;
namespace CameraControl
{
public partial class Form1 : Form
{
private Thread thread;
readonly private CameraThread cameraThread;
public Form1()
{
InitializeComponent();
cameraThread = new CameraThread(pictureBox1, 0); // 0번 카메라 출력
cameraThread.Initialize();
}
private void btnStart_Click(object sender, EventArgs e)
{
cameraThread.isCameraRunning = true;
thread = new Thread(new ThreadStart(cameraThread.Run));
thread.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
if (thread.IsAlive)
{
cameraThread.isCameraRunning = false;
}
}
}
}
반응형
'Software > C#' 카테고리의 다른 글
OpenCVSharp 카메라 제어 #3 ( Image Capture ) (0) | 2023.03.20 |
---|---|
OpenCVSharp 카메라 제어 #2 ( Line Generator) (0) | 2023.03.06 |
Ocean Optics 사의 OmniDriver 제어코드 - C# (0) | 2023.02.17 |
ScottPlot (Growing Data - #2) (2) | 2023.02.16 |
ScottPlot (Growing Data - #1) (0) | 2023.02.16 |
댓글()