Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- Marvin Project <2007-2009>
- Initial version by:
- Danilo Rosetto Munoz
- Fabio Andrijauskas
- Gabriel Ambrosio Archanjo
- site: http://marvinproject.sourceforge.net
- GPL
- Copyright (C) <2007>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- /**
- MARVIN Project
- Initial version by:
- Danilo Rosetto Muñoz
- Fábio Andrijauskas
- Gabriel Ambrósio Archanjo
- site: http://marvin.incubadora.fapesp.br/
- GPL
- Copyright (C) <2007>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- package marvin.test;
- import java.awt.Color;
- import marvin.gui.MarvinAttributesPanel;
- import marvin.image.MarvinImage;
- import marvin.image.MarvinImageMask;
- import marvin.plugin.MarvinAbstractImagePlugin;
- import marvin.test.MarvinTestCase;
- import marvin.util.MarvinAttributes;
- /**
- * Locates skin color pixels in an image.
- * @author Barry McCullagh
- * @version 08/05/2009
- */
- public class SkinColorDetection extends MarvinAbstractImagePlugin implements Runnable
- {
- MarvinAttributes attributes;
- public void load(){
- attributes = getAttributes();
- }
- public MarvinAttributesPanel getAttributesPanel(){
- return null;
- }
- /**
- * Initiate the process of finding skin
- * @param MarvinImage - the image to be rotated
- * @param boolean - to display a preview
- */
- public void process
- (
- MarvinImage imageIn,
- MarvinImage imageOut,
- MarvinAttributes attributesOut,
- MarvinImageMask mask,
- boolean previewMode
- )
- {
- MarvinImage l_hsvImage = new MarvinImage(imageIn.getWidth(), imageIn.getHeight());
- l_imageHeight = imageIn.getHeight();
- l_imageWidth = imageIn.getWidth();
- ColorSpaceConverter l_colorspaceConverter = new ColorSpaceConverter();
- l_colorspaceConverter.process(imageIn, l_hsvImage, attributesOut, mask, false);
- /*The first step is to determine regions of the scene which
- * have appropriate skin tone.
- */
- findSkinColorPixels(imageIn, l_hsvImage, imageOut);
- }
- /**
- * Using heuristics, identify any pixels which may be skin colored.
- * @param imageIn
- * @param a_imageOut
- */
- MarvinImage imageIn;
- MarvinImage hsvImage;
- MarvinImage imageOut;
- int l_imageHeight ;
- int l_imageWidth;
- Thread t;
- boolean[] l_rules = {false, false, false};
- private void findSkinColorPixels(MarvinImage imageIn, MarvinImage hsvImage, MarvinImage imageOut)
- {
- this.imageIn=imageIn;
- this.imageOut=imageOut;
- this.hsvImage=hsvImage;
- t=new Thread();
- t.start();
- }
- int minX=-1;
- int minY=-1;
- int maxX=-1;
- int maxY=-1;
- @Override
- public void run()
- {
- int xx=0, yy=0,r,g,b;
- for( xx = 0; xx < l_imageWidth; xx++)
- {
- for(yy = 0; yy < l_imageHeight; yy++)
- {
- r = hsvImage.getIntComponent0(xx, yy);
- g = hsvImage.getIntComponent1(xx, yy);
- b = hsvImage.getIntComponent2(xx, yy);
- if((g>r*1.1 && g>b*1.1 )){
- imageOut.setIntColor(xx, yy, imageIn.getIntColor(xx, yy));
- if( minX == -1 || xx < minX) { minX = xx; }
- if( minY == -1 || yy < minY) { minY = yy; }
- if( maxX == -1 || xx > maxX) { maxX = xx; }
- if( maxY == -1 || yy > maxY) { maxY = yy; }
- }
- else
- {
- imageOut.setIntColor(xx, yy, 0);
- }
- }
- imageOut.update();
- //System.out.println("here");
- }
- MarvinTest.imagePanel.setImage(imageOut);
- MarvinTest.imagePanel.repaint();
- //drawrect(minX,minY,maxX,maxY);
- }
- private void drawrect(int minX2, int minY2, int maxX2, int maxY2) {
- imageOut.drawRect(minX2,minY2 , maxX2-minX2, maxY2-minY2, Color.red);
- imageOut.update();
- }
- //rules from http://graphics.cs.msu.ru/en/publications/text/gc2003vsa.pdf
- protected void checkRule2(int currentRed, int currentGreen, int currentBlue, boolean[] a_rules)
- {
- int l_maxCoords = max3nums(currentRed, currentGreen, currentBlue);
- int l_minCoords = min3nums(currentRed, currentGreen, currentBlue);
- if(currentRed > 95 && currentGreen >40 && currentBlue > 20
- && (l_maxCoords - l_minCoords) > 15
- && Math.abs(currentRed - currentGreen) > 15
- && currentRed > currentGreen
- && currentRed > currentBlue)
- {
- a_rules[2] = true;
- }
- else
- {
- a_rules[2] = false;
- }
- }
- public int max3nums(int a_red, int a_green, int a_blue)
- {
- int l_max = 0;
- if(a_red > a_green)
- {
- l_max = a_red;
- }
- else
- {
- l_max = a_green;
- }
- if(l_max < a_blue)
- {
- l_max = a_blue;
- }
- return l_max;
- }
- public int min3nums(int a_red, int a_green, int a_blue)
- {
- int l_min = 255;
- if(a_red < a_green)
- {
- l_min = a_red;
- }
- else
- {
- l_min = a_green;
- }
- if(l_min < a_blue)
- {
- return l_min;
- }
- else
- {
- return a_blue;
- }
- }
- //rules from http://lrv.fri.uni-lj.si/~peterp/publications/eurocon03.pdf
- protected void checkRule1(int currentRed, int currentGreen, int currentBlue, boolean[] rules)
- {
- if(currentRed > 220
- && currentGreen > 210
- && currentBlue > 170
- && Math.abs(currentRed - currentGreen) <= 15
- && currentRed > currentBlue
- && currentGreen > currentBlue)
- {
- rules[1] = true;
- }
- else
- {
- rules[1] = false;
- }
- }
- //rules from http://cs-people.bu.edu/ringb/CS585/PA1/source/ImageFunct.html
- protected void checkRule0(int currentRed, int currentGreen, int currentBlue, boolean[] rules)
- {
- int[] l_currentSkintone = new int[2];
- l_currentSkintone[0] = currentRed;
- l_currentSkintone[1] = currentGreen;
- //check the red and green component of the current pixel
- //If it does not fall in between the required values set as black
- if(currentRed < 40 || currentGreen < 40)
- {
- //a_imageOut.setRGB(xx, yy, 0, 0, 0);
- rules[0] = false;
- //System.out.println(a_rule1);
- }
- else
- {
- int[] l_VectorSkintoneA = new int[2];
- int[] l_VectorSkintoneB = new int[2];
- l_VectorSkintoneA[0] = 225;
- l_VectorSkintoneA[1] = 165;
- l_VectorSkintoneB[0] = 125;
- l_VectorSkintoneB[1] = 50;
- double l_angleCurrentSkinVectorA = calculateVectorAngle(l_VectorSkintoneA, l_currentSkintone);
- double l_angleCurrentSkinVectorB = calculateVectorAngle(l_VectorSkintoneB, l_currentSkintone);
- if(l_angleCurrentSkinVectorA < .995 && l_angleCurrentSkinVectorB < .995)
- {
- //a_imageOut.setRGB(xx, yy, 0, 0, 0);
- rules[0] = false;
- }
- else
- {
- rules[0] = true;
- //System.out.println(a_rule1);
- //a_imageOut.setRGB(xx, yy, a_imageIn.getRGB(xx,yy));
- }
- }
- }
- /**
- * Find the minimum and maximum component of all the R, G and B values in an image.
- * @param imageIn
- * @param minMax
- */
- protected void findMinMax(MarvinImage imageIn, int[] minMax)
- {
- for(int l_currentX = 0; l_currentX < imageIn.getWidth(); l_currentX++)
- {
- for(int l_currentY = 0; l_currentY < imageIn.getHeight(); l_currentY++)
- {
- int l_currentRed = imageIn.getIntComponent0(l_currentX, l_currentY);
- int l_currentGreen = imageIn.getIntComponent1(l_currentX, l_currentY);
- int l_currentBlue = imageIn.getIntComponent2(l_currentX, l_currentY);
- //check red
- if(l_currentRed < minMax[0])
- {
- minMax[0] = l_currentRed;
- }
- if(l_currentRed > minMax[1])
- {
- minMax[1] = l_currentRed;
- }
- //check green
- if(l_currentGreen < minMax[0])
- {
- minMax[0] = l_currentGreen;
- }
- if(l_currentGreen > minMax[1])
- {
- minMax[1] = l_currentGreen;
- }
- //check blue
- if(l_currentBlue < minMax[0])
- {
- minMax[0] = l_currentBlue;
- }
- if(l_currentBlue > minMax[1])
- {
- minMax[1] = l_currentBlue;
- }
- }
- }
- }
- /**
- * The borders may not be continuous so this method examines the pixels
- * around the current pixel of interest. If there is no border pixel neighbouring
- * it, it searches within a 16 connected connected neighbourhood to find a bordering pixel
- * @param l_borderedRegions
- */
- /**
- * Get the angle between two, two dimensional vectors
- * @param a_Vector1, a_Vector2 - the vectors who's angle of difference needs to be calculated
- */
- protected double calculateVectorAngle(int[] vector1, int[] vector2)
- {
- if (vector1.length != vector2.length)
- {
- return 0;
- }
- double l_magVector1 = findMagnitude(vector1);
- double l_magVector2 = findMagnitude(vector2);
- double l_dotProduct = dotProduct(vector1, vector2);
- return l_dotProduct / (l_magVector1 * l_magVector2);
- }
- /**
- * Find the magnitude of a 2 element 'vector'
- * @param vector
- * @return
- */
- protected double findMagnitude(int[] vector)
- {
- if (vector.length != 2)
- {
- return 0;
- }
- else
- {
- return Math.sqrt(vector[0]*vector[0] + vector[1]*vector[1] );
- }
- }
- //Static Method that returns the Dot Product of two Vectors
- private double dotProduct(int[] vector1, int[] vector2)
- {
- if (vector1.length != vector2.length && vector1.length != 2)
- {
- return 0;
- }
- return vector1[0]*vector2[0] + vector1[1]*vector2[1];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement