Last active
August 29, 2015 14:06
-
-
Save arthurkushman/aab678f851bae634b7d9 to your computer and use it in GitHub Desktop.
NudeFilter class filters nudity/porn content 85% garanty - 15% is positive/negative (weakly tested)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.anumbers.core; | |
import java.awt.image.BufferedImage; | |
import java.io.File; | |
import java.io.IOException; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import javax.imageio.ImageIO; | |
/** | |
* | |
* @author Arthur Kushman | |
*/ | |
public class NudeFilter { | |
private final int rangeRGBMin = 7944996, // #79 3B 24 | |
rangeRGBMax = 16696767; // #FE C5 BF | |
private static final int PIXELS_MIN_FACTOR = 3, PIXELS_MAX_FACTOR = 9; | |
private int[] rgbMin, rgbMax; | |
public NudeFilter() { | |
// U can play with RGB as long as U need =) | |
rgbMin = new int[3]; | |
// rgbMin[0] = 90; // red - original | |
// rgbMin[1] = 90; // green - original | |
// rgbMin[2] = 80; // blue - original | |
rgbMin[0] = 100; // red | |
rgbMin[1] = 100; // green | |
rgbMin[2] = 90; // blue | |
rgbMax = new int[3]; | |
// rgbMax[0] = 210; // red - original | |
// rgbMax[1] = 165; // green - original | |
// rgbMax[2] = 175; // blue - original | |
rgbMax[0] = 245; // red | |
rgbMax[1] = 180; // green | |
rgbMax[2] = 175; // blue | |
} | |
// main method needed only if U test it locally - it is quite convinient | |
public static void main(String[] args) throws IOException { | |
String path = "C:\\pics\\"; | |
File dir = new File(path); | |
File[] files = dir.listFiles(); | |
String[] imgs = new String[files.length]; | |
int c = 0; | |
for (File f : dir.listFiles()) { | |
imgs[c] = path+f.getName(); | |
c++; | |
} | |
NudeFilter filter = new NudeFilter(); | |
for (String img : imgs) { | |
int points = filter.countPoints(img); | |
System.out.print(points+" - "+img); | |
if (points >= 65) { | |
System.out.print(" Banned..."); | |
} | |
System.out.println(); | |
} | |
} | |
public int countPoints(String sourceImg) throws IOException { | |
BufferedImage bi = ImageIO.read(new File(sourceImg)); | |
int width = bi.getWidth(); | |
int height = bi.getHeight(); | |
int[] xPoints = new int[6]; | |
int[] yPoints = new int[6]; | |
int[] zPoints = new int[4]; | |
xPoints[0] = width / 8; | |
xPoints[1] = width / 4; | |
xPoints[2] = (width / 8 + width / 4); | |
xPoints[3] = width + (width / 8 + width / 4); | |
xPoints[4] = width - (width / 4); | |
xPoints[5] = width - (width / 8); | |
yPoints[0] = height / 8; | |
yPoints[1] = height / 4; | |
yPoints[2] = (height / 8 + height / 4); | |
yPoints[3] = height + (height / 8 + height / 4); | |
yPoints[4] = height - (height / 4); | |
yPoints[5] = height - (height / 8); | |
zPoints[0] = xPoints[2]/2; | |
zPoints[1] = yPoints[1]; | |
zPoints[2] = xPoints[5]; | |
zPoints[3] = height; | |
Map<Integer, Map<Integer, Integer>> pixelsCollection = new HashMap<>(); | |
// collect all the x, y coord by color | |
for (int y = 0; y < height; y++) { | |
for (int x = 0; x < width; x++) { | |
int rgbPixel = bi.getRGB(x, y); | |
int red = (rgbPixel >> 16) & 0xff; | |
int green = (rgbPixel >> 8) & 0xff; | |
int blue = rgbPixel & 0xff; | |
// fit colors | |
if (green >= rgbMin[1] && green <= rgbMax[1] | |
&& blue >= rgbMin[2] && blue <= rgbMax[2] | |
&& red >= rgbMin[0] && red <= rgbMax[0]) { | |
// offset from all sides | |
if (x >= zPoints[0] && y >= zPoints[1] | |
&& x <= zPoints[2] && y <= zPoints[3]) { | |
if (pixelsCollection.containsKey(rgbPixel)) { // add coords to existing color | |
pixelsCollection.get(rgbPixel).put(x, y); | |
} else { // add new color with 1-st coords | |
Map<Integer, Integer> coords = new HashMap<>(); | |
coords.put(x, y); | |
pixelsCollection.put(rgbPixel, coords); | |
} | |
} | |
} | |
} | |
} | |
int pixelsMax = width/PIXELS_MAX_FACTOR; | |
int pixelsMin = pixelsMax/PIXELS_MIN_FACTOR; | |
double points = incrementPoint(pixelsCollection, pixelsMin, pixelsMax); | |
return countPointsRatioToSize(points, width, height); | |
} | |
private double incrementPoint(Map<Integer, | |
Map<Integer, Integer>> pixelsCollection, int pixelsMin, int pixelsMax) { | |
double points = 0; | |
// detect shapes by color - leave small/x-large areas ex.: 8>x<32 - nipples | |
for (Entry<Integer, Map<Integer, Integer>> color : pixelsCollection.entrySet()) { | |
Map<Integer, Integer> xy = color.getValue(); | |
int sizeOfShape = xy.size(); | |
if (sizeOfShape > pixelsMin && sizeOfShape < pixelsMax) { | |
if (sizeOfShape<=pixelsMax/2 && sizeOfShape>=pixelsMax/3) { // golden avg | |
points+=0.4; | |
} else if (sizeOfShape<pixelsMax/3 && sizeOfShape>pixelsMin) { // min shape | |
points+=0.3; | |
} else if (sizeOfShape>pixelsMax/2 && sizeOfShape<pixelsMax) { // max shape | |
points+=0.2; | |
} | |
} | |
} | |
return points; | |
} | |
private int countPointsRatioToSize(double points, int width, int height) { | |
int p = (int) (points * 100000) / (width * height) * 2; | |
if (p>100) p=100; | |
return p; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
3 step porn filter: