最近比较忙,很久没有更新博客了。
关于在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;
}
(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;
}
(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;
}
(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
(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;
}
(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;
}
(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;
}
(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;
}
(9)此外还做了一个图像人脸识别。
总之效果还可以,但是还有不足的地方,比如RGB颜色的计算和素描色的计算,不像Python有Numpy大法可以直接做矩阵运算。试了很多方法,最终我妥协了,用循环计算每一个像素点,这样就导致了图片越大,滤镜加载的效果就越慢,尤其是素描滤镜,简直慢到令人发耻。这与吴恩达教授所说的向量化计算大相径庭,根本不像一个学机器学习的人做出来的0.0。
不管怎样完工了,顺便搞定了一门课的课程设计,可能以后会对算法部分进行优化吧,再说。
在这个软件中,还有一个功能是人脸互换,要用到Dlib,但是在android上配置太麻烦了,我室友就做了一个服务器端,将图片上传到电脑上用Python处理。但是这个功能不是我写得,所以就不写在自己的博客里了。
就这样,下次继续刷leetcode,并将好玩的题目发到博客上。
完整版的源代码已经传到github