Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

주간 닷넷에 소개된,

주간닷넷 2016년 8월 2일
; https://learn.microsoft.com/en-us/archive/blogs/eva/%EC%A3%BC%EA%B0%84%EB%8B%B7%EB%84%B7-2016%EB%85%84-8%EC%9B%94-2%EC%9D%BC

내용 중에 다음의 것을 한번 실습해 보았습니다. ^^

Detect and Blur Faces with .NET Core and Face API
; https://carlos.mendible.com/2016/07/30/detect-and-blur-faces-with-dotnetcore-and-face-api/

위의 내용에 소개된 Face API는 마이크로소프트가 Azure를 통해 서비스하는 "Cognitive Services" 중의 하나입니다. 따라서 이 API를 사용하려면 APIKey를 받아야 하고 그러려면 다음의 페이지에서 구독 신청을 해야 합니다.

Cognitive Services - Get started for free
; https://www.microsoft.com/cognitive-services/en-us/sign-up

그럼 다양한 서비스를 신청할 수 있는데,

Cognitive Services - Request new trials
; https://azure.microsoft.com/en-us/services/cognitive-services/

Face API의 경우 (분당 20건의 제한으로) 월 3만 건의 호출을 무료로 사용할 수 있습니다.

어쨌든, 신청을 하면 API Key를 받았을 테고 시작해 보겠습니다. ^^




사실 모든 순서는 "Detect and Blur Faces with .NET Core and Face API" 글에 잘 나와 있습니다. 하지만, .NET Core를 바탕으로 하고 있는데, 그냥 윈도우 응용 프로그램에도 쉽게 적용할 수 있습니다.

제 경우에는 윈도우 콘솔 프로그램으로 시작해 보겠습니다. 프로젝트 만든 후, NuGet을 통해 "Microsoft Cognitive Services Face API"와 함께 관련 라이브러리를 참조 추가합니다.

PM> Install-Package Microsoft.ProjectOxford.Face
PM> Install-Package ChyImageProcessorCore -Pre
PM> Install-Package System.Numerics.Vectors -Pre 
PM> Install-Package System.Runtime.CompilerServices.Unsafe 

그다음 App.config에 Face API Key를 입력해 설정해 두고,

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
    <appSettings>
        <add key="FaceAPIKey" value="...[your_face_api_key]..." />
    </appSettings>
</configuration>

"Detect and Blur Faces with .NET Core and Face API" 글의 소스 코드를 그대로 적용하시면 됩니다.

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ImageProcessorCore;
using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Face.Contract;
using System.Configuration;

public class Program
{
    const string sourceImage = "face_blur_1.png";

    public static void Main(string[] args)
    {
        const string destinationImage = "detectedfaces.jpg";

        var detects = DetectFaces(sourceImage, ConfigurationManager.AppSettings["FaceAPIKey"]);
        var faceRects = detects.Result;

        Console.WriteLine($"Detected {faceRects.Length} faces");

        BlurFaces(faceRects, sourceImage, destinationImage);

        Console.WriteLine($"Done!!!");
    }

    private static void BlurFaces(FaceRectangle[] faceRects, string sourceImage, string destinationImage)
    {
        if (File.Exists(destinationImage))
        {
            File.Delete(destinationImage);
        }

        if (faceRects.Length > 0)
        {
            using (FileStream stream = File.OpenRead(sourceImage))
            using (FileStream output = File.OpenWrite(destinationImage))
            {
                var image = new Image<Color, uint>(stream);

                foreach (var faceRect in faceRects)
                {
                    var rectangle = new Rectangle(
                        faceRect.Left,
                        faceRect.Top,
                        faceRect.Width,
                        faceRect.Height);

                    image = image.BoxBlur(20, rectangle);
                }

                image.SaveAsJpeg(output);
            }
        }
    }

    private static async Task<FaceRectangle[]> DetectFaces(string imageFilePath, string apiKey)
    {
        var faceServiceClient = new FaceServiceClient(apiKey);

        try
        {
            using (Stream imageFileStream = File.OpenRead(imageFilePath))
            {
                var faces = await faceServiceClient.DetectAsync(imageFileStream);
                var faceRects = faces.Select(face => face.FaceRectangle);
                return faceRects.ToArray();
            }
        }
        catch (Exception)
        {
            return new FaceRectangle[0];
        }
    }
}

직접 실습을 해봤는데, 좀 실망(?!)스럽군요. 아래는 원본 사진에서 위의 프로그램을 돌려 얼굴을 인식해 흐림 처리한 결과입니다. 그런데... 요즘 핫한 사람의 얼굴조차 인식하지 못하고 있습니다. ^^;

face_blur_0.jpg

(첨부 파일은 이 글의 예제 코드를 포함합니다.)









[최초 등록일: ]
[최종 수정일: 4/17/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2021-06-16 09시16분
How to get started with neural text to speech in Azure | Azure Tips and Tricks
; https://www.youtube.com/watch?v=dl0amatX5zs&ab_channel=MicrosoftAzure
정성태

... 106  107  108  109  [110]  111  112  113  114  115  116  117  118  119  120  ...
NoWriterDateCnt.TitleFile(s)
11175정성태4/5/201725921.NET Framework: 652. C# 개발자를 위한 C++ COM 객체의 기본 구현 방식 설명파일 다운로드1
11174정성태4/3/201719449VC++: 116. Visual Studio 단위 테스트 - Failed to set up the execution context to run the test
11173정성태4/3/201722994VC++: 115. Visual Studio에서 C++ DLL을 대상으로 단위 테스트할 때 비정상 종료한다면?파일 다운로드1
11172정성태4/3/201722157.NET Framework: 651. C# - 특정 EXE 프로세스를 종료시킨 EXE를 찾아내는 방법파일 다운로드1
11171정성태3/31/201718866VS.NET IDE: 114. Visual Studio 디버깅 경고 창 - You are debugging a Release build of ...
11170정성태3/31/201720748.NET Framework: 650. C# - CachedAnonymousMethodDelegate 유형의 코드 생성
11169정성태3/30/201720611VC++: 114. C++ vtable의 가상 함수 호출 가로채기파일 다운로드1
11168정성태3/29/201723930VC++: 113. C++ 클래스 상속 관계의 vtable 생성 과정
11167정성태3/28/201724254VC++: 112. C++의 가상 함수 테이블 (vtable)은 언제 생성될까요? [2]
11166정성태3/28/201718482오류 유형: 382. System.Data.SqlClient.SqlException - Arithmetic overflow error converting IDENTITY to data type int.
11165정성태3/27/201721755오류 유형: 381. Visual C++에서 min, max 함수를 사용한 경우 C2589, C2059 컴파일 오류 발생
11164정성태3/27/201730096VC++: 111. C++ 클래스의 상속에 따른 메모리 구조 [2]파일 다운로드1
11163정성태3/25/201719889VC++: 110. CreateThread Win32 API에 C++ 클래스의 멤버 함수를 전달하는 방법파일 다운로드1
11162정성태3/24/201724108오류 유형: 380. Visual Studio 빌드 실패 - The OutputPath property is not set for project
11161정성태3/24/201716818오류 유형: 379. ICOMAdminCatalog.GetCollection 호출 시 0x80070422 예외 발생
11160정성태3/23/201721723.NET Framework: 649. ASP.NET - Server cannot append header after HTTP headers have been sent. (HTTP 헤더를 보낸 후에는 서버에서 헤더를 추가할 수 없습니다.)파일 다운로드1
11159정성태3/23/201719032Windows: 136. Memory-mapped File은 Private Bytes 크기에 포함될까요?파일 다운로드1
11158정성태3/22/201718640디버깅 기술: 85. Windbg - SOS 디버깅 사례 System.NullReferenceException 예외 추적
11157정성태3/22/201721902.NET Framework: 648. Dictionary<TKey, TValue>를 deep copy하는 방법파일 다운로드1
11156정성태3/21/201722532.NET Framework: 647. 닷넷(C#) 코드로 인증서 요청 코드 만드는 방법파일 다운로드1
11155정성태3/21/201722780.NET Framework: 646. SslStream의 CipherAlgorithm 선택이 가능할까요?파일 다운로드1
11154정성태3/5/201729769VC++: 109. DLL에서 STL 객체를 인자/반환값으로 갖는 함수를 제공할 때, 그 함수를 외부에서 사용하는 경우 비정상 종료한다면? [2]파일 다운로드1
11153정성태3/5/201729144VC++: 108. DLL에 정의된 C++ template 클래스의 복사 생성자 문제파일 다운로드1
11152정성태3/4/201722827VC++: 107. VirtualAlloc, HeapAlloc, GlobalAlloc, LocalAlloc, malloc, new의 차이점파일 다운로드1
11151정성태3/3/201723399VC++: 106. DLL 개발자가 주의해야 할 Secure CRT 함수 사용 [1]파일 다운로드1
11150정성태2/21/201719334.NET Framework: 645. Visual Studio Fakes 기능에서 Shim... 클래스가 생성되지 않는 경우 [5]
... 106  107  108  109  [110]  111  112  113  114  115  116  117  118  119  120  ...