本文主要是介绍android端基于openCV给图片打马赛克,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近一直在捣腾openCV,看到别人朋友圈总喜欢给图片打一点马赛克,充满神秘感。准备用openCV来实现打码,其实足够模糊就能实现马赛克效果。查看API发现ImgProc模块提供四种模糊方法:高斯模糊、均值模糊、中值模糊、双边滤波。在这里主要比较高斯模糊、均值模糊以及自定义覆盖层的实现效果。
首先,各种初始化:openCV库、模糊线程、人脸检测器。
/*** 初始化openCV*/private void initOpenCV(){boolean result = OpenCVLoader.initDebug();if(result){Log.i(TAG, "initOpenCV success...");}else {Log.e(TAG, "initOpenCV fail...");}}/*** 初始化mat*/private void initMat(){mat = new Mat();bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.beauty);Utils.bitmapToMat(bitmap, mat);}/*** 初始化线程*/private void initThread(){blurThread = new BlurThread(mHandler, blurMat);blurThread.start();blurThread.setRunning(true);}/*** 初始化人脸检测器* @param context context*/public void initDetector(Context context){mFaceRect = new MatOfRect();mFaceDetector = new ObjectDetector(context, R.raw.lbpcascade_frontalface,6, 0.2F, 0.2F,new Scalar(0, 0, 255, 0));}
使用人脸检测器去检测人脸,得到待打码区域:
/*** 检测人脸*/private void detectFace(){Mat mGray = new Mat();Imgproc.cvtColor(mat, mGray, Imgproc.COLOR_RGBA2GRAY);Rect[] faceRect = mFaceDetector.detectObject(mGray, mFaceRect);if(faceRect != null && faceRect.length > 0){Rect face = faceRect[0];//矩形标识Imgproc.rectangle(mat, face.tl(), face.br(),mFaceDetector.getRectColor(), 3);//待打码区域blurMat = mat.submat((int) face.tl().y, (int) face.br().y, (int) face.tl().x, (int) face.br().x);}mGray.release();mHandler.obtainMessage(100).sendToTarget();}
1、高斯模糊
高斯模糊是采用高斯核函数,创建高斯滤波器,遍历待滤波区域:每一个像素与给定像素矩阵模板相乘,求线性加权平均点。
//高斯模糊private void gaussianBlur(int width, int height,double sigmaX){Imgproc.GaussianBlur(blurMat, blurMat, new Size(width, height), sigmaX);}
均值模糊是对给定像素矩阵取平均值,算法比高斯模糊简单点,耗时相对短一点。
//均值模糊private void normalBlur(int width, int height){Imgproc.blur(blurMat, blurMat, new Size(width, height));}
3、深度模糊(自定义覆盖层)
自定义模糊算法相对简单:遍历待处理区域,重新赋值为指定颜色值。
//自定义模糊private void customBlur(int color){//ARGB转成RGBApixelColor[2] = color & 0xFF;//BluepixelColor[1] = (color >> 8) & 0xFF;//GreenpixelColor[0] = (color >> 16) & 0xFF;//RedpixelColor[3] = (color >> 24) & 0xFF;//Alphafor (int x=0; x<blurMat.rows(); x++){for (int y=0; y<blurMat.cols(); y++){blurMat.put(x, y, pixelColor);}}}
如果需要在预览时,可采用均值模糊进行实时打码(高斯模糊耗时比较长,引起预览卡顿):
@Overridepublic Mat onCameraFrame(CvCameraViewFrame inputFrame) {mRgba = inputFrame.rgba();mGray = inputFrame.gray();// 检测人脸Rect[] faceRect = mFaceDetector.detectObject(mGray, mFaceRect);if(faceRect != null && faceRect.length > 0){Rect face = faceRect[0];//采用均值模糊进行打码Mat blurMat = mRgba.submat((int) face.tl().y, (int) face.br().y, (int) face.tl().x, (int) face.br().x);Imgproc.blur(blurMat, blurMat, new Size(99, 99));}return mRgba;}
好了,关于采用高斯模糊、均值模糊以及自定义覆盖层给图片打码分析完毕。如果各位有什么问题或建议,欢迎交流,如果觉得本篇文章对您有所帮助,麻烦点个赞。。。
这篇关于android端基于openCV给图片打马赛克的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!