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

Java版人物图像过滤。直接上图,太有喜感了。
2011-06-26_023914.png2011-06-26_023836.png
过滤的不是很好,把老毛的脸都给过滤了,然后黑妹由于太黑,即使裸着上半身,都判断不出来。。。无法过滤。
看来针对黑人还得是另外一套算法,囧。
部分代码:
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));
    }
}

通过代码来实现网页截图

    有时候,我们需要用代码来网页截图,其实要实现这个功能,无非就是要么实现一个仿真浏览器,要么调用系统浏览器,唯有此而发而已。这里还是用的最常见的第二种,第一种难度很大。在网上找了一个库,很好用,记录下来,仅供有需要的同学参考。
下载地址:http://code.google.com/p/greenvm/downloads/detail?name=Screenshot.7z&can=2&q=
    Screenshot就是这样的一个程序,这是一个以DJNativeSwing于系统后台调用浏览器,产生指定网页地址截图的示例。
部分核心代码如下:
public Main(final String url, final int maxWidth, final int maxHeight) {
        super(new BorderLayout());
        JPanel webBrowserPanel = new JPanel(new BorderLayout());
        final String fileName = System.currentTimeMillis() + ".jpg";
        final JWebBrowser webBrowser = new JWebBrowser(null);
        webBrowser.setBarsVisible(false);
        webBrowser.navigate(url);
        webBrowserPanel.add(webBrowser, BorderLayout.CENTER);
        add(webBrowserPanel, BorderLayout.CENTER);

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 4, 4));

        webBrowser.addWebBrowserListener(new WebBrowserAdapter() {

            // 监听加载进度
            public void loadingProgressChanged(WebBrowserEvent e) {
                // 当加载完毕时
                if (e.getWebBrowser().getLoadingProgress() == 100) {
                    String result = (String) webBrowser
                            .executeJavascriptWithResult(jsDimension.toString());
                    int index = result == null ? -1 : result.indexOf(":");
                    NativeComponent nativeComponent = webBrowser
                            .getNativeComponent();
                    Dimension originalSize = nativeComponent.getSize();
                    Dimension imageSize = new Dimension(Integer.parseInt(result
                            .substring(0, index)), Integer.parseInt(result
                            .substring(index + 1)));
                    imageSize.width = Math.max(originalSize.width,
                            imageSize.width + 50);
                    imageSize.height = Math.max(originalSize.height,
                            imageSize.height + 50);
                    nativeComponent.setSize(imageSize);
                    BufferedImage image = new BufferedImage(imageSize.width,
                            imageSize.height, BufferedImage.TYPE_INT_RGB);
                    nativeComponent.paintComponent(image);
                    nativeComponent.setSize(originalSize);
                    // 当网页超出目标大小时
                    if (imageSize.width > maxWidth
                            || imageSize.height > maxHeight) {
                        //截图部分图形
                        image = image.getSubimage(0, 0, maxWidth, maxHeight);
                        /*此部分为使用缩略图
                        int width = image.getWidth(), height = image
                            .getHeight();
                         AffineTransform tx = new AffineTransform();
                        tx.scale((double) maxWidth / width, (double) maxHeight
                                / height);
                        AffineTransformOp op = new AffineTransformOp(tx,
                                AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
                        //缩小
                        image = op.filter(image, null);*/
                    }
                    try {
                        // 输出图像
                        ImageIO.write(image, "jpg", new File(fileName));
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    // 退出操作
                    System.exit(0);
                }
            }
        }

        );
        add(panel, BorderLayout.SOUTH);

    }
下面是我截的优酷的图,效果还是比较满意的。
1309025157547.jpg

Nailgun:通过省略JVM启动时间提高命令行Java程序运行速度

【Nailgun】

http://www.martiansoftware.com/nailgun/。对命令行下运行的java程序来说(已经编译了的java代码生成了.class文件或.jar包,需要在命令行下执行java class_name或者java -jar jar_name.jar来运行),在执行了java之后需要启动JVM。某些情况下JVM的启动比较耗时。Nailgun用于解决该问题:它包含一个server(使用Java编写),提供了正在运行的JVM;然后提供了一个client: ng(使用C编写),这样运行ng class_name可以将该class文件及参数传递到server执行并将结果返回。这样可以省去每次都要启动JVM。

【Nailgun的安装和使用】

安装:

