opencv4android 常用函数API(一)
来源:互联网 发布:java布尔型变量 编辑:程序博客网 时间:2024/06/07 03:46
openCV4android常用变换(一)
简介
OpenCV的全称是:Open Source Computer Vision Library。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。–来自百度。
OpenCV4android是opencv在android上的实现,进行一定配置之后就一个在android中通过Java调用opencv中的功能,可以实现很多不同的效果和进行图片分析,处理等。
作者水平有限,并没有专门学过opencv,也不了解具体的算法实现,这篇文章只是简单的介绍一下opencv4android在android中的使用和相关api,如有误,请斧正。
这篇都有哪些内容:主要就是Imgproc中API的使用,核心(core)模块没有多介绍,一些基础的关于opencv的知识可以在http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html学习,作者本人也是在这个网站学的,而且所有文章中的内容都是根据这个网站所提供的信息,在opencv4android中的实现,欢迎交流。
- 图像平滑处理
- 腐蚀和膨胀
- 更多形态学变化
- 图像金字塔
- 简单的阈值操作
- 实现自己的线性滤波器
- 给图像添加边界
- Sobel导数
先介绍这么多,以后还会有更多的内容的。这阅读下面的内容之前,请确定自己的Studio已经配置好了opencv4android,不会的可以去看我上一篇文章。先从简单的来。
图像的平滑处理
平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法。
在opencv中有四种常用处理方式:
- blur 归一化块滤波器
- GaussianBlur 高斯滤波器
- medianBlur 中值滤波器
- bilateralFilter 双边滤波器
这里先为大家普及两个概念,内核或者说核(Size),锚点(Point)
在我看来,核就是一个物体,用这个物体去扫描图片,使图片产生一系列的变化,锚点就是这个核中额某一个点,在一些特殊需要的情况下可能不在中心位置(我猜的)
具体的每一种滤波器是如何处理图像的我也不会,复制粘贴也不是我的风格,就这样了,直接上代码,看看效果。
private Mat rgbMat,dstMat;private void changeBitmap(){ if(rgbMat==null|dstMat==null){ rgbMat=new Mat(); Utils.bitmapToMat(mBitmap,rgbMat); //双边转换// Imgproc.cvtColor(rgbMat,rgbMat,Imgproc.COLOR_BGR2RGB); dstMat=new Mat(rgbMat.size(),rgbMat.type()); } Log.d("TAG","rgb:"+rgbMat.type()+"/"+rgbMat.size()+"/"+dstMat.size()+"/"+dstMat.type()); switch (operation){ case 0: Imgproc.blur(rgbMat,dstMat,new Size(2*n+1,2*n+1),new Point(-1,-1)); break; case 1: Imgproc.GaussianBlur(rgbMat,dstMat,new Size(2*n+1,2*n+1),0,0); break; case 2: Imgproc.medianBlur(rgbMat,dstMat,2*n+1); break; case 3: Imgproc.bilateralFilter(rgbMat,dstMat,10,75,75); break; } Utils.matToBitmap(dstMat,dstBitmap); dstImage.setImageBitmap(dstBitmap);}
说一下流程:
- 创建两个矩阵(容器)对象,分别问原图像(rgbMat),输出图像(dstMat);
- 将其中rgbMat赋值,使用* Utils.bitmapToMat(mBitmap,rgbMat)*将一张图片变成矩阵对象,赋值到rgbMat中;
- dstMat采用rgbMat的尺寸和类型创建。
四种不同的平滑方式:
- blur:参数:原图像,输入图像,内核(内核中数值必须为正奇数),锚点(-1,-1代表内核中心)。
- GaussianBlur:参数:原图像,输入图像,内核(内核中数值必须为正奇数),x方向标准方差,y方向标准方差(0代表使用内核大小计算得到)。
- medianBlur:参数:原图像,输入图像,内核大小(必须为正奇数)。
- bilateralFilter:参数:原图像,输入图像,像素的邻域直径,颜色空间的标准方差,坐标空间的标准方差(像素单位))。
调用Imgproc相对应的平滑方法会执行相应的操作,这里需要重点说一下bilateralFilter这个滤波器,在之前我练习的时候以为都差不多就使用高斯滤波器,跑一下可以了就过了,直到两个小时前在使用bilateralFilter的时候才发现,一直在报错,而且我也不理解是什么意思。
CvException [org.opencv.core.CvException: cv::Exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/imgproc/src/smooth.cpp:3145: error: (-215) (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.data != dst.data in function void cv::bilateralFilter_8u(const cv::Mat&, cv::Mat&, int, double, double, int)
]
可以看一下错误信息,对于一个从没有学过C++,opencv的人来说这是什么?完全不理解好不好,之后就是上网查资料,看见了这个。
CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data );
这个是赵春江先生/女士在CSDN上一篇博客的内容,是不是特别相似,不过到这我也不明白,所以就百度了下 CV_Assert 这个方法,说是C++中的assert()方法类似,括号内为false会抛一个异常,到这我就知道问题出在哪里了,之后就是解决问题吧,又是坑啊,在opencv4android中并没有明确的CV_8UC1或者CV_8UC3常量,我就是想把type设置成指定类型的我都不知道类型是多少,不过,经过我不断的尝试(就是一个个转换看哪个不报错而已),终于也可以了,可以看见:
Imgproc.cvtColor(rgbMat,rgbMat,Imgproc.COLOR_BGR2RGB);
使用COLOR_BGR2RGB这个转换方式可以将图片转换成CV_8UC3,可能会有人问你怎么知道到RGB就是CV_8UC3,不要嘲笑我,我是真不知道8位无符号3通道就是RGB,不过我有一个灵活的大脑和勤劳的双手,少年看这里:
The input Mat object has to be of the types 'CV_8UC1' (gray-scale), 'CV_8UC3' (RGB) or 'CV_8UC4' (RGBA).
这个是Mat类中倒数第二个方法的注释,可以看到’CV_8UC3’ 就是RGB,而’CV_8UC1’就是灰度图,用android中的数值应该怎么表示那?告诉你:
- CV_8UC1—–Gray(灰度图)—0
- CV_8UC3—–RGB(彩色图)—16
- CV_8UC4—–BGR(彩色图)—24
不要问我怎么知道的,我会告诉你每次转换之后我都打印了一下type了吗?,现在这个问题算是解决了,只要将BGR图片转换成RGB的就可以,至于为什么,我不知道。。。。效果图
这个是正常BGR模式下的效果图,可以看出来在前三种模式下,相同内核大小,高斯滤波器的平滑效果明显要弱于其他两种,具体的不多说了,看下RGB模式下的效果:
可以看出来在初始情况下,图片就已经转换为RGB模式了,颜色上有明显的不同,之后是四种平滑方式的对比实现,可以根据个人喜好去选择不同的平滑方式。
腐蚀和膨胀
腐蚀和膨胀是最基本的形态学操作,之后会学到的其他形态学变化都是基于这两种所实现的,形态学操作,简单来讲,形态学操作就是基于形状的一系列,图像处理操作,通过将结构元素作用于输入图像来产生输出图像。
- 腐蚀:erode。参数:原图像,输出图像,内核(通过Imgproc.getStructuringElement)指定内核形状和内核大小
- 膨胀:dilation.参数:原图像,输出图像,内核(通过Imgproc.getStructuringElement)指定内核形状和内核大小
参考代码:
private Mat rgbMat,dstMat;//腐蚀private void changeBitmap(){ if(rgbMat==null|dstMat==null){ rgbMat=new Mat(); dstMat=new Mat(); Utils.bitmapToMat(mBitmap,rgbMat); } //设置内核形状和内核大小 Mat kernel=Imgproc.getStructuringElement(shape,new Size(2*n+1,2*n+1),new Point(n,n)); Imgproc.erode(rgbMat,dstMat,kernel); Utils.matToBitmap(dstMat,dstBitmap); dstImage.setImageBitmap(dstBitmap);}//膨胀private void grayBitmap(){ if(rgbMat==null|dstMat==null){ rgbMat=new Mat(); dstMat=new Mat(); Utils.bitmapToMat(mBitmap,rgbMat); } //设置内核形状和内核大小 Mat kernel=Imgproc.getStructuringElement(shape,new Size(2*n+1,2*n+1),new Point(n,n)); Imgproc.dilate(rgbMat,dstMat,kernel); Utils.matToBitmap(dstMat,dstBitmap); dstImage.setImageBitmap(dstBitmap);}
可以看到大部分的代码都是相同的就是函数名不一样,也没有什么好解释的,看效果:
关于内核的形状有三种,分别是矩形,交错形和椭圆形,可以通过腐蚀时看出来三种不同的内核对腐蚀效果的影响。
更多形态学变化
在掌握了基础的两种变化之后,可以学习更复杂一点的形态学变化方式:
- 开运算 (Opening):腐蚀后膨胀
- 闭运算 (Closing):膨胀后腐蚀
- 形态梯度 (Morphological Gradient):膨胀和腐蚀之差
- 顶帽 (Top Hat):原图像和开运算之差
- 黑帽(Black Hat):原图像和闭运算之差
所使用的函数统一为morphologyEx(Mat src, Mat dst, int op, Mat kernel),其中src为原图像,dst为输出图像,op为操作类型,kernel为内核。
忘了介绍了,在opencv4android中关于内核形状和形态学方法是有常量表示的:
形态学方法:
- MORPH_ERODE = 0,
- MORPH_DILATE = 1,
- MORPH_OPEN = 2,
- MORPH_CLOSE = 3,
- MORPH_GRADIENT = 4,
- MORPH_TOPHAT = 5,
- MORPH_BLACKHAT = 6,
内核形状:
- MORPH_RECT = 0,
- MORPH_CROSS = 1,
- MORPH_ELLIPSE = 2,
至于这些内容是从哪找的,可以去参考Imgproc中的常量。上代码~~~~·
private void changeBitmap() { if(rgbMat==null|dstMat==null){ rgbMat=new Mat(); dstMat=new Mat(); Utils.bitmapToMat(mBitmap,rgbMat); } Mat kernel=Imgproc.getStructuringElement(shape,new Size(2*n+1,2*n+1),new Point(n,n)); Imgproc.morphologyEx(rgbMat,dstMat,operation,kernel); Utils.matToBitmap(dstMat,dstBitmap); Toast.makeText(MainActivity.this,"OK",Toast.LENGTH_SHORT).show(); dstImage.setImageBitmap(dstBitmap);}
效果图如下:
个人比较喜欢黑猴子,不知道大家喜欢哪一个?值得注意就是当采用black加椭圆内核的时候,运行起来有比较严重的延迟,界面被阻塞了,实际应用中应该采用异步的方式去使用,更多的就需要大家去实践了。如果有不理解的可以留言,这篇就讲这么多,剩下的内容我需要去整理一下,先到这里。
- opencv4android 常用函数API(一)
- 使用OpenCV4android(一)
- opencv4android常用变换(二)
- opencv4android常用变换(终)
- OpenCv4Android (一)
- numpy 常用api(一)
- sklearn 常用api(一)
- Java常用API(一)
- VC API常用函数简单例子大全一
- VC API常用函数简单例子大全一
- VC API常用函数简单例子大全一
- OpenCV4Android--使用java api做人脸识别
- Linux网络编程常用API(一)
- express的常用API(一)
- Java常用API(一)Object
- JAVA 常用API(一)
- ElasticSearch-常用API(一)
- JS 常用 API (一)
- ubuntu系统下mysql允许远程访问
- 手把手教你把Vim改装成一个IDE编程环境(图文)
- DOM入门
- 变量作用域(JavaScript)
- java引用介绍篇
- opencv4android 常用函数API(一)
- IOS-自定义Tabbar与Navigation
- tableView 的headerView下拉缩放
- float/clear float的问题总结 (⌒▽⌒)
- Elipse安装插件
- Linux下分割、合并PDF(pdftk)
- HDU 2222 Keywords Search
- 怎样yarn application -kill jobid
- Android ListView at android.widget.AbsListView$RecycleBin.addScrapView