一个很有趣的东西,人物图像过滤,模拟绿坝


过滤的不是很好,把老毛的脸都给过滤了,然后黑妹由于太黑,即使裸着上半身,都判断不出来。。。无法过滤。
看来针对黑人还得是另外一套算法,囧。
部分代码:
public class FleshDetector {
/**
* 截获脸部(肉色)特征区域
*
* @param src
* @return
*/
public static PallDetection detectFaces(final BufferedImage src,
final int type) {
// 转为黑白两色图
BufferedImage bin = getFleshBinaryImage(src);
// 扩大白色区域
BufferedImage dil = Alteration.dilate(bin, type);
// 取得肌肤颜色
PallDetection bd = detectWhite(dil);
return bd;
}
/**
* 截获白色特征区域
*
* @param src
* @return
*/
public static PallDetection detectWhite(final BufferedImage src) {
// 设定默认矫正值
Pall.MAX_NBLINE = 4000;
PallDetection.MAX_NUMBER = 1000;
PallDetection pall = new PallDetection(src.getWidth(), src.getHeight());
pall.setPosDiscrimination(false);
pall.setThreshold(0.38f);
int[] pixels = src.getRGB(0, 0, src.getWidth(), src.getHeight(), null,
0, src.getWidth());
// 利用象素点获得适当反色遮挡位置
pall.computePalls(pixels);
return pall;
}
/**
* 返回黑白二色图
*
* @param src
* @return
*/
public static BufferedImage getFleshBinaryImage(final BufferedImage src) {
BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(),
BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < src.getWidth(); x++) {
for (int y = 0; y < src.getHeight(); y++) {
Color c = new Color(src.getRGB(x, y));
if (isFlesh(c)) {
dst.setRGB(x, y, Color.WHITE.getRGB());
} else {
dst.setRGB(x, y, Color.BLACK.getRGB());
}
}
}
return dst;
}
/**
* 检查是否为肉色
*
* @param c
* @return
*/
private static boolean isFlesh(final Color c) {
if ((c.getRed() > 230) && (c.getGreen() > 170)&&(c.getBlue() > 190)) {
return false;
}
LDialyzer yuv = LDialyzer.getYuv(c.getRed(), c.getGreen(), c.getBlue());
return ((c.getRed() > 40) && (c.getGreen() > 40) && (yuv.y + 16 > 145)
&& (yuv.v + 128 < 173) && (yuv.v + 128 > 133)
&& (yuv.u + 128 < 127) && (yuv.u + 128 > 77));
}
}




