{"id":415,"date":"2025-03-15T21:22:46","date_gmt":"2025-03-16T00:22:46","guid":{"rendered":"https:\/\/www.wagnersalvi.com.br\/?p=415"},"modified":"2025-03-15T21:44:19","modified_gmt":"2025-03-16T00:44:19","slug":"reconhecimento-de-imagens-em-c","status":"publish","type":"post","link":"http:\/\/www.wagnersalvi.com.br\/?p=415","title":{"rendered":"Reconhecimento de Imagens em C#"},"content":{"rendered":"\n<p>O processamento de imagens e a vis\u00e3o computacional s\u00e3o \u00e1reas que t\u00eam ganhado grande relev\u00e2ncia em aplica\u00e7\u00f5es modernas, como seguran\u00e7a, automa\u00e7\u00e3o industrial e an\u00e1lise de v\u00eddeos. No ecossistema C#, uma das bibliotecas mais populares para esse tipo de tarefa \u00e9 a Emgu.CV.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">O que \u00e9 a Emgu.CV?<\/h2>\n\n\n\n<p>A <strong>OpenCV (Open Source Computer Vision Library)<\/strong> \u00e9 uma biblioteca de c\u00f3digo aberto amplamente utilizada para processamento de imagens e vis\u00e3o computacional. Ela fornece diversas funcionalidades para an\u00e1lise de imagens, detec\u00e7\u00e3o de objetos, reconhecimento facial, manipula\u00e7\u00e3o de v\u00eddeos, aprendizado de m\u00e1quina e muito mais. Foi escrita principalmente em <strong>C++<\/strong> e possui bindings para outras linguagens, como <strong>Python, Java e C#<\/strong>.<\/p>\n\n\n\n<p>O Emgu CV \u00e9 um wrapper para a OpenCV que permite que desenvolvedores usem a OpenCV no ambiente .NET (C#, VB.NET, F#). Ele encapsula as funcionalidades da OpenCV em classes e m\u00e9todos que podem ser utilizados diretamente no C#.<\/p>\n\n\n\n<p>Um wrapper \u00e9 uma camada de abstra\u00e7\u00e3o que envolve outra biblioteca ou c\u00f3digo para facilitar seu uso em diferentes linguagens ou ambientes. O Emgu CV \u00e9 um wrapper porque:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Fornece bindings para OpenCV<\/strong>: Ele exp\u00f5e as fun\u00e7\u00f5es da OpenCV de forma mais amig\u00e1vel para o ambiente .NET, tornando o uso da biblioteca mais intuitivo<\/li>\n\n\n\n<li><strong>Ele usa a OpenCV como base<\/strong>: O Emgu CV n\u00e3o implementa algoritmos de vis\u00e3o computacional por conta pr\u00f3pria, mas apenas disponibiliza os da OpenCV para serem usados no .NET.<\/li>\n\n\n\n<li><strong>Facilita a interoperabilidade<\/strong>: A OpenCV \u00e9 escrita em C++, e o Emgu CV fornece um meio de us\u00e1-la em C# e .NET sem precisar escrever c\u00f3digo em C++ diretamente.<\/li>\n\n\n\n<li><strong>Gerencia ponteiros e chamadas nativas<\/strong>: Como a OpenCV usa ponteiros e estruturas de dados de baixo n\u00edvel, o Emgu CV converte esses elementos para objetos gerenciados do .NET.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Principais funcionalidades da Emgu.CV<\/h2>\n\n\n\n<p>A biblioteca oferece diversas funcionalidades, incluindo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Processamento de imagens<\/strong>: Aplica\u00e7\u00e3o de filtros, detec\u00e7\u00e3o de bordas, transforma\u00e7\u00e3o de cores, entre outros.<\/li>\n\n\n\n<li><strong>Detec\u00e7\u00e3o de objetos e reconhecimento facial<\/strong>: Algoritmos como Haar Cascade e redes neurais para identifica\u00e7\u00e3o de rostos.<\/li>\n\n\n\n<li><strong>Processamento de v\u00eddeo em tempo real<\/strong>: Captura de v\u00eddeo de webcams e c\u00e2meras IP.<\/li>\n\n\n\n<li><strong>Reconhecimento de padr\u00f5es<\/strong>: Identifica\u00e7\u00e3o de formas, leitura de c\u00f3digos de barras e OCR (Optical Character Recognition).<\/li>\n\n\n\n<li><strong>Integra\u00e7\u00e3o com aprendizado de m\u00e1quina<\/strong>: Possibilidade de usar modelos treinados para reconhecimento avan\u00e7ado de imagens.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Aplicando Emgu.CV para reconhecimento facial em v\u00eddeos<\/h2>\n\n\n\n<p>Uma das aplica\u00e7\u00f5es mais comuns da Emgu.CV \u00e9 o reconhecimento facial em tempo real. Com apenas algumas linhas de c\u00f3digo, \u00e9 poss\u00edvel detectar rostos em um fluxo de v\u00eddeo ao vivo capturado pela webcam.<\/p>\n\n\n\n<p>No pr\u00f3ximo post, veremos um exemplo pr\u00e1tico em C# que demonstra como identificar faces em um v\u00eddeo ao vivo utilizando Emgu.CV.<\/p>\n\n\n\n<p>Se voc\u00ea deseja iniciar com vis\u00e3o computacional no C#, a Emgu.CV \u00e9 uma excelente escolha, pois combina a robustez do OpenCV com a facilidade de desenvolvimento no ecossistema .NET. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Exemplo de Reconhecimento Facial em C#<\/h2>\n\n\n\n<p><strong>Requisitos:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Visual Studio 2022 com .Net Core 8 instalado<\/li>\n\n\n\n<li>C\u00e2mera de pelo menos 720p (abaixo pode n\u00e3o ter resolu\u00e7\u00e3o suficiente)<\/li>\n\n\n\n<li>Biblioteca Emgu.CV (Baixar via Nuget)<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/opencv\/opencv\/tree\/master\/data\/haarcascades\">Download <\/a>de um modelo j\u00e1 treinado de reconhecimento facial <\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Passo a Passo:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cria\u00e7\u00e3o de um projeto WPF dentro do Visual Studio 2022<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"859\" height=\"221\" src=\"https:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image.png\" alt=\"\" class=\"wp-image-416\" srcset=\"http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image.png 859w, http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-300x77.png 300w, http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-768x198.png 768w\" sizes=\"auto, (max-width: 859px) 100vw, 859px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Instala\u00e7\u00e3o dos Pacotes Emgu.CV e Emgu.CV.runtime.windows<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"978\" height=\"189\" src=\"https:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-2.png\" alt=\"\" class=\"wp-image-418\" srcset=\"http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-2.png 978w, http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-2-300x58.png 300w, http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-2-768x148.png 768w\" sizes=\"auto, (max-width: 978px) 100vw, 978px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fazer download neste <a href=\"https:\/\/github.com\/opencv\/opencv\/tree\/master\/data\/haarcascades\">link <\/a>do arquivo haarcascade_frontalface_default.xml . O arquivo  \u00e9 um classificador em cascata baseado no algoritmo Haar Cascade para detec\u00e7\u00e3o de rostos frontais. Ele faz parte dos modelos pr\u00e9-treinados fornecidos pelo OpenCV e \u00e9 amplamente utilizado para reconhecimento facial em aplica\u00e7\u00f5es de vis\u00e3o computacional. <\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Colar o c\u00f3digo abaixo em C#<\/li>\n<\/ul>\n\n\n\n<p>Arquivo XAML<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;Window\n    x:Class=\"WpfApp2.MainWindow\"\n    xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\n    xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\n    xmlns:d=\"http:\/\/schemas.microsoft.com\/expression\/blend\/2008\"\n    xmlns:mc=\"http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006\"\n    Title=\"Reconhecimento de Face em C#\"\n    Width=\"800\"\n    Height=\"450\"\n    Closing=\"MainWindow_OnClosing\"\n    mc:Ignorable=\"d\">\n    &lt;Grid>\n        &lt;Image\n            x:Name=\"cameraImage\"\n            HorizontalAlignment=\"Stretch\"\n            VerticalAlignment=\"Stretch\" \/>\n    &lt;\/Grid>\n&lt;\/Window><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Arquivo Cs<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using Emgu.CV;\nusing Emgu.CV.Structure;\nusing System.Drawing;\nusing System.Windows;\nusing System.Windows.Interop;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Threading;\n\nnamespace WpfApp2\n{\n\tpublic partial class MainWindow : Window\n\t{\n\t\tprivate VideoCapture capture;\n\t\tprivate CascadeClassifier faceCascade;\n\t\tprivate bool isRunning = false;\n\t\tprivate DispatcherTimer timer;\n\n\t\tpublic MainWindow()\n\t\t{\n\t\t\tInitializeComponent();\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t\/\/ Inicializa a captura de v\u00eddeo (c\u00e2mera padr\u00e3o)\n\t\t\t\tcapture = new VideoCapture();\n\n\t\t\t\t\/\/ Carrega o classificador Haar Cascade para detec\u00e7\u00e3o facial\n\t\t\t\tfaceCascade = new CascadeClassifier(\"haarcascade_frontalface_default.xml\"); \/\/ Certifique-se de ter o arquivo XML\n\n\t\t\t\t\/\/ Inicializa o timer para atualizar a imagem\n\t\t\t\ttimer = new DispatcherTimer();\n\t\t\t\ttimer.Tick += ProcessFrame;\n\t\t\t\ttimer.Interval = TimeSpan.FromMilliseconds(30); \/\/ Ajuste conforme necess\u00e1rio\n\t\t\t\ttimer.Start();\n\n\t\t\t\tisRunning = true;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tMessageBox.Show($\"Erro ao inicializar: {ex.Message}\");\n\t\t\t}\n\t\t}\n\n\t\tprivate void ProcessFrame(object sender, EventArgs e)\n\t\t{\n\t\t\tif (!isRunning) return;\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tMat frame = capture.QueryFrame();\n\t\t\t\tif (frame == null) return;\n\n\t\t\t\tImage&lt;Bgr, byte> image = frame.ToImage&lt;Bgr, byte>();\n\n\t\t\t\t\/\/ Detecta rostos na imagem\n\t\t\t\tRectangle[] faces = faceCascade.DetectMultiScale(\n\t\t\t\t\timage,\n\t\t\t\t\t1.1,\n\t\t\t\t\t10,\n\t\t\t\t\tSystem.Drawing.Size.Empty);\n\n\t\t\t\t\/\/ Desenha ret\u00e2ngulos verdes ao redor dos rostos detectados\n\t\t\t\tforeach (Rectangle face in faces)\n\t\t\t\t{\n\t\t\t\t\timage.Draw(face, new Bgr(Color.Green), 2);\n\t\t\t\t}\n\n\t\t\t\t\/\/ Converte a imagem para um formato que WPF pode exibir\n\t\t\t\tBitmap bitmap = new Bitmap(frame.Width, frame.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);\n\t\t\t\tSystem.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);\n\n\t\t\t\tint imageSize = frame.Width * frame.Height * 3; \/\/ 3 bytes por pixel (B, G, R)\n\t\t\t\tbyte[] data = new byte[imageSize];\n\t\t\t\tSystem.Runtime.InteropServices.Marshal.Copy(image.MIplImage.ImageData, data, 0, imageSize);\n\t\t\t\tSystem.Runtime.InteropServices.Marshal.Copy(data, 0, bitmapData.Scan0, imageSize);\n\n\t\t\t\tbitmap.UnlockBits(bitmapData);\n\n\t\t\t\tvar bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(\n\t\t\t\t\tbitmap.GetHbitmap(),\n\t\t\t\t\tIntPtr.Zero,\n\t\t\t\t\tInt32Rect.Empty,\n\t\t\t\t\tBitmapSizeOptions.FromEmptyOptions());\n\n\t\t\t\t\/\/ Exibe a imagem no controle Image da WPF\n\t\t\t\tcameraImage.Source = bitmapSource;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tMessageBox.Show($\"Erro ao processar frame: {ex.Message}\");\n\t\t\t\tStopCapture(); \/\/ Para a captura em caso de erro\n\t\t\t}\n\t\t}\n\n\t\tprivate void StopCapture()\n\t\t{\n\t\t\tif (timer != null)\n\t\t\t{\n\t\t\t\ttimer.Stop();\n\t\t\t\ttimer = null;\n\t\t\t}\n\t\t\tif (capture != null)\n\t\t\t{\n\t\t\t\tcapture.Stop();\n\t\t\t\tcapture.Dispose();\n\t\t\t\tcapture = null;\n\t\t\t}\n\t\t\tif (faceCascade != null)\n\t\t\t{\n\t\t\t\tfaceCascade.Dispose();\n\t\t\t\tfaceCascade = null;\n\t\t\t}\n\t\t\tisRunning = false;\n\t\t}\n\n\t\tprivate void MainWindow_OnClosing(object sender, System.ComponentModel.CancelEventArgs e)\n\t\t{\n\t\t\tStopCapture();\n\t\t}\n\t}\n}<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Abaixo uma imagem de teste da aplica\u00e7\u00e3o funcionando, reconhecendo meu rosto e deixando dentro de um quadro verde<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"443\" src=\"https:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-4.png\" alt=\"\" class=\"wp-image-420\" srcset=\"http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-4.png 786w, http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-4-300x169.png 300w, http:\/\/www.wagnersalvi.com.br\/wp-content\/uploads\/2025\/03\/image-4-768x433.png 768w\" sizes=\"auto, (max-width: 786px) 100vw, 786px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Haar Cascade<\/h2>\n\n\n\n<p>O arquivo <strong>haarcascade_frontalface_default.xml<\/strong> \u00e9 um <strong>classificador em cascata<\/strong> baseado no algoritmo <strong>Haar Cascade<\/strong> para detec\u00e7\u00e3o de rostos frontais. Ele faz parte dos modelos pr\u00e9-treinados fornecidos pelo <strong>OpenCV<\/strong> e \u00e9 amplamente utilizado para reconhecimento facial em aplica\u00e7\u00f5es de vis\u00e3o computacional.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Como Funciona?<\/h3>\n\n\n\n<p>O algoritmo Haar Cascade foi desenvolvido por Paul Viola e Michael Jones e funciona atrav\u00e9s de um treinamento com milhares de imagens positivas (com rostos) e negativas (sem rostos). Ele utiliza janelas deslizantes para analisar diferentes partes da imagem e identificar padr\u00f5es que correspondam a um rosto.<\/p>\n\n\n\n<p>O modelo treinado \u00e9 armazenado no formato XML, contendo os coeficientes necess\u00e1rios para a detec\u00e7\u00e3o.<\/p>\n\n\n\n<p>Dentro deste <a href=\"https:\/\/github.com\/opencv\/opencv\/tree\/master\/data\/haarcascades\">link <\/a>temos diversos modelos pr\u00e9 treinados, e pode ser encontrados diversos, como por exemplo modelos que avaliam n\u00e3o somente rosto mas corpo todo, se est\u00e1 ou n\u00e3o de \u00f3culos, uso de m\u00e1scara ,etc<\/p>\n<p>Views: 0<\/p>","protected":false},"excerpt":{"rendered":"<p>O processamento de imagens e a vis\u00e3o computacional s\u00e3o \u00e1reas que t\u00eam ganhado grande relev\u00e2ncia em aplica\u00e7\u00f5es modernas, como seguran\u00e7a, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":421,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[49],"tags":[205,212],"class_list":["post-415","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacao","tag-machine-learning","tag-reconhecimento-facial"],"_links":{"self":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts\/415","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=415"}],"version-history":[{"count":2,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts\/415\/revisions"}],"predecessor-version":[{"id":423,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/posts\/415\/revisions\/423"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=\/wp\/v2\/media\/421"}],"wp:attachment":[{"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=415"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.wagnersalvi.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}