이번에 소개할 알고리즘은 opencv를 통해 영상에 실시간 사각형이나 텍스트를 표시하는 방법을 설명합니다

opencv에서 실시간으로 나오는 카메라 영상에다가 마우스 이벤트로 사각형과 글씨를 그릴수있는 방법은 우선
마우스 이벤트(pictureBox에 관한)
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
}
위의 5개 이벤트가 우선 필요하고.
opencvsharp함수
cv2.Rectangel()
cv2.Puttext()
cv2.Line()
세개와
BitmapConverter.ToBitmap()
그림판에 출력하기 위해 위 함수가 필요하다.
이제 다들 앞장에서 패키지 설치는 했기를.
https://easytocoding.tistory.com/7
이번장에서는 그냥 테스트를 위해 번거러움을 줄이기 위해 노트북 내장 카메라를 쓰므로
opencvsharp 영상처리 프로그래밍(1) c# opencv
이번장에서 알아볼것은 opencv를 통해 c#에서 영상을 어떻게 처리하는지 알아볼것이다. opencv(Open Source Computer Vision Library)가 먼지 간략하게 설명하자면, 크로스플랫폼(Windows, Linux, OS X(Mac),iOS,Andro
easytocoding.tistory.com
vc=new VideoCapture(0);
을 쓸 예정이다.
이제 본격적으로
코딩하기
1. 라이브러리 사용하기.

extension은

위와 같은식으로 BitmapConveter()를 워낙 빈번하게 쓸것이므로 그냥 사용하기로 해놨다.
2. 전역 변수 설정하기

curMode 변수는 현재 내가 사각형 그리기 상태인지 아닌지 판단하기 위해 쓴다 그냥 계속 그리는게 아니라
그리기 버튼을 누를때 이제 마우스도 실시간으로 아래와 같이 바꿀것이므로, 그리기 상태가 아니라면 그냥 일반 마우스 포인터로 될것이다.

그러기 위해서 우선 드로우 모드를 변경할수 있는 함수를 선언한다.


그리기 모드 지우기 모드들을 우선 추가한다 근데 본문에서 소개하는 코딩은 그리는것만 지우는거까지는 직접해보시길 간단하다.
힌트를 주자면, 좌표값을 확인해서 좌표값 범위가 사각형이랑 일치할때 지울수있게하는것이다 정확히 사각형 그려진것을 선택할수없으므로 그 범위안에오게 선택하면 색깔 바뀌게 하고 지우게 하는 것이다.
2. 디자이너에 컴포넌트들 추가

기본적으로 필요한 것들이 위와 같이
Button 2개
DatagridView 1개
timer 1개
pictureBox 1개
이 4가지 이다.도구상자에서 추가하시길.
버튼은 그리기 모드를 추가하기 위해 필요하고 datagridview는 사각형 그릴 좌표값과 이것저것 정보등을 저장하기 위해 Visible를 그냥 false로 만들어 놓으면 된다 그냥 저장공간으로만 쓰는것임.
이제 앞장에서 timer에 추가로 코딩할 부분은. 아래와 같이 구현하면 된다.

당연히
this.Invoke((Action)(() =>
{
//이안에 들어가야됨
}), null);
위의 코드 안에 위치할 코드이다. c# 프로그래밍 에서 windowsforms앱은 GUI 디자이너랑 코드가 밀접한 관련이 있으므로 꼭 invoke()처리 해줘야된다 안하면 중간에 뻗어버린다.
3. 프로그램이 추가될때 영상 뜨게 설정

