Android OpenCV 初级

一:简介

OpenCV(Open Source Computer Vision Library:http://OpenCV.org)是一个开源的基于BSD许可的库,它包括数百种计算机视觉算法。

OpenCV具有模块化结构,这就意味着开发包里面包含多个共享库或者静态库。下面是可使用的模块:

  • 核心功能(Core functionality) - 一个紧凑的模块,定义了基本的数据结构,包括密集的多维Mat数组和被其他模块使用的基本功能。
  • 图像处理(Image processing) - 一个图像处理模块,它包括线性和非线性图像滤波,几何图形转化(重置大小,放射和透视变形,通用基本表格重置映射),色彩空间转换,直方图等。
  • 影像分析(video) - 一个影像分析模块,它包括动作判断,背景弱化和目标跟踪算法。
  • 3D校准(calib3d) - 基于多视图的几何算法,平面和立体摄像机校准,对象姿势判断,立体匹配算法,和3D元素的重建。
  • 平面特征(features2d) - 突出的特征判断,特征描述和对特征描述的对比。
  • 对象侦查(objdetect) - 目标和预定义类别实例化的侦查(例如:脸、眼睛、杯子、人、汽车等等)。
  • highgui - 一个容易使用的用户功能界面。
  • 视频输入输出(videoio) - 一个容易使用的视频采集和视频解码器。
  • GPU - 来自不同OpenCV模块的GPU加速算法。
  • 一些其他的辅助模块,比如FLANN和谷歌的测试封装,Python,android等绑定和其他。

二:Android OpenCV简介

为Android开发OpenCV程序, 有两种方式, 第一种用java形式的OpenCV库,  第二种用C++形式的OpenCV库,  这两种库都在OpenCV官方提供的SDK中。 我们可以从官网下载 http://OpenCV.org/releases.html。

       第一种形式, 需要在开发环境中导入 OpenCV 的 jre包, 还需要安装 Android OpenCV Manager,  有的书上例子也是用这种方式写的。  Android OpenCV Manager是用来管理OpenCV 库的, 减少APP内存占用, 支持特定硬件优化, 定期更新库等, 具体看它的介绍(http://docs.OpenCV.org/2.4/platforms/android/service/doc/index.html)。

       第二种形式, 需要使用C++的OpenCV库,  以jni的形式来调用。底层NDK的方式开发可以使用这种。

  在本文中采取第一种方式进行。

三:Android OpenCV 开发的准备  

  1.先准备Android studio开发环境

  2.到官网(https://OpenCV.org/releases.html)下载sdk,然后import library到工程里面,添加到项目进行使用

四:OpenCV在Android上的简单使用

  1.在OpenCV中存储图像

  OpenCV中使用名为Mat的自定义对象存储图像,该对象B奥村了行数,列数,数据等能唯一标识该图像的信息,并能在需要的时候重新创建图像。不同的图像包含的数据信息也不同,例如色彩不同的图片色彩多的比灰度多的图片包含信息多,因为彩色图片是通过RGB三通道的,而灰度图片是单通道的。

  2.OpenCV中的线性滤波器

  越清晰的图片,图片的信息越丰富,进行图片好事操作的时候计算时间比包含信息少的图片要更长,为了解决这个问题,需要对图片进行模糊处理。

  很多线性滤波器都采用了核(kernel)的数字向量。核可以看作沿着像素滑动的窗口,并把计算结果输出给该像素。大概如下图

  openCV滤波器图解

  3.几种常见的模糊方法,均值模糊方法,搞死模糊方法,中值模糊方法

  均值模糊方法:均值滤波是最简单的滤波,对核进行均值计算,每一个淋雨像素都有相同的权值。

   在OpenCV for Android中的方法如下

  // Bitmap转为Mat

  Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);

  Utils.bitmapToMat(bitmap, src);

  // 中值模糊方法 Imgproc.blur(src, src, new Size(3,3));

  // Mat转Bitmap

  Bitmap processedImage = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);

  Utils.matToBitmap(src, processedImage);

 

  高斯模糊方法:高斯核是通过高斯函数所获得的,大概是临近像素对特定像素结果的影响比那些较远像素的影响要高。

  Imgproc.GaussianBlur(src, src, new Size(3, 3), 0);(Mat核bitmap转换不写了)

  中值模糊方法:椒盐噪声是一种图片中常见的噪点,噪点随机发呢不在图片中,中值模糊就是为了出去这些噪点,将核中的像素按照升序或者降序排列,

  取中值作为输出结果。

  Imgproc.medianBlur(src,src,3);(Mat核bitmap转换不写了)

  

五.检测图片的基本特征

  1.边缘检测

  边缘检测的一般步骤:

  1. 滤波——消除噪声
  2. 增强——使边界轮廓更加明显
  3. 检测——选出边缘点

  高斯差分法检测边缘

  第一步  将图像转为灰度图像 Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY);

  第二步  用两个不同的模糊半径对灰度图像执行高斯模糊(取得两幅高斯模糊图像)

  Imgproc.GaussianBlur(grayMat, blur1, new Size(15, 15), 5);

  Imgproc.GaussianBlur(grayMat, blur2, new Size(21, 21), 5);

  第三步  将两幅高斯模糊图像做减法,得到一幅包含边缘点的结果图像

  Mat diff = new Mat();

  Core.absdiff(blur1, blur2, diff);

  Canny边缘检测器

  是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化。

  平滑图像:通过使用合适的模糊半径执行高斯模糊来减少图像内的噪声。

  计算图像的梯度:这里计算图像的梯度,并将梯度分类为垂直、水平和斜对角。这一步的输出用于在下一步中计算真正的边缘。 

  非最大值抑制:利用上一步计算出来的梯度方向,检测某一像素在梯度的正方向和负方向上是否是局部最大值,如果是,则抑制该像素(像素不属于边缘)。

  这是一种边缘细化技术,用最急剧的变换选出边缘点。 

  用滞后阈值化选择边缘:最后一步,检查某一条边缘是否明显到足以作为最终输出,最后去除所有不明显的边缘。

  第一步:使用很简单,首先将图像灰度化  Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY);

  第二步:然后调用Imgproc.Canny()方法即可  Imgproc.Canny(grayMat, cannyEdges, 10, 100);

    

  

猜你喜欢

转载自www.cnblogs.com/xunzhi/p/9131962.html