下载Nailgun(http://sourceforge.net/projects/nailgun/),并解压缩可以看到:nailgun-0.7.1.jar(它为ng server的jar),ng.exe(它为Windows下的ng client,也可以在Linux下运行make编译得到Linux下的ng client)。

将/nailgun-path/nailgun-0.7.1.jar添加到系统的ClassPath中。

使用:

  • 将要运行的java程序的class添加到系统的ClassPath中

例如可以使用nailgun自带的实例程序,将/nailgun-path/nailgun-example-0.7.1.jar添加到系统的ClassPath中。

  • 运行ng server:

运行命令:java -server com.martiansoftware.nailgun.NGServer。启动ng server,默认运行在端口2113。如果希望侦听指定的地址和端口可以在如上命令之后添加127.0.0.1:1984

  • 运行ng client执行java代码:

假如要执行的java程序为com.martiansoftware.nailgun.examples.HelloWorld,则运行如下命令:

ng com.martiansoftware.nailgun.examples.HelloWorld

如果需要指定ng server的ip或port,可以使用ng --nailgun-server 127.0.0.1 --nailgun-port 1984 class_name

  • 注:运行ng ng-stop可以关闭ng server。


使用nailgun方式运行Apache Tika

  • 将tika的jar添加到classpath中:

添加/tika-path/tika-app/target/tika-app-0.9.jar到系统的ClassPath中。然后运行ng org.apache.tika.cli.TikaCLI -t test.doc可以对test.doc文件进行抽取。

【Nailgun在Linux上】

  • 安装

下载nailgun,然后在nailgun目录下运行make编译得到ng client端:ng。然后mv -f nailgun-0.7.1 /usr/local

  • 添加CLASSPATH

export CLASSPATH=$CLASSPATH:/usr/local/nailgun-0.7.1/nailgun-0.7.1.jar:/usr/local/nailgun-0.7.1/nailgun-examples-0.7.1.jar:/usr/local/apache-tika-0.9/tika-app/target/tika-app-0.9.jar

  • 运行ng server

java -server com.martiansoftware.nailgun.NGServer

  • 运行ng测试程序

    java com.martiansoftware.nailgun.examples.HelloWorld/usr/local/nailgun-0.7.1/ng com.martiansoftware.nailgun.examples.HelloWorld
  • 运行Apache Tika:

    time java org.apache.tika.cli.TikaCLI -t ~/test/tika/test.docreal    0m2.326suser    0m3.570ssys     0m0.180stime /usr/local/nailgun-0.7.1/ng org.apache.tika.cli.TikaCLI -t ~/test/tika/test.docreal    0m0.748suser    0m0.000ssys     0m0.010s

今夜没有月光-历数SEO的罪恶

月光博客,和郭吉军,管鹏一样风光的人物,坐拥几十万粉丝,被业界称为super SEO,站长代表人物,草根中的精英,是历届站长大会的座上客。我依稀记得去年河南站长大会,好几位重量级SEO在河南中原论剑,其雄哉,其壮哉。
今天它的网站,http://williamlong.info/被黑了。
月光博客,其人尤其擅长炒作,颠倒黑白是非,哗众取宠,投机取巧。抓住一个事件,就大写文章。将其炒作,赚取眼球。
又擅长软文写作,于无形中杀人,杀公司,捧人,捧公司。
我历来鄙视SEO,其原因如下:
(1)肆意左右搜索引擎排名,扰乱正常的网络资源。
(2)到处发表软文,广告,制作网络垃圾,是各大论坛,博客最头疼的垃圾制造者。
(3)高级一点的SEO到处搞培训,收徒弟,组团队,沽名钓誉。制造各类名词,如SEO,SEM,故弄玄虚,只为了卖个好价钱
(4)高级一点的SEO擅长写软文,读起来看似有用,实乃一无是处的非专业文字。
(5)再高级一点的SEO,就是各种网络水军的组织者,可以带队,想要碰谁杀谁,易如反掌。
(6)炒作,扰乱网络秩序。利用博客,微博等大肆炒作,赚取人气,赚取粉丝。其为了增加粉丝,手段无所不用,搞得网络乌烟瘴气。然后利用手中的粉丝资源,控制舆论,搞病毒式营销。典型的如臭名昭著的QQ微博的“互听大队”,“V5推推”。
(7)败坏道德风气,形成一切为钱看的风气,一切都是为了钱。博文是为了赚钱,炒作是为了赚钱,粉丝数也是为了赚钱。
2011-06-20_140433.jpg
转发黑客全文:
---------------------------------------------------------------------------------------
致尊敬的龙威廉

你是明事理的孩子
哥不是没有你这个新浪博客的密码
哥更不是没有你info 
ZBlog 的密码
哥只是觉得你我不是一路人

作为一个对黑客技术追求之极的人,说实在话根本不想对你的及你自认很有成绩的那些垃圾博客网站发起攻击,我想一个真正的黑客有自己的理想和追求,他们也许被大众误解,被大众唾骂,也许大家了解的并不是他们正真的世界,但是这一切都无法阻挡我们对技术的热爱。而你也有你的生活和世界,作为一个掌握了20几万粉丝及日访问量近万的博客主,你应该善用你辛苦累计的这一切,为大家带来的应该是欢乐和知识,尽可能站在第三方客观公正的去评价一些事情。
 
     而龙威廉先生说真的本来我并不打算关注你,作为生活中底层的一个平头百姓无非能做的就是利用自己辛苦累计的流量去帮人用微薄发一些软文来挣取看来实在是可笑的一点回报,但是龙威廉先生你错误的选择了炒作黑客事件,作为增加自己流量的资本,原本对你的评价我只是报以一笑了之,大度和宽容告诉我你只是个外行,也许评价不太中肯,也许带有炒作的嫌疑,但毕竟你只是一个外行,我用宽容和笑脸迎接你中肯的评价。但是你一而再再而三的污蔑与诽谤所有黑客,这是我不想看到你错误的引导大众。
    
 
       请你千万记住不要以为有了20万粉丝就掌握了这个世界的话语权,黑客一般都很低调,黑客比你有的是话语权,黑客比你掌握的高深电脑技术比你能想到要多的多,你不激怒他们一般他们是不会对你一个平头百姓发起攻击,黑客都喜欢在黑夜里活跃不是因为见不得光,因为他们不像你一样希望每个都知道他们在做什么。
     
        写在最后 不是不能篡改你的博客及你所有的微薄,我暂时接管你所有的账号,包括你的用于购买网站服务的信用卡账号,及你所有的一切,只是我暂时还没有对这些数据进行处理,如果你仍然执迷不悟你的世界将不在有月光。
 
       抛掉这些浮躁,每天几个小时的更新,几十个账号的互相自我炒作,你不觉得累吗,从新开始生活,也许我帮你从你的世界里拯救了出来。
----------------------------------------------------------------------------------------
善哉。

转:趣题:老鼠与毒药问题的推广

今天的趣题来源于 IBM Ponder This 三月份的谜题

    大家应该都听说过这个老题目:有 1000 个一模一样的瓶子,其中有 999 瓶是普通的水,有一瓶是毒药。任何喝下毒药的生物都会在一星期之后死亡。现在,你只有 10 只小白鼠和一星期的时间,如何检验出哪个瓶子里有毒药?

    这个问题的答案也堪称经典:把瓶子从 0 到 999 依次编号,然后全部转换为 10 位二进制数。让第一只老鼠喝掉所有二进制数右起第一位是 1 的瓶子,让第二只老鼠喝掉所有二进制数右起第二位是 1 的瓶子,等等。一星期后,如果第一只老鼠死了,就知道毒药瓶子的二进制编号中,右起第一位是 1 ;如果第二只老鼠没死,就知道毒药瓶子的二进制编号中,右起第二位是 0 ⋯⋯每只老鼠的死活都能确定出 10 位二进制数的其中一位,由此便可知道毒药瓶子的编号了。

    现在,有意思的问题来了:如果你有两个星期的时间(换句话说你可以做两轮实验),为了从 1000 个瓶子中找出毒药,你最少需要几只老鼠?注意,在第一轮实验中死掉的老鼠,就无法继续参与第二次实验了。

  
    答案:7 只老鼠就足够了。事实上,7 只老鼠足以从 37 = 2187 个瓶子中找出毒药来。首先,把所有瓶子从 0 到 2186 编号,然后全部转换为 7 位三进制数。现在,让第一只老鼠喝掉所有三进制数右起第一位是 2 的瓶子,让第二只老鼠喝掉所有三进制数右起第二位是 2 的瓶子,等等。一星期之后,如果第一只老鼠死了,就知道毒药瓶子的三进制编号中,右起第一位是 2 ;如果第二只老鼠没死,就知道毒药瓶子的三进制编号中,右起第二位不是 2,只可能是 0 或者 1 ⋯⋯也就是说,每只死掉的老鼠都用自己的生命确定出了,三进制编号中自己负责的那一位是 2 ;但每只活着的老鼠都只能确定,它所负责的那一位不是 2 。于是,问题就归约到了只剩一个星期时的情况。在第二轮实验里,让每只活着的老鼠继续自己未完成的任务,喝掉它负责的那一位是 1 的所有瓶子。再过一星期,毒药瓶子的三进制编号便能全部揭晓了。

    类似地,我们可以证明, n 只小白鼠 t 周的时间可以从 (t+1)n 个瓶子中检验出毒药来。

refer:http://www.matrix67.com/blog/archives/4361

插件,扩展和hack的区别

昨晚在检查自己写的文档时,看到“插件”这个词,猛然想起这里面还有些许文章,自己的描述不够严谨。
插件(plugin),看这个名词就知道,插,从外面插到里面来;
扩展(extension),扩,是从里面扩到外面去。
二者是完全不同的概念,一个是从外向里,一个是从里向外。
插件呢,就是外来物,辅助已经存在的软件更好的工作;
而扩展,是衍生物,从软件自身衍生出来,用来更好的增强软件的功能。
二者所起的作用是一样的,而概念则是彻底相反的。然而很多人却搞不清这二者的概念,经常混淆。
在firefox中就经常涉及这两个概念。firefox一向把这两个概念分的很清,如下图:
ex_c.png
通常我们所下载的firefox的功能增强组件都是扩展,它们是基于firefox所提供的专用脚本制作的,但也不限于此。
而flash播放器等则属于插件,是adobe公司开发的用于增强火狐功能的组件。扩展本身可以包含一个或者多个插件,但是插件不包 含扩展。
有时我们还会接触到hack这个概念,hack一般指对源代码做的小改动,使软件功能增强和变化,hack和原有系统的耦合度比较高。把一些耦合度高的,不是很大的改动就称之为hack了。或者hack也指某些语法糖类的东西,如CSS hack.

转:简单的验证码识别技术,学习笔记

Screenshot-C12-Aurora.pngScreenshot-C12-Aurora.png

原理

对于简单的验证码,使用的原理也相当的简单。
现在有两个长度一致的二进制的数字,1110111011101和1010111011100,比较他们的相似度可以使用XOR运算!

1110111011101 XOR 1010111011100 = 0100000000001

结果中,1的数目越小,相似度越高。现在比较两张单色的图片,也可以使用这样的方法。这两张图必须是规格相同的,
compare.png
把两张单色的图片进行Xor,结果残留下来的白点越小,表示相似度越高!!!
for y in range(h):
    for x in range(w):
        im2.putpixel((x,y), im1.getpixel((x,y)) ^ im2.getpixel((x,y)))
im2.show()

阅读剩余部分...

axis2的qname not fond for the package问题的解决

在一个项目组,需要用到webservice,虽然现有的webservice组件为axis2,比较古老了,不过夜没办法,是个老项目。
不过AXIS2还算好用,就是还是复杂了一些。
在部署webservice的时候,我们可以通过这样的方法来在浏览器中测试
http://aiyooyoo.com/service/getStudentService/listStudent?unit=5
getStudentService为服务名,listStudent为方法名,而unit=5自然就是参数了。
在测试的时候,发现如果是基本类型的话,就能正常运行,但我这次需要的是一个list<student>的集合类型。
在浏览器中报错如下:
qname not fond for the package com.aiyooyoo.com.dbutil
很明显,我的代码里是有这个包的,刚开始怀疑是这种方法有局限性造成的,于是用代码写了个客户端进行测试,问题依然如此。现在就确实确实是返回类型的问题了,如果返回int等基本类型就正常。
查了下资料,发现AXIS2不支持集合,而axis1反倒支持,axis2需要用对象数组的方式来处理,为了已有类的通用性,想到了我可以再服务器端先把集合转换为字符串,再在客户端把字符串转换为集合,不就解决了吗。
于是,主要代码如下:
//集合转字符串
List list<Student>=new arrayList<Student>();
....
return list.toString();
//字符串转集合
JSONArray jsonArray = JSONArray.fromObject(jsonString);
  JSONObject jsonObject;
  Object pojoValue;
  List list = new ArrayList();
  for (int i = 0; i < jsonArray.size(); i++) {
   jsonObject = jsonArray.getJSONObject(i);
   pojoValue = JSONObject.toBean(jsonObject, Student.class);
   list.add(pojoValue);
  }
  return list;

 }

问题解决。记录下,供遇到同类问题的童鞋参考。
    Page :
  1. 1
  2. ...
  3. 10
  4. 11
  5. 12
  6. 13
  7. 14
  8. 15
  9. 16
  10. ...
  11. 40