OpenCV Skin Detector with C#

http://www.prodigyproductionsllc.com/articles/programming/opencv-skin-detector-with-c/


To go along with the skin detector we wrote in Perl a few days ago, and because I’ve been doing some work today with OpenCV & C#, I thought I’d go ahead and show you how to create a skin detector using OpenCV and C#. Just like the skin detector we wrote in Perl, OpenCV already provides us with tools to do this out of the box. Because of that, creating a skin detector using OpenCV and C# is a piece of cake. In our Perl skin detector, we simply measured the percentage of skin viewable in an image and wrote that percentage to the console. In this tutorial, we’ll actually detect skin in a video feed from a standard USB webcam and will overlay the skin in the video feed with a different color. So, let’s begin.

Just like in my other OpenCV articles, we will need to add references to our OpenCvSharp libraries and add OpenCvSharp to our using statements. For this program, we will also need to add OpenCvSharp.CPlusPlus to our using statements. We’ll find out why in a moment.

using OpenCvSharp;
using OpenCvSharp.CPlusPlus;

Once you’ve added your references, you will need to setup your capture device and a window to display the video on. For that, you will use the CvCapture object which you’ll call “FromCamera” on. The FromCamera method has 2 overloaded methods. The first overload simply takes a camera index as its parameter. This index is only really important when you have more than one camera attached to your computer. If you do have multiple cameras, you will need to set this to the index of the camera you want OpenCV to use. To get the index for the camera you want to use, begin with 1 and increment the number until you find the camera of choice. After you’ve setup your capture device, go ahead and construct a CvWindow for displaying your video feed.

using (CvCapture cap = CvCapture.FromCamera(1))
using (CvWindow w = new CvWindow(“Skin Detector”))

Next, you’ll need to create a while-loop which will be used to keep the window from closing until you click on the window and press a key.

while (CvWindow.WaitKey(10) < 0)

Inside your while-loop, you’re gonna need to setup a few IplImages. The first of these images is simply a reference to the current frame from your capture device. The second image is an image which will contain the color-overlay. The third image is just a copy of the first image (the frame from the capture device). This last image will be a combination of the first 2 images and is what we’ll display in our CvWindow in just a bit.

Now that you have references to your capture device and have each frame referenced as an IplImage, it’s time to use the OpenCvSharp.CPlusPlus namespace we added to our using statements at the beginning of this article. The CPlusPlus package contains a class called CvAdaptiveSkinDetector. This is the class that is going to locate the skin in our frames, just as the name implies. Once you’ve built your detector object, you will need to call the “Process” method. This method accepts the image source (the first image from above), locates the skin in the image, and then stores that skin reference in the second image from above. So, if you were to draw the second image to the window, you would only see your skin and nothing else.

CvAdaptiveSkinDetector detector = new CvAdaptiveSkinDetector(1, MorphingMethod.None);
detector.Process(imgSrc, imgHueMask);

That’s pretty cool, but we’re not stopping there. Instead, we are now going to add a private method that will take that second image, color it green (or whatever color you choose), and overlay that image on top of the third (destination) image from above. This method will need to accept 3 parameters. The first parameter will be the skin-only image from above. The second parameter will be the image that we want to draw the green onto. And the third parameter will be the color we want to use. Note: You can hardcode the color and remove it from the parameters list if you don’t want to pass it into this method or in case you never plan on changing the color programmatically.

In the code below, you will notice that the first thing I do in my new method is a check to make sure that both incoming images are the same size and I throw an ArgumentException if they’re not. Since I’m manually specifying my images in the previous method, I know that my images are going to be the same size. So, this check isn’t required for this example, but I’m including it anyways. The reason both images have to be the same size is because we’re going to manually loop thru ever pixel in the skin-only image, find each pixel that represents skin, and then find the same pixel location in the other image and change that pixel color to green. Here is the entire method for doing that.

01 private void DisplaySkinPoints(IplImage imgHueMask, IplImage imgRgbDst, CvColor color)
02 {
03     if (imgHueMask.Size != imgRgbDst.Size)
04         throw new ArgumentException();
05  
06     for (int y = 0; y < imgHueMask.Height; y++)
07     {
08         for (int x = 0; x < imgHueMask.Width; x++)
09         {
10             byte value = (byte)imgHueMask[y, x].Val0;
11             if (value != 0)
12             {
13                 imgRgbDst[y, x] = color;
14             }
15         }
16     }
17 }

