OPENCV image processing for background blur on mobile phones

Source: Internet
Author: User
Tags gety scalar

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.