첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestProject.zip
0.37MB

▶ IFaceDetectionService.cs

using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;
using Windows.Media.FaceAnalysis;

namespace TestProject
{
    /// <summary>
    /// 얼굴 탐지 서비스
    /// </summary>
    public interface IFaceDetectionService
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        #region 탐지 얼굴 리스트 구하기 - GetDetectedFaceList(stream)

        /// <summary>
        /// 탐지 얼굴 리스트 구하기
        /// </summary>
        /// <param name="stream">스트림</param>
        /// <returns>탐지 얼굴 리스트 태스크</returns>
        Task<IList<DetectedFace>> GetDetectedFaceList(Stream stream);

        #endregion
        #region 탐지 얼굴 비트맵 구하기 - GetDetectedFaceBitmap(stream, detectedFaceList, boxColor, strokeThickness)

        /// <summary>
        /// 탐지 얼굴 비트맵 구하기
        /// </summary>
        /// <param name="stream">스트림</param>
        /// <param name="detectedFaceList">탐지 얼굴 리스트</param>
        /// <param name="boxColor">박스 색상</param>
        /// <param name="strokeThickness">스트로크 두께</param>
        /// <returns>탐지 얼굴 비트맵</returns>
        Bitmap GetDetectedFaceBitmap(Stream stream, IList<DetectedFace> detectedFaceList, Color boxColor, int strokeThickness = 2);

        #endregion
    }
}

 

728x90

 

▶ FaceDetectionService.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Media.FaceAnalysis;
using Windows.Storage.Streams;

namespace TestProject
{
    /// <summary>
    /// 얼굴 탐지 서비스
    /// </summary>
    public class FaceDetectionService : IFaceDetectionService
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 탐지 얼굴 리스트 구하기 - GetDetectedFaceList(stream)

        /// <summary>
        /// 탐지 얼굴 리스트 구하기
        /// </summary>
        /// <param name="stream">스트림</param>
        /// <returns>탐지 얼굴 리스트 태스크</returns>
        public async Task<IList<DetectedFace>> GetDetectedFaceList(Stream stream)
        {
            IRandomAccessStream randomAccessStream = stream.AsRandomAccessStream();

            var bitmapDecoder = await BitmapDecoder.CreateAsync(randomAccessStream);

            using SoftwareBitmap sourceBitmap = await bitmapDecoder.GetSoftwareBitmapAsync();

            SoftwareBitmap targetBitmap = FaceDetector.IsBitmapPixelFormatSupported(sourceBitmap.BitmapPixelFormat)
                ? sourceBitmap : SoftwareBitmap.Convert(sourceBitmap, BitmapPixelFormat.Gray8);

            FaceDetector faceDetector = await FaceDetector.CreateAsync();

            IList<DetectedFace> detectedFaceList = await faceDetector.DetectFacesAsync(targetBitmap);

            return detectedFaceList;
        }

        #endregion
        #region 탐지 얼굴 비트맵 구하기 - GetDetectedFaceBitmap(stream, detectedFaceList, boxColor, strokeThickness)

        /// <summary>
        /// 탐지 얼굴 비트맵 구하기
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="detectedFaceList"></param>
        /// <param name="boxColor"></param>
        /// <param name="strokeThickness"></param>
        /// <returns></returns>
        public System.Drawing.Bitmap GetDetectedFaceBitmap
        (
            Stream               stream,
            IList<DetectedFace>  detectedFaceList,
            System.Drawing.Color boxColor,
            int                  strokeThickness = 2
        )
        {
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(stream);
            
            using(System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
            {
                using System.Drawing.Pen pen = new System.Drawing.Pen(boxColor, strokeThickness);

                foreach(DetectedFace detectedFace in detectedFaceList)
                {
                    BitmapBounds bitmapBounds = detectedFace.FaceBox;

                    graphics.DrawRectangle
                    (
                        pen,
                        (int)bitmapBounds.X,
                        (int)bitmapBounds.Y,
                        (int)bitmapBounds.Width,
                        (int)bitmapBounds.Height
                    );
                }
            }

            return bitmap;
        }

        #endregion
    }
}

 

300x250

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="800"
    Height="600"
    Title="FaceDetector 클래스 : DetectFacesAsync 메소드를 사용해 얼굴 탐지하기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Grid>
        <Border
            Margin="10"
            BorderThickness="1"
            BorderBrush="Black">
            <Image Name="image" />
        </Border>
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

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

            Loaded += Window_Loaded;
        }

        #endregion

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

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

        /// <summary>
        /// 윈도우 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            FaceDetectionService service = new FaceDetectionService();

            await using FileStream fileStream = File.OpenRead(@"IMAGE\sample.jpg");

            var faces = await service.GetDetectedFaceList(fileStream);

            System.Drawing.Bitmap FacesBitmap = service.GetDetectedFaceBitmap(fileStream, faces, System.Drawing.Color.Red, 8);

            this.image.Source = GetBitmapImage(FacesBitmap);
        }

        #endregion

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

        #region 비트맵 이미지 구하기 - GetBitmapImage(bitmap)

        /// <summary>
        /// 비트맵 이미지 구하기
        /// </summary>
        /// <param name="bitmap">비트맵</param>
        /// <returns>비트맵 이미지</returns>
        private BitmapImage GetBitmapImage(System.Drawing.Bitmap bitmap)
        {
            using MemoryStream stream = new MemoryStream();

            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);

            stream.Position = 0;

            BitmapImage bitmapImage = new BitmapImage();

            bitmapImage.BeginInit();

            bitmapImage.CacheOption  = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = stream;

            bitmapImage.EndInit();

            bitmapImage.Freeze();

            return bitmapImage;
        }

        #endregion
    }
}
728x90
반응형
그리드형
Posted by 사용자 icodebroker

댓글을 달아 주세요