【Andriod】Andriod-Opencv 实现一些简单的滤镜功能

     最近比较忙,很久没有更新博客了。

     关于在android 下配置opencv的文章可以去看这一片博客:Android Studio中使用OpenCV Android SDK

    这篇文章所说的配置可以直接用android写opencv,而不需要采用内嵌C++的办法。(话说我本来想用Dlib来识别人脸的,却在内嵌c++上吃了不少苦头。)

    下面就简单介绍下几种滤镜的实现以及效果图:

   (1)灰度化:这个比较简单,主要就一行代码搞定。

//灰度化方法
    Bitmap RGB2Gray(Bitmap photo) {
        Mat RGBMat = new Mat();
        Bitmap grayBitmap = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.RGB_565);
        Utils.bitmapToMat(photo, RGBMat);//convert original bitmap to Mat, R G B.
        Imgproc.cvtColor(RGBMat, RGBMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat
        Utils.matToBitmap(RGBMat, grayBitmap);
        return grayBitmap;
    }   

   【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第1张图片

(2)二值化:二值化主要考虑到一个阈值效果,这个我没有设置,直接就默认中值了,以后也许会加一个控制条啥的。

//二值化滤镜
    Bitmap theshold(Bitmap photo){
        Mat mat = new Mat();
        Bitmap thes = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        Utils.bitmapToMat(photo, mat);
        Imgproc.cvtColor(mat,mat,Imgproc.COLOR_RGB2GRAY);
        Core.bitwise_not(mat,mat);
        Imgproc.threshold(mat,mat,100,255,Imgproc.THRESH_BINARY_INV);
        Utils.matToBitmap(mat,thes);
        return thes;
    }

【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第2张图片


(3)轮廓:轮廓说到底就是一个边缘检测。

//轮廓
    Bitmap Lunkuo(Bitmap photo){
        Mat mat = new Mat();
        Mat Cmat = new Mat();
        Mat Bmat = new Mat();
        Bitmap cartton = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        Utils.bitmapToMat(photo, mat);
        Imgproc.Canny(mat,Cmat,50,100);
        Core.bitwise_not(Cmat,Cmat);
        Utils.matToBitmap(Cmat, cartton);
        return cartton;
    }
【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第3张图片

(4)素描:

//素描滤镜
    Bitmap SuMiao(Bitmap photo){
        Mat SM = new Mat();
        Mat SM1 = new Mat();
        Bitmap sumiaoMap = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        Bitmap SMB = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        Bitmap SMB1 = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        Utils.bitmapToMat(photo, SM);
        //灰度化
        Imgproc.cvtColor(SM, SM, Imgproc.COLOR_RGB2GRAY);
        //颜色取反
        Core.bitwise_not(SM,SM1);
        //高斯模糊
        Imgproc.GaussianBlur(SM1,SM1,new Size(13,13),0,0);
        Utils.matToBitmap(SM, SMB);
        Utils.matToBitmap(SM1, SMB1);
        for(int i = 0;i

【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第4张图片


(5)接下来是怀旧色。这个要对RGB算式相乘

//怀旧色滤镜
    Bitmap HuaiJiu(Bitmap photo){
        Bitmap huaijiu = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        for(int i = 0;i 255 ? 255 : AR;
                AG = AG > 255 ? 255 : AG;
                AB = AB > 255 ? 255 : AB;
                huaijiu.setPixel(i,j,Color.rgb(AR,AG,AB));
            }
        }
        return huaijiu;
    }

【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第5张图片

(6)连环画:同样是对RGB色彩操作

Bitmap LianHuanHua(Bitmap photo){
        Bitmap lianhuanhua = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        for(int i = 0;i 255 ? 255 : AR;
                AG = AG > 255 ? 255 : AG;
                AB = AB > 255 ? 255 : AB;
                lianhuanhua.setPixel(i,j,Color.rgb(AR,AG,AB));
            }
        }
        return lianhuanhua;
    }

【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第6张图片

(7)熔铸以及冰冻:同上:

//熔铸滤镜
    Bitmap RongZhu(Bitmap photo){
        Bitmap rongzhu  = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        for(int i = 0;i 255 ? 255 : AR;
                AG = AG > 255 ? 255 : AG;
                AB = AB > 255 ? 255 : AB;
                rongzhu.setPixel(i,j,Color.rgb(AR,AG,AB));
            }
        }
        return rongzhu;
    }

    //冰冻滤镜
    Bitmap BingDong(Bitmap photo){
        Bitmap bingdong  = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        for(int i = 0;i 255 ? 255 : AR;
                AG = AG > 255 ? 255 : AG;
                AB = AB > 255 ? 255 : AB;
                bingdong.setPixel(i,j,Color.rgb(AR,AG,AB));
            }
        }
        return bingdong;
    }
【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第7张图片 【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第8张图片

(8)浮雕:

//浮雕滤镜
    Bitmap FuDiao(Bitmap photo){
        Bitmap bingdong  = Bitmap.createBitmap(photo.getWidth(), photo.getHeight(), Bitmap.Config.ARGB_8888);
        for(int i = 1;i 255 ? 255 : AR;
                AG = AG > 255 ? 255 : AG;
                AB = AB > 255 ? 255 : AB;
                bingdong.setPixel(i,j,Color.rgb(AR,AG,AB));
            }
        }
        return bingdong;
    }
【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第9张图片

(9)此外还做了一个图像人脸识别。

【Andriod】Andriod-Opencv 实现一些简单的滤镜功能_第10张图片


        总之效果还可以,但是还有不足的地方,比如RGB颜色的计算和素描色的计算,不像Python有Numpy大法可以直接做矩阵运算。试了很多方法,最终我妥协了,用循环计算每一个像素点,这样就导致了图片越大,滤镜加载的效果就越慢,尤其是素描滤镜,简直慢到令人发耻。这与吴恩达教授所说的向量化计算大相径庭,根本不像一个学机器学习的人做出来的0.0。

       不管怎样完工了,顺便搞定了一门课的课程设计,可能以后会对算法部分进行优化吧,再说。

       在这个软件中,还有一个功能是人脸互换,要用到Dlib,但是在android上配置太麻烦了,我室友就做了一个服务器端,将图片上传到电脑上用Python处理。但是这个功能不是我写得,所以就不写在自己的博客里了。

         就这样,下次继续刷leetcode,并将好玩的题目发到博客上。


        完整版的源代码已经传到github

     

    

你可能感兴趣的:(android)