http://m.blog.csdn.net/blogercn/article/details/75004162
1. High-end digital cameras have background blur function. The background blur is to make the depth of field lighter and focus on the subject. General camera The best virtual method is to use macro shooting, if the main scene and the background is far apart, because the optical lens on the non-focal point of the image can not be clearly characterized by the ability to achieve a similar effect of the blur. As follows.
2. It takes four steps to take a camera to blur a picture:
(1) Make the zoom magnification (focal length) as large as possible;
(2) As far away from the background as possible;
(3) The lens and the photograph are as close as possible;
(4) Aperture to meet the needs of the shooting as large as possible, that is, a small f value;
3. For cameras that do not support background blur, you can use the software to achieve a background blur to meet the needs of different customers.
To use software technology for precise background blur, you need to go through three steps:
One is the selected area, the former background separation is realized according to the remote region using the key drawing technique.
Two pairs of backgrounds are processed using fuzzy methods such as Gaussian or mean, as needed
Three post-processing background and foreground merging
Foreground background separation This is achieved using OPENCV and Grabcut technology, project import my own Yi OpenCV aar package, put OpenCV library into Libs folder, modify the app Build.gradle, add Libs:
repositories { mavenlocal () mavencentral () flatdir { dirs ' libs ' }}
And in
Compile Filetree (dir: ' Libs ', include: ' *.aar ')
4. Attach the code:
Import Android.app.activity;import Android.app.progressdialog;import Android.content.intent;import Android.database.cursor;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.graphics.canvas;import Android.graphics.paint;import Android.graphics.rectf;import Android.graphics.drawable.bitmapdrawable;import Android.net.uri;import Android.os.asynctask;import Android.os.bundle;import Android.provider.mediastore;import Android.util.log;import Android.view.Menu;import Android.view.menuitem;import Android.view.motionevent;import Android.view.view;import Android.widget.ImageView; Import Org.opencv.android.baseloadercallback;import Org.opencv.android.loadercallbackinterface;import Org.opencv.android.opencvloader;import Org.opencv.core.core;import Org.opencv.core.cvtype;import Org.opencv.core.mat;import Org.opencv.core.point;import Org.opencv.core.rect;import Org.opencv.core.Scalar;import Org.opencv.core.size;import Org.opencv.imgcodecs.imgcodecs;import ORG.OPENCV.IMgproc. Imgproc;public class Mainactivity extends Activity {static final int request_open_image = 1; String Mcurrentphotopath; Bitmap Mbitmap; ImageView Mimageview; int touchcount = 0; Point TL; Point BR; Boolean targetchose = false; ProgressDialog Dlg; Private Baseloadercallback Mloadercallback = new Baseloadercallback (this) {@Override public void Onmanagerc onnected (int status) {switch (status) {case loadercallbackinterface.success: { LOG.I (TAG, "OpenCV loaded successfully"); } break; Default: {super.onmanagerconnected (status); } break; } } }; @Override public void Onresume () {super.onresume (); if (! Opencvloader.initdebug ()) {LOG.D ("OpenCV", "Internal OpenCV library not found. Using OpenCV Manager for Initialization "); Opencvloader.Initasync (Opencvloader.opencv_version_3_0_0, this, mloadercallback); } else {log.d ("OpenCV", "OpenCV library found inside package. Using it! "); Mloadercallback.onmanagerconnected (loadercallbackinterface.success); }} @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Mimageview = (ImageView) Findviewbyid (R.id.imgdisplay); Dlg = new ProgressDialog (this); TL = new Point (); br = new Point (); if (! Opencvloader.initdebug ()) {//Handle initialization error//}} @Override public boolean Oncreateo Ptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is present. Getmenuinflater (). Inflate (R.menu.menu_main, menu); return true; } int scalefactor = 1; private void Setpic () {int targetw = 720;//mimageview.getwidth ();int targeth = 1128;//mimageview.getheight (); LOG.I (">>>>>", "targetw=" +TARGETW); LOG.I (">>>>>", "targeth=" + targeth); Bitmapfactory.options bmoptions = new Bitmapfactory.options (); Bmoptions.injustdecodebounds = true; Bitmapfactory.decodefile (Mcurrentphotopath, bmoptions); int Photow = Bmoptions.outwidth; int Photoh = Bmoptions.outheight; LOG.I (">>>>>", "photow=" +photow); LOG.I (">>>>>", "photoh=" + Photoh); Scalefactor = Math.max (PHOTOW/TARGETW, Photoh/targeth) +1; LOG.I (">>>>>", "photow/targetw=" + (PHOTOW/TARGETW)); LOG.I (">>>>>", "photoh/targeth=" + (Photoh/targeth)); Bmoptions.injustdecodebounds = false; Bmoptions.insamplesize = Scalefactor; Bmoptions.inpurgeable = true; Mbitmap = Bitmapfactory.decodefile (Mcurrentphotopath, bmoptions); Mimageview.setimagebitmap (Mbitmap); LOG.I (">>>>>", "mbitmap.getwidth () =" +mbitmap.getwidth ()); LOG.I (">>>>>", "mbitmap.getheight () =" + Mbitmap.getheight ()); } @Override protected void Onactivityresult (int requestcode, int resultcode, Intent data) {switch (Requestco DE) {case request_open_image:if (ResultCode = = RESULT_OK) {Uri Imguri = da Ta.getdata (); String[] Filepathcolumn = {MediaStore.Images.Media.DATA}; cursor cursor = getcontentresolver (). Query (Imguri, filepathcolumn, NULL, NULL, NULL); Cursor.movetofirst (); int colindex = Cursor.getcolumnindex (filepathcolumn[0]); Mcurrentphotopath = cursor.getstring (Colindex); Cursor.close (); Setpic (); } break; }} @Override public boolean onoptionsitemselected (menuitem item) {int id = item.getitemid (); Switch (ID) {case r.id.action_open_img:intent getpictureintent = new Intent (intent.action_get_ CONTENT); Getpictureintent.settype ("image/*"); Intent pickpictureintent = new Intent (Intent.action_pick, MediaStore.Images.Media.EXTERNAL_CONTENT_ URI); Intent chooserintent = Intent.createchooser (getpictureintent, "select Image"); Chooserintent.putextra (intent.extra_initial_intents, new intent[] {pickpictureintent }); Startactivityforresult (Chooserintent, request_open_image); return true; Case R.id.action_choose_target:if (Mcurrentphotopath! = null) Targetchose = FALSE; Mimageview.setontouchlistener (New View.ontouchlistener () {@Override Pub Lic boolean OnTouch (View V, MOtionevent event) {int cx = (Mimageview.getwidth ()-mbitmap.getwidth ())/2; int cy = (mimageview.getheight ()-mbitmap.getheight ())/2; if (event.getaction () = = Motionevent.action_down) {if (Touchcount = = 0) { tl.x = Event.getx ();//300;//tl.y = Event.gety ();//300;// touchcount++; } else if (Touchcount = = 1) {br.x = Event.getx ();//1100;// Br.y = Event.gety ();//1200;//paint rectpaint = new paint (); Rectpaint.setargb (255, 255, 0, 0); Rectpaint.setstyle (Paint.Style.STROKE); Rectpaint.setstrokewidth (3); Bitmap tmpbm = Bitmap.createbitmap (MBitmap.getwidth (), Mbitmap.getheight (), Bitmap.Config.RGB_565); Canvas Tmpcanvas = new canvas (TMPBM); Tmpcanvas.drawbitmap (mbitmap, 0, 0, NULL); Tmpcanvas.drawrect (new RECTF (float) tl.x, (float) tl.y, (float) br.x, (float) br.y), Rectpaint); Mimageview.setimagedrawable (New Bitmapdrawable (Getresources (), TMPBM)); Targetchose = true; Touchcount = 0; Mimageview.setontouchlistener (NULL); }} return true; } }); return true; Case R.id.action_cut_image:if (Mcurrentphotopath! = null && targetchose) {New Processimagetask (). Execute(); Targetchose = false; } return true; } return super.onoptionsitemselected (item); } private class Processimagetask extends Asynctask<integer, Integer, integer> {Mat img; Mat foreground; @Override protected void OnPreExecute () {super.onpreexecute (); Dlg.setmessage ("Processing Image ..."); Dlg.setcancelable (FALSE); Dlg.setindeterminate (TRUE); Dlg.show (); } @Override protected integer doinbackground (integer ... params) {//mat img = new Mat (mbitmap.get Height (), Mbitmap.getheight (), CVTYPE.CV_8UC3); Utils.bitmaptomat (Mbitmap, IMG); Long LL = System.currenttimemillis (); LOG.I (">>>>>", "start=" +ll); img = Imgcodecs.imread (mcurrentphotopath); Imgproc.resize (IMG, IMG, New Size (Img.cols ()/scalefactor, img.rows ()/scalefactor)); LOG.I (">>>>>", "11111=" + system.currenttimemillis () + "" + (System.currenttimemillis ()-ll)); Mat background = new Mat (Img.size (), CVTYPE.CV_8UC3, New Scalar (255, 255, 255)); Mat firstmask = new Mat (); Mat Bgmodel = new Mat (); Mat Fgmodel = new Mat (); Mat Mask; Mat Source = new Mat (1, 1, cvtype.cv_8u, new Scalar (IMGPROC.GC_PR_FGD)); Mat DST = new Mat (); Rect rect = new Rect (TL, BR); LOG.I (">>>>>", "22222=" +system.currenttimemillis () + "" + (System.currenttimemillis ()-ll)); Imgproc.grabcut (IMG, Firstmask, rect, Bgmodel, Fgmodel, 1, imgproc.gc_init_with_rect); LOG.I (">>>>>", "33333=" + system.currenttimemillis () + "" + (System.currenttimemillis ()-ll)); Core.compare (Firstmask, source, Firstmask, core.cmp_eq); LOG.I (">>>>>", "44444=" + systeM.currenttimemillis () + "" + (System.currenttimemillis ()-LL); foreground = new Mat (Img.size (), CVTYPE.CV_8UC3, New Scalar (255, 255, 255)); Img.copyto (foreground); Imgproc.blur (foreground, foreground, new Size (20, 20)); LOG.I (">>>>>", "55555=" + system.currenttimemillis () + "" + (System.currenttimemillis ()-ll)); Img.copyto (foreground, firstmask); LOG.I (">>>>>", "66666=" + system.currenttimemillis () + "" + (System.currenttimemillis ()-ll)); Firstmask.release (); Source.release (); Bgmodel.release (); Fgmodel.release (); Imgcodecs.imwrite (Mcurrentphotopath + ". png", foreground); return 0; } @Override protected void OnPostExecute (Integer result) {Super.onpostexecute (result); Bitmap jpg = bitmapfactory. DecodefilE (Mcurrentphotopath + ". png"); Mimageview.setscaletype (ImageView.ScaleType.CENTER_INSIDE); Mimageview.setadjustviewbounds (TRUE); Mimageview.setpadding (2, 2, 2, 2); Mimageview.setimagebitmap (jpg); Mimageview.invalidate (); Dlg.dismiss (); } }}
5. The complete project can be seen on GitHub Https://github.com/blogercn/backgroundblur
6. Use the key function to parse:
A.imgproc.grabcut, keying, keying out the foreground
B.imgproc.blur, fuzzy processing of the background
C.copyto. Background background Merging images
7. The effect is as follows:
OPENCV image processing for background blur on mobile phones