source: eviacam/trunk/fuentes/creavision/crvskindetection.cpp @ 567

Last change on this file since 567 was 567, checked in by mabarracus, 4 years ago

updated sources to version 2.0.3

  • Property svn:executable set to *
File size: 4.6 KB
Line 
1/////////////////////////////////////////////////////////////////////////////
2// Name:        crvskindetection.cpp
3// Purpose: 
4// Author:      Cesar Mauri Loba (cesar at crea-si dot com)
5// Modified by:
6// Created:     23/02/2008
7// Copyright:   (C) 2008 Cesar Mauri Loba - CREA Software Systems
8//
9//  This program is free software: you can redistribute it and/or modify
10//  it under the terms of the GNU General Public License as published by
11//  the Free Software Foundation, either version 3 of the License, or
12//  (at your option) any later version.
13//
14//  This program is distributed in the hope that it will be useful,
15//  but WITHOUT ANY WARRANTY; without even the implied warranty of
16//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17//  GNU General Public License for more details.
18//
19//  You should have received a copy of the GNU General Public License
20//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21/////////////////////////////////////////////////////////////////////////////
22#include "crvmisc.h"
23#include "crvskindetection.h"
24#include <assert.h>
25#include <string.h>
26
27void CSkinRegionModel::crvBinarizeSkin_KToyama (IplImage *pIpl, float &krg_min, 
28                                                                                                  float &krg_max, float &krb_min, 
29                                                                                                  float &krb_max)
30{
31        int x, y, xIni, yIni, xLim, yLim;
32        float krg, krb;
33        unsigned char *pSrc;
34
35        assert (pIpl);
36
37        crvGetROILimits (pIpl, xIni, yIni, xLim, yLim);
38       
39        for (y= yIni; y< yLim; y++) {
40                pSrc= (unsigned char *) crvImgOffset (pIpl, xIni, y);           
41                for (x= xIni; x< xLim; x++) {
42                        krg= (float) pSrc[0] / (float) pSrc[1];
43                        krb= (float) pSrc[0] / (float) pSrc[2];
44
45                        if (krg_min<= krg && krg_max>= krg &&
46                                krb_min<= krb && krb_max>= krb) {
47                                pSrc[0]= pSrc[1]= pSrc[2]= 255;
48                        }
49                        else 
50                                pSrc[0]= pSrc[1]= pSrc[2]= 0;
51
52                        pSrc+= 4;
53                }
54        }
55}
56
57//
58// Skin Models Definition
59//
60#define min(x,y) (x< y? x : y)
61#define max(x,y) (x> y? x : y)
62#define min3(x,y,z) (min(min(x,y),z))
63#define max3(x,y,z) (max(max(x,y),z))
64
65
66// The skin colour at uniform daylight illumination
67#define IS_SKIN_PEER(R,G,B)             (R> 95 && G> 40 && B> 20 && R> G && R> B && \
68                                                                (max3(R,G,B) - min3(R,G,B))> 15 && \
69                                                                ((R-G)> 15 || (G-R)> 15))
70
71// The skin colour under flashlight or (light) daylight
72// lateral illumination
73#define IS_SKIN_PEER2(R,G,B)    (R> 220 && G> 210 && B> 170 && \
74                                                                ((R-G)< 15 || (G-R)< 15) && \
75                                                                R> B && G> B)
76                                                               
77                                                               
78
79inline bool IsSkin_GomezMorales_1 (int R, int G, int B)
80{
81        float r, g, b, rgb, rgb2;
82
83        r= (float) R / 255.0f;  g= (float) G / 255.0f;  b= (float) B / 255.0f;
84        rgb= r + g + b;
85        rgb2= rgb * rgb;
86
87        return ( ((r/g)> 1.185) && (((r*b)/rgb2)> 0.107) && (((r*g)/rgb2)> 0.112) );
88}
89
90inline bool IsSkin_GomezMorales_2 (int R, int G, int B)
91{
92        float r, g, b, rgb;
93
94        r= (float) R / 255.0f;  g= (float) G / 255.0f;  b= (float) B / 255.0f;
95        rgb= r + g + b;
96       
97        return ( (b/g)< 1.249 && (rgb / (3*r))> 0.696 && 
98                         ((1.0/3.0) - (b/rgb))> 0.014 && (g / (3*rgb))< 0.108 );
99}
100
101void CSkinRegionModel::crvBinarizeSkin  (IplImage *pSrc, IplImage *pDst)
102{
103        int x, y, xIni, yIni, xLim, yLim, srcBytesPPixel, dstBytesPPixel;
104        unsigned char *pSrcB, *pDstB;
105        bool isBGR= false;
106       
107        assert (pSrc && pSrc->imageData && pDst && pDst->imageData);
108        if (!strncmp (pSrc->channelSeq, "BGR", 4) || !strncmp (pSrc->channelSeq, "BGRA", 4))
109                isBGR= true;
110        else if (!strncmp (pSrc->channelSeq, "RGB", 4) || !strncmp (pSrc->channelSeq, "RGBA", 4))
111                isBGR= false;
112        else
113                assert (false);
114        assert (!strncmp (pDst->channelSeq, "GRAY", 4) || !strncmp (pDst->channelSeq, "BGRA", 4));
115
116        // Get depth
117        srcBytesPPixel= pSrc->nChannels;
118        dstBytesPPixel= pDst->depth / 8;
119       
120        cvSetZero(pDst);
121       
122        crvGetROILimits (pSrc, xIni, yIni, xLim, yLim);
123
124        if (isBGR)
125                for (y= yIni; y< yLim; y++) {
126                        pSrcB= (unsigned char *) crvImgOffset (pSrc, xIni, y);
127                        pDstB= (unsigned char *) crvImgOffset (pDst, xIni, y);
128
129                        for (x= xIni; x< xLim; x++) {
130
131                                if (IS_SKIN_PEER(pSrcB[2],pSrcB[1],pSrcB[0]))                   
132                                {
133                                        // Color acceptat
134                                        pDstB[0]= 255;
135                                        if (dstBytesPPixel> 1)
136                                        {
137                                                pDstB[1]= 255;
138                                                if (dstBytesPPixel> 2)
139                                                {
140                                                        pDstB[2]= 255;
141                                                }
142                                        }
143                                }                       
144
145                                pSrcB+= srcBytesPPixel;
146                                pDstB+= dstBytesPPixel;
147                        }
148                }
149        else
150                for (y= yIni; y< yLim; y++) {
151                        pSrcB= (unsigned char *) crvImgOffset (pSrc, xIni, y);
152                        pDstB= (unsigned char *) crvImgOffset (pDst, xIni, y);
153
154                        for (x= xIni; x< xLim; x++) {
155
156                                if (IS_SKIN_PEER(pSrcB[0],pSrcB[1],pSrcB[2]))                   
157                                {
158                                        // Color acceptat
159                                        pDstB[0]= 255;
160                                        if (dstBytesPPixel> 1)
161                                        {
162                                                pDstB[1]= 255;
163                                                if (dstBytesPPixel> 2)
164                                                {
165                                                        pDstB[2]= 255;
166                                                }
167                                        }
168                                }                       
169
170                                pSrcB+= srcBytesPPixel;
171                                pDstB+= dstBytesPPixel;
172                        }
173                }
174}
Note: See TracBrowser for help on using the repository browser.