After you’ve repainted the pixels in your destination image, all you’re left to do is to draw that image back to your window in the first method above. If you did everything correctly, you should be able to test the app at which point your skin should now be green like this:

OpenCV Skin Detection

The screenshot isn’t perfect because I did a screen grab from a moving video. So, there’s a little bit of “noise” in it. But, the video does look a lot better when it’s in real-time. Plus, the skin would be more prominent if I wasn’t wearing a white T-shirt. Or, maybe I just need to get out more and work on my tan? Here is the complete source code for this article. As always, if you have any questions or suggestions, feel free to post them in the comments below and I’ll help you any way I can. Until next time, HAPPY CODING!

01 using System;
02 using System.Collections.Generic;
03 using System.Diagnostics;
04 using System.Windows.Forms;
05 using System.Runtime.InteropServices;
06 using OpenCvSharp;
07 using OpenCvSharp.CPlusPlus;
08  
09 namespace EdgeDetect
10 {
11     class SkinDetector
12     {
13         public SkinDetector()
14         {
15             using (CvCapture cap = CvCapture.FromCamera(1))
16             using (CvWindow w = new CvWindow("Skin Detector"))
17             {
18                 while (CvWindow.WaitKey(10) < 0)
19                 {
20                     using (IplImage imgSrc = cap.QueryFrame())
21                     using (IplImage imgHueMask = new IplImage(imgSrc.Size, BitDepth.U8, 1))
22                     using (IplImage imgDst = imgSrc.Clone())
23                     {
24                         CvAdaptiveSkinDetector detector = newCvAdaptiveSkinDetector(1, MorphingMethod.None);
25                         detector.Process(imgSrc, imgHueMask);
26                         DisplaySkinPoints(imgHueMask, imgDst, CvColor.Green);
27  
28                         w.Image = imgDst;
29                     }
30                 }
31             }
32         }
33  
34         private void DisplaySkinPoints(IplImage imgHueMask, IplImage imgRgbDst, CvColor color)
35         {
36             if (imgHueMask.Size != imgRgbDst.Size)
37                 throw new ArgumentException();
38  
39             for (int y = 0; y < imgHueMask.Height; y++)
40             {
41                 for (int x = 0; x < imgHueMask.Width; x++)
42                 {
43                     byte value = (byte)imgHueMask[y, x].Val0;
44                     if (value != 0)
45                     {
46                         imgRgbDst[y, x] = color;
47                     }
48                 }
49             }
50         }
51     }
52 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了在C#中使用OpenCV进行图像去噪,你可以使用以下两种方法:高斯模糊(Gaussian Blur)和均值模糊(Blur)。 高斯模糊是一种常用的去噪方法,可以通过调整参数来控制去噪的程度。在C#中,你可以使用以下代码来进行高斯模糊: ``` Cv2.GaussianBlur(src_img, dst, new OpenCvSharp.Size(gussX.Value, gussY.Value), gussPX.Value, gussPY.Value); ``` 其中,`src_img`是输入图像,`dst`是输出图像,`gussX`和`gussY`是高斯核的大小,`gussPX`和`gussPY`是高斯核的标准差。 均值模糊也是一种简单有效的去噪方法,可以通过调整参数来控制去噪的程度。在C#中,你可以使用以下代码来进行均值模糊: ``` OpenCvSharp.Point point = new OpenCvSharp.Point(SharpPoint.Value, SharpPoint.Value); Cv2.Blur(src_img, dst, new OpenCvSharp.Size(meanKernelX.Value, meanKernelY.Value), point); ``` 其中,`src_img`是输入图像,`dst`是输出图像,`meanKernelX`和`meanKernelY`是均值核的大小,`SharpPoint`是均值核的锐化参数。 使用这两种方法可以帮助你在C#中实现图像去噪的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [c#Opencvsharp4学习笔记与心得(Winform)](https://blog.csdn.net/Iawfy_/article/details/124398457)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C# OpenCVSharp 记录 之一中值、均值、高斯滤波](https://blog.csdn.net/xaiqpl/article/details/118577496)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值