108.59MBRAR
C# OpenCvSharp DNN Yolov8-OBB 회전 표적 감지 소스 코드
효과
모델 정보
모델 속성
————————-
date: 2024-02-26T08:38:44.171849
설명: runs/DOTAv1.0-ms.yaml에서 학습된 Ultralytics YOLOv8s-obb 모델
저자: Ultralytics
작업: OBB
라이선스: AGPL-3.0 https://ultralytics.com/license
버전: 8.1.18
보폭: 32
배치: 1
IMGSZ: [640, 640]
names: {0: '비행기', 1: '선박', 2: '저장탱크', 3: ' baseball 다이아몬드', 4: '테니스 코트', 5: '농구 코트', 6: '육상 트랙 필드 ', 7: '항구', 8: '다리', 9: '대형 차량', 10. '소형 차량', 11: '헬리콥터', 12: '원형 교차로', 13. '축구장', 14: '수영장'}
—————————————————————
입력
————————-
이름:이미지
텐서: Float[1, 3, 640, 640]
—————————————————————
출력
————————-
이름: 출력0
텐서: Float[1, 20, 8400]
—————————————————————
스포츠 이벤트
코딩
OpenCvSharp를 사용합니다.
OpenCvSharp를 사용합니다.
System.
Generic; System.Collections를 사용합니다.
System.Drawing을 사용합니다.
System.IO를 사용합니다.
System.Linq를 사용합니다.
System.Windows.Forms를 사용합니다.
네임스페이스 OpenCvSharp_DNN_Demo
{
공용 부분 클래스 frmMain : Form
{
public frmMain()
{
초기화 컴포넌트();
}
문자열 fileFilter = "*. *|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
문자열 image_path = "";
날짜 시간 dt1 = 날짜 시간.지금;
날짜 시간 dt2 = 날짜 시간.지금;
문자열 모델 경로.
문자열 클래서_경로.
class_names를 나열합니다.
Net opencv_net.
Mat BN_image.
매트 이미지.
매트 결과_이미지.
문자열[] class_lables.
private void button1_Click(객체 sender, EventArgs e)
{
OpenFileDialog ofd = 새 OpenFileDialog();
ofd.Filter = 파일필터;
if (ofd.ShowDialog() ! = DialogResult.OK) 반환합니다;
PictureBox1.Image = null;
PictureBox2.Image = null;
textBox1.Text = "";
이미지 경로 = ofd.파일 이름;
pictureBox1.Image = 새 비트맵(image_path);
image = 새 Mat(image_path);
}
private void Form1_Load(객체 sender, EventArgs e)
{
모델 경로 = "model/yolov8s-obb.onnx";
클래서_경로 = "model/lable.txt";
opencv_net = CvDnn.ReadNetFromOnnx(모델 경로);
목록 str = 새 목록();
스트림리더 sr = 새 스트림리더(classer_path);
문자열 라인.
while ((line = sr.ReadLine()) ! = null)
{
str.Add(line);
}
class_lables = str.ToArray();
이미지 경로 = "test_img/1.png";
pictureBox1.Image = 새 비트맵(image_path);
}
private void button2_Click(object sender, EventArgs e)
{
if (image_path == "")
{
반환합니다;
}
textBox1.Text = "검색 진행 중, 잠시만 기다려 주세요 ......";
PictureBox2.Image = null;
button2.Enabled = false;
Application.DoEvents();
image = 새 Mat(image_path);
// 사진 크기 조정
image = 새 Mat(image_path);
int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
Rect roi = 새로운 Rect(0, 0, image.Cols, image.Rows);
image.CopyTo(new Mat(max_image, roi));
float[] result_array;
float factor = (float)(max_image_length / 640.0);
// 이미지를 RGB 채널로 변환
Mat image_rgb = 새로운 Mat();
Cv2.CvtColor(max_image, image_rgb, ColorConversionCodes.BGR2RGB);
Mat resize_image = 새로운 Mat();
Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640));
BN_image = CvDnn.BlobFromImage(resize_image, 1 / 255.0, new OpenCvSharp.Size(640, 640), new Scalar(0, 0, 0), true, false)로 설정합니다;
// 사진 입력 데이터 구성
opencv_net.SetInput(BN_image);
//모델 추론, 추론 결과 읽기
Mat[] outs = new Mat[1] { new Mat() };
string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();
dt1 = DateTime.Now;
opencv_net.Forward(outs, outBlobNames);
dt2 = DateTime.Now;
int num_proposal = outs[0].Size(1);
int nout = outs[0].Size(2);
if (outs[0].Dims > 2)
{
outs[0] = outs[0].Reshape(0, num_proposal);
}
Mat result_data = 새로운 Mat(20, 8400, MatType.CV_32F);
result_data = outs[0].T();
위치 상자 목록 = 새 목록();
목록 class_ids = 새 목록();
목록 자신감 = 새 목록();
목록 회전 = 새 목록();
// 출력 결과 전처리
for (int i = 0; i < result_data.Rows; i++)
{
Mat classes_scores = new Mat(result_data, new Rect(4, i, 15, 1));
OpenCvSharp.Point 최대_클래스아이디_포인트, 최소_클래스아이디_포인트;
double max_score, min_score.
// 데이터 집합에서 최대값과 그 위치를 가져옵니다.
Cv2.MinMaxLoc(classes_scores, out min_score, out max_score,
out min_classId_point, out max_classId_point);
// 신뢰 수준 0 ~ 1 사이
// 식별 상자 정보 얻기
if (max_score > 0.25)
{
float cx = result_data.At(i, 0);
float cy = result_data.At(i, 1);
float ow = result_data.At(i, 2);
float oh = result_data.At(i, 3);
double x = (cx - 0.5 * ow) * factor.
double y = (cy - 0.5 * oh) * factor;
더블 너비 = ow * 계수.
더블 높이 = 오 * 계수.
Rect2d 상자 = 새 Rect2d();
box.X = x;
box.Y = y;
box.Width = 너비;
box.Height = 높이;
위치_상자.추가(상자);
class_ids.Add(max_classId_point.X);
confidences.Add((float)max_score);
rotations.Add(result_data.At(i, 19));
}
}
// NMS
int[] indexes = new int[position_boxes.Count];
CvDnn.NMSBoxes(위치_박스, 컨피던스, 0.25f, 0.7f, 아웃 인덱스);
List rotated_rects = 새 List();
for (int i = 0; i < indexes.Length; i++)
{
int index = indexes[i];
float w = (float)position_boxes[index].Width;
float h = (float)position_boxes[index].Height;
float x = (float)position_boxes[index].X + w / 2;
float y = (float)position_boxes[index].y + h / 2;
float r = rotations[index];
float w_ = w > h ? w : h;
float h_ = w > h ? h : w;
r = (float)((w > h ? r : (float)(r + Math.PI / 2)) % Math.PI);
RotatedRect rotate = new RotatedRect(new Point2f(x, y), new Size2f(w_, h_), (float)(r * 180.0 / Math.PI));
rotated_rects.Add(rotate);
}
result_image = image.Clone();
for (int i = 0; i < indexes.Length; i++)
{
int index = indexes[i];
Point2f[] points = rotated_rects[i].Points();
for (int j = 0; j < 4; j++)
{
Cv2.Line(result_image, (OpenCvSharp.Point)points[j], (OpenCvSharp.Point)points[(j + 1) % 4], new Scalar(0, 255, 0), 2);
}
Cv2.PutText(result_image, class_lables[class_ids[index]] + "-" + confidences[index].ToString("0.00) "),
(OpenCvSharp.Point)points[0], HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 255), 2);
}
pictureBox2.Image = 새 비트맵(result_image.ToMemoryStream());
textBox1.Text = "추론 경과 시간:" + (dt2 - dt1).TotalMilliseconds + "ms";
button2.Enabled = true;
}
private void pictureBox2_DoubleClick(object sender, EventArgs e)
{
Common.ShowNormalImg(pictureBox2.Image);
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
Common.ShowNormalImg(pictureBox1.Image);
}
}
}
OpenCvSharp를 사용합니다.
OpenCvSharp를 사용합니다.
Dnn 사용; System.
System.Collections.
Generic; using System.Collections.Generic; using System.
using System.
System.IO를 사용하는 경우; System.IO를 사용하는 경우; System.
System.Windows.
네임스페이스 OpenCvSharp_DNN_Demo
{
public 부분 클래스 frmMain : Form
{
public frmMain()
{
초기화 컴포넌트();
}
문자열 fileFilter = "*. *|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
문자열 image_path = """;
날짜 시간 dt1 = 날짜 시간.
날짜 시간 dt2 = 날짜 시간.
dt2 = DateTime.Now; 문자열 모델경로; dt2 = DateTime.
문자열 classer_path.
List<문자열> class_names.
Net opencv_net;
Mat BN_image.
매트 이미지.
매트 결과_이미지.
문자열[] class_lables.
private void button1_Click(객체 sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = fileFilter;
if (ofd.ShowDialog() ! ofd = new OpenFileDialog(); ofd.Filter = fileFilter; if (ofd.ShowDialog() !
PictureBox1.Image = null;
pictureBox2.Image = null; pictureBox2.
pictureBox2.Image = null; pictureBox2.Image = null; pictureBox1.Text = ""; textBox1.
image_path = ofd.FileName;
PictureBox1.Image = 새 비트맵(image_path);
pictureBox1.Image = 새로운 비트맵(이미지_경로); image = 새로운 매트(이미지_경로);
}
private void Form1_Load(객체 sender, EventArgs e)
{
modelpath = "model/yolov8s-obb.onnx";
classer_path = "model/lable.txt";
opencv_net = CvDnn.ReadNetFromOnnx(모델경로);
List<문자열> str = 새 목록<문자열>().
StreamReader sr = 새 StreamReader(classer_path);
StreamReader sr = new StreamReader(classer_path); 문자열 line.
while ((line = sr.ReadLine()) ! line; while ((line = sr.ReadLine()) !
{
str.Add(line);
}
class_lables = str.ToArray();
image_path = "test_img/1.png";
pictureBox1.Image = 새 비트맵(image_path);
}
private void button2_Click(object sender, EventArgs e)
{
if (image_path == "")
{
반환합니다;
}
textBox1.Text = "검색 진행 중, 잠시만 기다려주세요 ......";
pictureBox2.Image = null;
button2.Enabled = false;
Application.DoEvents();
application.DoEvents(); image = new Mat(image_path);
//이미지 스케일링
image = new Mat(image_path);
int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
Rect roi = new Rect(0, 0, image.Cols, image.Rows);
image.CopyTo(new Mat(max_image, roi));
float[] result_array;
float factor = (float)(max_image_length / 640.0);
// 이미지를 RGB 채널로 변환
Mat image_rgb = 새로운 Mat();
Cv2.CvtColour(max_image, image_rgb, ColorConversionCodes.BGR2RGB);
Mat resize_image = 새로운 Mat();
Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640));
BN_image = CvDnn.BlobFromImage(resize_image, 1 / 255.0, new OpenCvSharp.Size(640, 640), new Scalar(0, 0, 0), true, false);
// 이미지 입력 데이터 설정
opencv_net.SetInput(BN_image);
//모델 추론, 추론 결과 읽기
Mat[] outs = new Mat[1] { new Mat() };
string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();
dt1 = DateTime.Now;
opencv_net.Forward(outs, outBlobNames);
dt2 = DateTime.
int num_proposal = outs[0].Size(1);
int nout = outs[0].Size(2);
if (outs[0].Dims > 2)
{
outs[0] = outs[0].Reshape(0, num_proposal);
}
Mat result_data = new Mat(20, 8400, MatType.CV_32F);
result_data = outs[0].
T(); result_data = outs[0].<Rect2d> 위치 상자 = 새 목록<Rect2d>().
목록<int> class_ids = 새 목록<int>().
목록<float> 자신감 = 새 목록<float>().
목록<float> 회전 = 새 목록<float>().
// 출력 결과 전처리
for (int i = 0; i 0.25)
{
float cx = result_data.At<float>(i, 0);
float cy = result_data.At<float>(i, 1);
float ow = result_data.At<float>(i, 2).
float oh = result_data.At<float>(i, 3).
double x = (cx - 0.5 * ow) * factor.
double y = (cy - 0.5 * oh) * 계수.
더블 너비 = ow * 계수.
이중 높이 = oh * 계수; 이중 너비 = ow * 계수; 이중 높이 = oh * 계수; 이중 높이 = oh * 계수
Rect2d 상자 = 새로운 Rect2d();
box.X = x;
box.X = x; box.Y = y.
box.Width = 너비;
box.Width = 너비; box.Height = 높이; box.Y = y
위치_상자.추가(상자);
class_ids.Add(max_classId_point.X);
confidences.Add((float)max_score);
rotations.Add(result_data.At<float>(i, 19)).
}
}
// NMS
int[] indexes = new int[position_boxes.Count];
CvDnn.NMSBoxes(position_boxes, confidences, 0.25f, 0.7f, out indexes);
List<회전된 직사각형> rotated_rects = 새 목록<회전된 직사각형>().
for (int i = 0; i h ? w : h;
float h_ = w > h ? h : w;
r = (float)((w > h ? r : (float)(r + Math.PI / 2)) % Math.PI);
RotatedRect rotate = new RotatedRect(new Point2f(x, y), new Size2f(w_, h_), (float)(r * 180.0 / Math.PI));
rotated_rects.Add(rotate);
}
result_image = image.Clone();
for (int i = 0; i < indexes.Length; i++)
{
int index = indexes[i];
Point2f[] points = rotated_rects[i].Points();
for (int j = 0; j < 4; j++)
{
Cv2.Line(result_image, (OpenCvSharp.Point)points[j], (OpenCvSharp.Point)points[(j + 1) % 4], new Scalar(0, 255, 0), 2);
}
Cv2.PutText(result_image, class_lables[class_ids[index]] + "-" + confidences[index].ToString("0.00"),
(OpenCvSharp.Point)points[0], HersheyFonts.HersheySimplex, 0.8, new Scalar(0, 0, 255), 2);
}
pictureBox2.Image = 새 비트맵(result_image.ToMemoryStream());
textBox1.Text = "추론 경과 시간:" + (dt2 - dt1).TotalMilliseconds + "ms";
button2.Enabled = true;
}
private void pictureBox2_DoubleClick(object sender, EventArgs e)
{
Common.ShowNormalImg(pictureBox2.Image);
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
Common.ShowNormalImg(pictureBox1.Image);
}
}
}
리소스 정책(구매는 이 정책에 동의하는 것으로 간주됩니다): 1. 웹 사이트 플랫폼에서의 모든 작업은 웹 사이트 등록 계약 및 면책 조항 하단을 읽고 동의 한 것으로 간주되며,이 사이트 리소스는 초저가이며 기술 지원을 제공하지 않습니다. 2. 일부 네트워크 사용자가 공유하는 넷 디스크 주소가 오류 발생 등 유효하지 않을 수 있으므로 고객 서비스 코드711cn#qq.com (#를 @로 대체)으로 이메일을 보내 주시기 바랍니다. 이 사이트는 부정적인 변경이 없도록 다운로드 가능한 모든 리소스 (소프트웨어 등) 사이트를 제공합니다. 그러나이 사이트는 리소스의 정확성, 보안 및 무결성을 보장 할 수 없으며 사용자는 자신의 재량에 따라 다운로드하며 모든 소스 코드가 100% 오류가 없거나 버그가없는 것은 아니라는 목적으로 배우기 위해 통신하며 코드를 읽고 이해할 수있는 특정 기초가 있어야 디버깅을 수정할 수 있습니다! 코드를 수정하고 오류를 해결할 수 있어야 합니다. 동시에 이 사이트의 사용자는 소스 코드 편의점이 다운로드용으로 제공된 소프트웨어에 대한 어떠한 권리도 소유하지 않으며, 저작권은 리소스의 법적 소유자에게 있음을 이해해야 합니다. 4. 본 사이트의 모든 자료는 학습 및 연구 목적으로 만 다운로드 한 후 24시간 이내에 삭제해야 하며, 상업적 목적으로 사용하지 마시고, 그렇지 않을 경우 발생하는 법적 분쟁은 사이트 및 부수적 책임 사이트의 게시자에게 있으며 책임을지지 않습니다! 5. 재생산 가능한 자원의 특성으로 인해 일단 구매하면 환불이 불가능하며, 충전 잔액도 환불되지 않습니다.