위 코드처럼 노트북내장카메라(0번) 을 VideoCapture함수에 추가하고 timer만 켜주면 된다.
참고로 주의사항은 사각형 그리기 버튼을 영상이 나오기전에 누르면 에러가 나서 프로그램이 죽어 버리므로 , 사각형 그리기 함수는 처음에 enable=false로 하고 영상이 나오면 true로 바꿔주시길.
this.Invoke((Action)(() =>
{
}), null);
buttonRect.Enable=true;
위와 같이 구현하면 이제 사각형 띄우게 기본 구성은 다 된것이다.
이제 마우스 이벤트에 코딩을 시작하면.
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (curMode == (int)DRAW_MODE.SHAPEMODE)
{
init = new OpenCvSharp.Point((double)e.X, (double)e.Y );
drawing = true;
}
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
SetDrawMode(curMode);
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
SetDrawMode((int)DRAW_MODE.EDITMODE);
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (curMode == (int)DRAW_MODE.SHAPEMODE)
{
if (drawing == true)
{
OpenCvSharp.Point a = new OpenCvSharp.Point((double)e.X , (double)e.Y );
Mat tp = new Mat();
if (pictureBox1.InvokeRequired)
{
pictureBox1.Invoke(new MethodInvoker(
delegate ()
{
pictureBox1.Image = BitmapConverter.ToBitmap(temp);
}));
}
else
{
pictureBox1.Image = BitmapConverter.ToBitmap(temp);
}
drawnrect(temp, a);
}
else
{
OpenCvSharp.Point a = new OpenCvSharp.Point(e.X, e.Y);
Mat tp = new Mat();
if (pictureBox1.InvokeRequired)
{
pictureBox1.Invoke(new MethodInvoker(
delegate ()
{
pictureBox1.Image = BitmapConverter.ToBitmap(temp);
}));
}
else
{
pictureBox1.Image = BitmapConverter.ToBitmap(temp);
}
drawcross(temp, a);
init = a;
}
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
OpenCvSharp.Point a = new OpenCvSharp.Point((double)e.X , (double)e.Y );
Mat t = new Mat();
Scalar sc = new Scalar(0, 255, 0);
dataGridView1.Rows.Add(Convert.ToString(init.Y), Convert.ToString(init.X), Convert.ToString(a.X - init.X), Convert.ToString(a.Y - init.Y), "", "");
dataGridView1.ClearSelection();
drawing = false;
}
위와 같이 마우스가 클릭해서 사각형을 그리는 동안은 노란색으로 표시되고 마우스가 다 그리고 마우스 왼쪽마우스버튼이 떨어지는순간 초록색으로 확정적으로 그린다.
당연히 그리기 버튼에 대한이벤트는

위와 같이 처리하면 된다 그리기 버튼을 누르는 순간 바로 마우스 포인트가

위와 같이 바뀌게 되고 마우스 좌표값도 표시된다.
당연히 pictureBox에서 마우스가 벗어나면 마우스 포인트는 벗어난상태에서 고정된다.
pictureBox안에서만 위와 같이 변경되는 것이다.
이제 마우스 포인터를 십자가로 표시하는 함수. drawcross()를 구현하는데 아래와 같이 구현하면 된다.

마우스 포인터의 십자가 표시의 색깔을 바꿀려면 Scalar()함수의 색상표를 바꾸면 된다. 다들 255,255,255이렇게 3채널로 된값은 알리라 생각한다. 자신의 원하는 색상표는 인터넷에 찾아보길 너무나도 많이 널렸다.
참고로 0,255,255 는 노란색이다.
위 코드에서 마찬가지로 디자이너에 쓰레드처리를 해야되므로 invoke()를 꼭 적용하시길 안그러면 다운된다.
그다음에 십자가의 크기를 현재는 40픽셀정도로 설정해놨는데 줄이던가 늘릴려면
Cv2.Line()
함수에서 40숫자를 원하는데로 조정하면 크기를 원하는데로 조정할수있다.
다음으로, 사각형을 실제로 그려주는 함수 drawrect()함수는

위와 같이 구현하면 된다. 다른 거 없다 마우스 시작점부터 드래그해서 최종 가져간 점까지 좌표값을 받아서 그려주면 끝.
너무나도 쉽다.
다음장에서는 위 실시간 사각형 그린것을 이용해서 사각형 그린위치의 초점거리를 확인하는 방법과 물체간의 거리 측정하는 법에 대해 설명하도록 하겠습니다.
카메라의 실시간 초점거리를 내가 원하는 영역내에서만 확인하는 작업이므로 위의 작업은 필수입니다.
'C# 윈도우 프로그래밍' 카테고리의 다른 글
Geometric model finder C#(2) (0) | 2022.12.17 |
---|---|
Geometric model finder C#(1) (0) | 2022.12.17 |
AI 딥러닝 objectdetection YOLO c# 프로그래밍 (0) | 2022.12.11 |
Opencvsharp 탬플릿 매칭 c# (template Matching) opencv (0) | 2022.12.11 |
opencvsharp 영상처리 프로그래밍(1) c# opencv (0) | 2022.12.11 |