Advertisement
Guest User

Untitled

a guest
Apr 16th, 2013
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.15 KB | None | 0 0
  1. /**
  2. Marvin Project <2007-2009>
  3.  
  4. Initial version by:
  5.  
  6. Danilo Rosetto Munoz
  7. Fabio Andrijauskas
  8. Gabriel Ambrosio Archanjo
  9.  
  10. site: http://marvinproject.sourceforge.net
  11.  
  12. GPL
  13. Copyright (C) <2007>  
  14.  
  15. This program is free software; you can redistribute it and/or modify
  16. it under the terms of the GNU General Public License as published by
  17. the Free Software Foundation; either version 2 of the License, or
  18. any later version.
  19.  
  20. This program is distributed in the hope that it will be useful,
  21. but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. GNU General Public License for more details.
  24.  
  25. You should have received a copy of the GNU General Public License along
  26. with this program; if not, write to the Free Software Foundation, Inc.,
  27. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  28. */
  29.  
  30. /**
  31. MARVIN Project
  32.  
  33. Initial version by:
  34. Danilo Rosetto Muñoz
  35. Fábio Andrijauskas
  36. Gabriel Ambrósio Archanjo
  37.  
  38. site: http://marvin.incubadora.fapesp.br/
  39.  
  40. GPL
  41. Copyright (C) <2007>  
  42.  
  43. This program is free software; you can redistribute it and/or modify
  44. it under the terms of the GNU General Public License as published by
  45. the Free Software Foundation; either version 2 of the License, or
  46. any later version.
  47.  
  48. This program is distributed in the hope that it will be useful,
  49. but WITHOUT ANY WARRANTY; without even the implied warranty of
  50. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  51. GNU General Public License for more details.
  52.  
  53. You should have received a copy of the GNU General Public License along
  54. with this program; if not, write to the Free Software Foundation, Inc.,
  55. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  56. */
  57.  
  58. package marvin.test;
  59.  
  60.  
  61. import java.awt.Color;
  62.  
  63. import marvin.gui.MarvinAttributesPanel;
  64. import marvin.image.MarvinImage;
  65. import marvin.image.MarvinImageMask;
  66. import marvin.plugin.MarvinAbstractImagePlugin;
  67. import marvin.test.MarvinTestCase;
  68. import marvin.util.MarvinAttributes;
  69.  
  70.  
  71. /**
  72.  * Locates skin color pixels in an image.
  73.  * @author Barry McCullagh
  74.  * @version 08/05/2009
  75.  */
  76. public class SkinColorDetection extends MarvinAbstractImagePlugin  implements Runnable
  77. {
  78.    
  79.     MarvinAttributes attributes;
  80.  
  81.     public void load(){
  82.         attributes = getAttributes();
  83.     }
  84.  
  85.     public MarvinAttributesPanel getAttributesPanel(){
  86.         return null;
  87.     }
  88.  
  89.     /**
  90.      * Initiate the process of finding skin
  91.      * @param MarvinImage - the image to be rotated
  92.      * @param boolean - to display a preview
  93.      */
  94.     public void process
  95.     (
  96.         MarvinImage imageIn,
  97.         MarvinImage imageOut,
  98.         MarvinAttributes attributesOut,
  99.         MarvinImageMask mask,
  100.         boolean previewMode
  101.     )
  102.     {
  103.         MarvinImage l_hsvImage = new MarvinImage(imageIn.getWidth(), imageIn.getHeight());
  104.          l_imageHeight = imageIn.getHeight();
  105.          l_imageWidth = imageIn.getWidth();
  106.         ColorSpaceConverter l_colorspaceConverter = new ColorSpaceConverter();
  107.         l_colorspaceConverter.process(imageIn, l_hsvImage, attributesOut, mask, false);
  108.        
  109.        
  110.         /*The first step is to determine regions of the scene which
  111.          * have appropriate skin tone.
  112.          */
  113.         findSkinColorPixels(imageIn, l_hsvImage, imageOut);
  114.        
  115.        
  116.        
  117.        
  118.     }
  119.     /**
  120.      * Using heuristics, identify any pixels which may be skin colored.
  121.      * @param imageIn
  122.      * @param a_imageOut
  123.      */
  124.     MarvinImage imageIn;
  125.     MarvinImage hsvImage;
  126.     MarvinImage imageOut;
  127.     int l_imageHeight ;
  128.     int l_imageWidth;
  129.     Thread t;
  130.    
  131.     boolean[] l_rules = {false, false, false};
  132.     private void findSkinColorPixels(MarvinImage imageIn, MarvinImage hsvImage, MarvinImage imageOut)
  133.     {
  134.         this.imageIn=imageIn;
  135.         this.imageOut=imageOut;
  136.         this.hsvImage=hsvImage;
  137.     t=new Thread();
  138.     t.start();
  139.        
  140.     }
  141.     int minX=-1;
  142.     int minY=-1;
  143.     int maxX=-1;
  144.     int maxY=-1;
  145.     @Override
  146.     public void run()
  147.     {
  148.         int xx=0, yy=0,r,g,b;
  149.          
  150.         for( xx = 0; xx < l_imageWidth; xx++)
  151.         {
  152.             for(yy = 0; yy < l_imageHeight; yy++)
  153.             {
  154.                  r = hsvImage.getIntComponent0(xx, yy);
  155.                  g = hsvImage.getIntComponent1(xx, yy);
  156.                  b = hsvImage.getIntComponent2(xx, yy);
  157.                
  158.                 if((g>r*1.1 && g>b*1.1 )){
  159.                    
  160.                     imageOut.setIntColor(xx, yy, imageIn.getIntColor(xx, yy));
  161.                       if( minX == -1 || xx < minX) {   minX = xx;   }
  162.                         if( minY == -1 || yy < minY) {   minY = yy;   }
  163.                         if( maxX == -1 || xx > maxX) {   maxX = xx;   }
  164.                         if( maxY == -1 || yy > maxY) {   maxY = yy;   }
  165.                    
  166.                 }
  167.            
  168.                 else
  169.                 {
  170.                     imageOut.setIntColor(xx, yy, 0);
  171.                 }
  172.  
  173.                
  174.             }
  175.            
  176.             imageOut.update();         
  177.             //System.out.println("here");      
  178.         }
  179.         MarvinTest.imagePanel.setImage(imageOut);
  180.         MarvinTest.imagePanel.repaint();
  181.         //drawrect(minX,minY,maxX,maxY);
  182.     }
  183.     private void drawrect(int minX2, int minY2, int maxX2, int maxY2) {
  184.        
  185.         imageOut.drawRect(minX2,minY2 , maxX2-minX2, maxY2-minY2, Color.red);
  186.         imageOut.update();
  187.        
  188.     }
  189.  
  190.     //rules from http://graphics.cs.msu.ru/en/publications/text/gc2003vsa.pdf
  191.     protected void checkRule2(int currentRed, int currentGreen, int currentBlue, boolean[] a_rules)
  192.     {
  193.         int l_maxCoords = max3nums(currentRed, currentGreen, currentBlue);
  194.         int l_minCoords = min3nums(currentRed, currentGreen, currentBlue);
  195.         if(currentRed > 95 && currentGreen >40 && currentBlue > 20
  196.                 && (l_maxCoords - l_minCoords) > 15
  197.                 && Math.abs(currentRed - currentGreen) > 15
  198.                 && currentRed > currentGreen
  199.                 && currentRed > currentBlue)
  200.         {
  201.             a_rules[2] = true;
  202.         }
  203.         else
  204.         {
  205.             a_rules[2] = false;
  206.         }
  207.     }
  208.     public int max3nums(int a_red, int a_green, int a_blue)
  209.     {
  210.         int l_max = 0;
  211.         if(a_red > a_green)
  212.         {
  213.             l_max = a_red;
  214.         }
  215.         else
  216.         {
  217.             l_max = a_green;
  218.            
  219.         }
  220.         if(l_max < a_blue)
  221.         {
  222.             l_max = a_blue;
  223.         }
  224.        
  225.         return l_max;
  226.     }
  227.     public int min3nums(int a_red, int a_green, int a_blue)
  228.     {
  229.         int l_min = 255;
  230.         if(a_red < a_green)
  231.         {
  232.             l_min = a_red;
  233.         }
  234.         else
  235.         {
  236.             l_min = a_green;
  237.         }
  238.         if(l_min < a_blue)
  239.         {
  240.             return l_min;
  241.         }
  242.         else
  243.         {
  244.             return a_blue;
  245.         }
  246.     }
  247.    
  248.     //rules from http://lrv.fri.uni-lj.si/~peterp/publications/eurocon03.pdf
  249.     protected void checkRule1(int currentRed, int currentGreen, int currentBlue, boolean[] rules)
  250.     {
  251.         if(currentRed > 220
  252.                 && currentGreen > 210
  253.                 && currentBlue > 170
  254.                 && Math.abs(currentRed - currentGreen) <= 15
  255.                 && currentRed > currentBlue
  256.                 && currentGreen > currentBlue)
  257.         {
  258.             rules[1] = true;
  259.         }
  260.         else
  261.         {
  262.             rules[1] = false;
  263.         }
  264.     }
  265.    
  266.     //rules from http://cs-people.bu.edu/ringb/CS585/PA1/source/ImageFunct.html
  267.     protected void checkRule0(int currentRed, int currentGreen, int currentBlue, boolean[] rules)
  268.     {
  269.         int[] l_currentSkintone = new int[2];
  270.         l_currentSkintone[0] = currentRed;
  271.         l_currentSkintone[1] = currentGreen;
  272.         //check the red and green component of the current pixel
  273.         //If it does not fall in between the required values set as black
  274.         if(currentRed < 40  || currentGreen < 40)
  275.         {
  276.             //a_imageOut.setRGB(xx, yy, 0, 0, 0);
  277.             rules[0] = false;
  278.             //System.out.println(a_rule1);
  279.         }
  280.         else
  281.         {
  282.             int[] l_VectorSkintoneA = new int[2];
  283.             int[] l_VectorSkintoneB = new int[2];
  284.             l_VectorSkintoneA[0] = 225;
  285.             l_VectorSkintoneA[1] = 165;
  286.             l_VectorSkintoneB[0] = 125;
  287.             l_VectorSkintoneB[1] = 50;
  288.             double l_angleCurrentSkinVectorA = calculateVectorAngle(l_VectorSkintoneA, l_currentSkintone);
  289.             double l_angleCurrentSkinVectorB = calculateVectorAngle(l_VectorSkintoneB, l_currentSkintone);
  290.            
  291.             if(l_angleCurrentSkinVectorA < .995 && l_angleCurrentSkinVectorB < .995)
  292.             {
  293.                 //a_imageOut.setRGB(xx, yy, 0, 0, 0);
  294.                 rules[0] = false;
  295.                
  296.             }
  297.             else
  298.             {
  299.                 rules[0] = true;
  300.                 //System.out.println(a_rule1);
  301.                 //a_imageOut.setRGB(xx, yy, a_imageIn.getRGB(xx,yy));
  302.             }
  303.         }
  304.     }
  305.     /**
  306.      * Find the minimum and maximum component of all the R, G and B values in an image.
  307.      * @param imageIn
  308.      * @param minMax
  309.      */
  310.     protected void findMinMax(MarvinImage imageIn, int[] minMax)
  311.     {
  312.         for(int l_currentX = 0; l_currentX < imageIn.getWidth(); l_currentX++)
  313.         {
  314.             for(int l_currentY = 0; l_currentY < imageIn.getHeight(); l_currentY++)
  315.             {
  316.                 int l_currentRed = imageIn.getIntComponent0(l_currentX, l_currentY);
  317.                 int l_currentGreen = imageIn.getIntComponent1(l_currentX, l_currentY);
  318.                 int l_currentBlue = imageIn.getIntComponent2(l_currentX, l_currentY);
  319.                 //check red
  320.                 if(l_currentRed < minMax[0])
  321.                 {
  322.                     minMax[0] = l_currentRed;
  323.                 }
  324.                 if(l_currentRed > minMax[1])
  325.                 {
  326.                     minMax[1] = l_currentRed;
  327.                 }
  328.                 //check green
  329.                 if(l_currentGreen < minMax[0])
  330.                 {
  331.                     minMax[0] = l_currentGreen;
  332.                 }
  333.                 if(l_currentGreen > minMax[1])
  334.                 {
  335.                     minMax[1] = l_currentGreen;
  336.                 }
  337.                 //check blue
  338.                 if(l_currentBlue < minMax[0])
  339.                 {
  340.                     minMax[0] = l_currentBlue;
  341.                 }
  342.                 if(l_currentBlue > minMax[1])
  343.                 {
  344.                     minMax[1] = l_currentBlue;
  345.                 }
  346.             }
  347.         }
  348.     }
  349.     /**
  350.      * The borders may not be continuous so this method examines the pixels
  351.      * around the current pixel of interest. If there is no border pixel neighbouring
  352.      * it, it searches within a 16 connected connected neighbourhood to find a bordering pixel
  353.      * @param l_borderedRegions
  354.      */
  355.    
  356. /**
  357.  * Get the angle between two, two dimensional vectors
  358.  * @param a_Vector1, a_Vector2 - the vectors who's angle of difference needs to be calculated
  359.  */
  360.     protected double calculateVectorAngle(int[] vector1, int[] vector2)
  361.     {
  362.         if (vector1.length != vector2.length)
  363.         {
  364.             return 0;
  365.         }
  366.         double l_magVector1 = findMagnitude(vector1);
  367.         double l_magVector2 = findMagnitude(vector2);
  368.         double l_dotProduct = dotProduct(vector1, vector2);
  369.        
  370.         return l_dotProduct / (l_magVector1 * l_magVector2);
  371.  
  372.     }
  373.     /**
  374.      * Find the magnitude of a 2 element 'vector'
  375.      * @param vector
  376.      * @return
  377.      */
  378.     protected double findMagnitude(int[] vector)  
  379.     {
  380.         if (vector.length != 2)
  381.         {
  382.             return 0;
  383.         }
  384.         else
  385.         {
  386.             return Math.sqrt(vector[0]*vector[0] + vector[1]*vector[1] );
  387.         }
  388.     }
  389.    
  390.     //Static Method that returns the Dot Product of two Vectors
  391.     private double dotProduct(int[] vector1, int[] vector2)
  392.     {
  393.         if (vector1.length != vector2.length && vector1.length != 2)
  394.         {
  395.             return 0;
  396.         }
  397.         return vector1[0]*vector2[0] + vector1[1]*vector2[1];
  398.     }
  399.    
  400.    
  401.  
  402.    
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement