첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestSolution.zip
다운로드
TestSolution.z01
다운로드
TestSolution.z02
다운로드
TestSolution.z03
다운로드
TestSolution.z04
다운로드
TestSolution.z05
다운로드
TestSolution.z06
다운로드
TestSolution.z07
다운로드
TestSolution.z08
다운로드

[TestProject 프로젝트]

▶ MainForm.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

using TestCommon;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// YOLO 레퍼
        /// </summary>
        private YoloWrapper wrapper;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.processImageButton.Enabled = false;

            this.sourceDataGridView.AutoGenerateColumns = false;
            this.resultDataGridView.AutoGenerateColumns = false;

            IEnumerable<ImageInfo> imageInfoEnumerable = new DirectoryImageReader().Analyze(@".\IMAGE");

            this.sourceDataGridView.DataSource = imageInfoEnumerable.ToList();

            ConfigurationDetector configurationDetector = new ConfigurationDetector();

            YoloConfiguration configuration = configurationDetector.Detect();

            if(configuration == null)
            {
                MessageBox.Show("YOLO 구성 탐지를 실패했습니다.", "INFORMATION", MessageBoxButtons.OK, MessageBoxIcon.Information);

                return;
            }

            this.toolStripStatusLabel1.Text = string.Empty;
            this.toolStripStatusLabel2.Text = string.Empty;

            FormClosing += Form_FormClosing;
            this.sourceDataGridView.SelectionChanged += sourceDataGridView_SelectionChanged;
            this.sourceDataGridView.KeyDown          += sourceDataGridView_KeyDown;
            this.processImageButton.Click            += processImageButton_Click;
            this.resultDataGridView.SelectionChanged += resultDataGridView_SelectionChanged;

            Task.Run(() => Initialize(configuration));
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 폼 닫을 경우 처리하기 - Form_FormClosing(sender, e)

        /// <summary>
        /// 폼 닫을 경우 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.wrapper.Dispose();
        }

        #endregion
        #region 소스 데이터 그리드 뷰 선택 변경시 처리하기 - sourceDataGridView_SelectionChanged(sender, e)

        /// <summary>
        /// 소스 데이터 그리드 뷰 선택 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourceDataGridView_SelectionChanged(object sender, EventArgs e)
        {
            Image previousImage = this.pictureBox.Image;

            ImageInfo imageInfo = GetCurrentImageInfo();

            this.pictureBox.Image = Image.FromFile(imageInfo.FilePath);

            previousImage?.Dispose();

            this.resultDataGridView.DataSource = null;
        }

        #endregion
        #region 소스 데이터 그리드 뷰 키 DOWN 처리하기 - sourceDataGridView_KeyDown(sender, e)

        /// <summary>
        /// 소스 데이터 그리드 뷰 키 DOWN 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sourceDataGridView_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Space)
            {
                Detect();
            }
        }

        #endregion
        #region 이미지 처리 버튼 클릭시 처리하기 - processImageButton_Click(sender, e)

        /// <summary>
        /// 이미지 처리 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void processImageButton_Click(object sender, EventArgs e)
        {
            Detect();
        }

        #endregion
        #region 결과 데이터 그리드 뷰 선택 변경시 처리하기 - resultDataGridView_SelectionChanged(sender, e)

        /// <summary>
        /// 결과 데이터 그리드 뷰 선택 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void resultDataGridView_SelectionChanged(object sender, EventArgs e)
        {
            if(!this.resultDataGridView.Focused)
            {
                return;
            }

            List<YoloItem> itemList = this.resultDataGridView.DataSource as List<YoloItem>;

            YoloItem item = this.resultDataGridView.CurrentRow?.DataBoundItem as YoloItem;

            DrawImage(itemList, item);
        }

        #endregion
        #region 폴더 열기 메뉴 항목 클릭시 처리하기 - openFolderMenuItem_Click(sender, e)

        /// <summary>
        /// 폴더 열기 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void openFolderMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult result = this.folderBrowserDialog.ShowDialog();

            if(result != DialogResult.OK)
            {
                return;
            }
            
            IEnumerable<ImageInfo> imageInfoEnumerable = new DirectoryImageReader().Analyze(this.folderBrowserDialog.SelectedPath);

            this.sourceDataGridView.DataSource = imageInfoEnumerable.ToList();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 초기화 하기 - Initialize(configuration)

        /// <summary>
        /// 초기화 하기
        /// </summary>
        /// <param name="configuration">YOLO 구성</param>
        private void Initialize(YoloConfiguration configuration)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            this.wrapper = new YoloWrapper(configuration.ConfigurationFilePath, configuration.WeightFilePath, configuration.NameFilePath, 0);

            stopwatch.Stop();

            this.statusStrip.Invoke
            (
                new MethodInvoker
                (
                    delegate()
                    {
                        this.toolStripStatusLabel1.Text = string.Format
                        (
                            "초기화 시간 : {0} 밀리초, 탐지 시스템 : {1} ({2})",
                            stopwatch.Elapsed.TotalMilliseconds,
                            this.wrapper.DetectionSystemType,
                            this.wrapper.EnvironmentReport.GraphicDeviceName
                        );
                    }
                )
            );

            this.processImageButton.Invoke(new MethodInvoker(delegate () { this.processImageButton.Enabled = true; }));
        }

        #endregion
        #region 현재 이미지 정보 구하기 - GetCurrentImageInfo()

        /// <summary>
        /// 현재 이미지 정보 구하기
        /// </summary>
        /// <returns>현재 이미지 정보</returns>
        private ImageInfo GetCurrentImageInfo()
        {
            ImageInfo imageInfo = this.sourceDataGridView.CurrentRow?.DataBoundItem as ImageInfo;

            return imageInfo;
        }

        #endregion
        #region 펜 구하기 - GetPen(confidence, width)

        /// <summary>
        /// 펜 구하기
        /// </summary>
        /// <param name="confidence">확신도</param>
        /// <param name="width">너비</param>
        /// <returns>펜</returns>
        private Pen GetPen(double confidence, int width)
        {
            int size = width / 100;

            if(confidence > 0.5)
            {
                return new Pen(Brushes.GreenYellow, size);
            }
            else if(confidence > 0.2 && confidence <= 0.5)
            {
                return new Pen(Brushes.Orange, size);
            }

            return new Pen(Brushes.DarkRed, size);
        }

        #endregion
        #region 이미지 그리기 - DrawImage(itemList, selectedItem)

        /// <summary>
        /// 이미지 그리기
        /// </summary>
        /// <param name="itemList">이미지 리스트</param>
        /// <param name="selectedItem">선택 이미지</param>
        private void DrawImage(List<YoloItem> itemList, YoloItem selectedItem = null)
        {
            ImageInfo imageInfo = GetCurrentImageInfo();

            Image image = Image.FromFile(imageInfo.FilePath);

            using(Graphics graphics = Graphics.FromImage(image))
            {
                foreach(YoloItem item in itemList)
                {
                    int x      = item.X;
                    int y      = item.Y;
                    int width  = item.Width;
                    int height = item.Height;

                    using(SolidBrush overlayBrush = new SolidBrush(Color.FromArgb(150, 255, 255, 102)))
                    {
                        using(Pen pen = GetPen(item.Confidence, image.Width))
                        {
                            if(item.Equals(selectedItem))
                            {
                                graphics.FillRectangle(overlayBrush, x, y, width, height);
                            }

                            graphics.DrawRectangle(pen, x, y, width, height);

                            graphics.Flush();
                        }
                    }
                }
            }

            Image previousImage = this.pictureBox.Image;

            this.pictureBox.Image = image;

            previousImage?.Dispose();
        }

        #endregion
        #region 탐지하기 - Detect()

        /// <summary>
        /// 탐지하기
        /// </summary>
        private void Detect()
        {
            if(this.wrapper == null)
            {
                return;
            }

            bool memoryTransfer = true;

            ImageInfo imageInfo = GetCurrentImageInfo();

            byte[] imageByteArray = File.ReadAllBytes(imageInfo.FilePath);

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            List<YoloItem> itemList;

            if(memoryTransfer)
            {
                itemList = this.wrapper.Detect(imageByteArray).ToList();
            }
            else
            {
                itemList = this.wrapper.Detect(imageInfo.FilePath).ToList();
            }

            stopwatch.Stop();

            this.toolStripStatusLabel2.Text = $"이미지 처리 시간 : {stopwatch.Elapsed.TotalMilliseconds:0.00} 밀리초";

            this.resultDataGridView.DataSource = itemList;

            DrawImage(itemList);
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요