【图像识别】GrabCut的Android实现

原创 2016年08月11日 20:47:58

除了用神经网络,做图像识别最重要的是进行图片特征提取。包括:纹理特征、边缘特征、颜色特征、形状特征等等。每一种特征又有不同的实现方式和效果。比如形状特征可以通过提取边缘的斜率,也可以通过其外接矩形的长宽比。

目前前景提取没有十分完美的算法。一种方法不可能适用于所有复杂的环境。所以采用了人机交互的grabcut算法。通过人为制定一些背景信息,大大增加了前景提取的准确性,为之后的特征提取或降维奠定基础。

本算法基于android平台实现,在自己做之前搜索过很多相关信息后,发现目前该算法并没有在android设备上的实现。

GrabCut的算法实现:http://blog.csdn.net/bless2015/article/details/52063432

思路:
自定义view,通过onDraw方法进行画线和矩形。修改其background图片为待提取的图片。把矩形和线的参数传给grabcut算法来完成。

这其中有图片分辨率问题。更改自定义view背景问题。比较坑的是,app启动后,需要加载OpenCV的类库,这需要几十毫秒的时间,所以在使用OpenCV的数据结构时,要先等一会。所以在初始化时:

    private class ProcessImageTask extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected Integer doInBackground(Integer... arg0) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("准备初始化...");
            mask = new Mat();
            System.out.println("imagePath:"+imagePath);
            image = Imgcodecs.imread(imagePath);
            mask.create(image.size(), CvType.CV_8UC1);
            mask.setTo(new Scalar(0));
            System.out.println("图像读取成功!");
            return 0;
        }
    }

画矩形:

            double min = CompareUtils.min(clickX, scalX);
            double min2 = CompareUtils.min(clickY, scalY);
            canvas.drawRect(rectX, rectY, (int) min, (int) min2, paint);
            System.out.println("onProcess  and  up");
            onProcess = false;

其中CompareUtils.min是进行边界判断,去参数里面的最小值。
之后把矩形数据存入mask矩阵中:

                // rows是行数 height
                double qidianX = 0;
                double qidianY = 0;
                qidianX = CompareUtils.min(clickX, rectX);
                qidianY = CompareUtils.min(clickY, rectY);
                rectangle = new Rect((int) (qidianX/proW), (int) (qidianY/proH),
                        (int) Math.abs((clickX - rectX)/proW), (int) Math.abs((clickY
                                - rectY)/proH));
                mask.submat(rectangle).setTo(new Scalar(GC_PR_FGD));

然后画轮廓,并把轮廓信息存入mask中:

            System.out.println("画轮廓 ");
            canvas.drawLine(startX, startY, clickX, clickY, paint);

            pX = CompareUtils.max(0, clickX/proW);
            pY = CompareUtils.max(0, clickY/proH);
            p = new Point((int) pX, (int) pY);

            Imgproc.circle(mask, p, radius, new Scalar(GC_BGD), thickness);

最后传给grabcut来实现:

    private class ShowTask extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected Integer doInBackground(Integer... arg0) {

            Mat bgdModel = new Mat();
            Mat fgdModel = new Mat();
            System.out.println("初始化bgdModel、fgdModel成功!");
            // source为1,1的矩阵,8位无符号数,初始化为3
            Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3));
            System.out.println("执行GrabCut");
            Imgproc.grabCut(image, mask, rectangle, bgdModel, fgdModel, 3, 1);
            Core.compare(mask, source, mask, Core.CMP_EQ);
            // 产生输出图像
            System.out.println("准备产生输出图像");
            Mat foreground = new Mat(image.size(), CvType.CV_8UC1, new Scalar(
                    0, 0, 0));
            image.copyTo(foreground, mask);
            System.out.println("准备写入结果");
            System.out.println(mask.size());
            Imgcodecs.imwrite(path2, foreground);
            Log.i("pd", "算法完成");
            result = "success";
            return 0;
        }
    }

效果:
grabcut算法效果

版权声明:本文为博主原创文章,未经博主允许不得转载。

OPENCV图像边缘查找与分割技术在android中使用汇总

图像分割技术或者叫抠图技术,是一种根据需要对图像进行截取分离的技术,在一般的图像处理和视频处理中应用十分广泛,是图像查找,图像识别,图像特效的基础。经常被人们使用在相机美颜,自动人脸马赛克,车牌识别,...
  • blogercn
  • blogercn
  • 2017年09月12日 02:33
  • 776

图像分割之(三)从Graph Cut到Grab Cut

图像分割之(三)从Graph Cut到Grab Cut zouxy09@qq.com http://blog.csdn.net/zouxy09         上一文对GraphCut做了一个...
  • zouxy09
  • zouxy09
  • 2013年01月23日 17:00
  • 99196

在Android上实现图像颜色过滤与反转

from: http://blog.csdn.net/jia20003/article/details/7169430 一:原理 Android已经提供了以resource形式加载...
  • Real_Myth
  • Real_Myth
  • 2015年10月20日 10:18
  • 1505

【OpenCV】 GrabCut.cpp详解

grabCut的方法参数 从核心代码开始 grabCut(*image, mask, rect, bgdModel, fgdModel, 1, GC_INIT_WITH_MASK); *imag...
  • bless2015
  • bless2015
  • 2016年07月29日 12:35
  • 1716

Android 使用OpenCV的三种方式(Android Studio)

from: http://blog.csdn.net/sbsujjbcy/article/details/49520791 其实最早接触OpenCV是很久很久之前的事了,大概在2013年的5,6...
  • Real_Myth
  • Real_Myth
  • 2016年08月29日 09:11
  • 841

android中利用opencv进行图像识别

之前开发的时候老大让研究下图像识别的功能,同事推荐看看opencv,发现对于移动端来说opencv的资料和demo都比较少,现在整理下之前的工作成果。 首先是进行配置工作,先导入opencv的一个代...
  • xw13782513621
  • xw13782513621
  • 2017年03月08日 16:16
  • 5394

实现android图像识别的几种方法

实现android图像识别的几种方法 点击这里下载第一种代码 最近完成了毕业设计,论文名为基于图像识别的移动人口管理系统。编写过程中学到了几种图像识别的技术,先写下来与大家分享。 ...
  • L_serein
  • L_serein
  • 2013年11月23日 16:07
  • 34103

Android图片识别

本来想利用OpenCV的工具实现手机上的图片识别,但随着对OpenCV内容的探索,严格地说,我认为所谓的“识别”,只不过是图片的“匹配”而已。 因为计算机在图片的相似度比较上太笨了,不像人眼一看就能...
  • qq_18870023
  • qq_18870023
  • 2017年03月02日 17:38
  • 4232

Android图像识别扫名片识别技术SDK

Android图像识别扫名片识别技术SDK 一、Android图像识别扫名片识别技术应用背景 这些年,随着移动互联的发展,APP应用成爆发式的增长,在很多APP中都涉及到对名片信息的录入,如移动C...
  • jinweiyirna
  • jinweiyirna
  • 2017年03月08日 08:22
  • 1185

Android静态图片人脸识别的完整demo(附完整源码)

本文介绍了android静态识别人脸并进行标记人眼位置及人脸框的完整demo,后续将再次基础上推出camera实时预览环境下人脸检测、人眼标记的demo。...
  • yanzi1225627
  • yanzi1225627
  • 2013年12月29日 11:08
  • 51290
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【图像识别】GrabCut的Android实现
举报原因:
原因补充:

(最多只允许输入30个字)