最近一段时间再研究图像技术,所以抽抽时间写写心得。
说到OpenCV 需要说的一个东西必须要说的就是Map的自定义对象存储图像,该图像保存了行数,列数,数据等能唯一标识该图像的信息,并且能在需要的时候重新创建图像。
使用OpenGL 需要在设备上安装opencv管理器的应用 (找到适配的CPU 安装上去就OK) 如果不想使用OpenCV的管理器 也可以自定义JNI 虽然APK的大小会有显著的增加 但是 对于用户来说 用这个app 还需要下载管理器 不免得繁杂 本篇使用的OpenCV的管理器 后面有时间再更新JNI的实现
下面是android opencv的管理器图
页面逻辑 在activity进入运行状态的时候检测OpenCV是否成功配置
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION,this,mOpenCVCallBacl);
mOpenCVCallBacl为OpenCV管理器安装的回调函数
均值模糊 blur()
Bitmap mBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.yr)).getBitmap();//获取本地的图片
Mat src =new Mat(mBitmap.getHeight(), mBitmap.getWidth(), CvType.CV_8UC4);//以位图加载图像 并将其转换为Mat以供处理的代码
Utils.bitmapToMat(mBitmap, src);
我们使用OpenCV提供的Buur()函数对对象做均值模糊 核用6*6(图片太小 看的清楚一点)
Imgproc.blur(src, src, new Size(6, 6));//均值模糊
最后我们需要一张改变后的图显示处理的效果,从Mat对象中获取就OK
Bitmap change = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(src, change);
change就是种均值模糊后的图像 (下面附上效果图)
高斯模糊 GaussianBlur()
高斯模糊的效果很常见 也有人叫它毛玻璃 也可以借助其他的库 本人写过Java的处理 但是耗时远远比JNI的的要大很多 因为Java跟c或者c++的效率自然是比不了 。目前我认为直接jni实现处理的效果图 返回图位是最快的, 回归正题。
大体理想的情况下 临近像素对于特定的像素结果影响比那些较远的像素高
OpenCV提供了GaussianBlur的内置函数
Imgproc.GaussianBlur(src,src,new Size(7,7),0);//高斯模糊 7*7的高斯核 其他的与均值模糊一样的处理
附上效果图
中值模糊 medianBlur()
椒盐噪声是一种图像中比较常见的噪声 该噪声是稀疏分布在整个图像中的黑白像素点
在该滤波中,我们将覆盖的像素点按照升或者降序排列 将中间元素作为锚点像素 使用中值滤波的优势在于椒盐噪声的是稀疏的出现 将他的值平均时只会对很少一部分像素造成影响,
OpenCV内置函数medianBlur()进行中值滤波
Imgproc.medianBlur(src,src,9);
下面附上效果图
锐化
锐化自定义的核 得到更加清晰的图像
Mat kernel =new Mat(3, 3, CvType.CV_16SC1);
kernel.put(0, 0, 0, -1, 0, -1, 5, -1, 0, -1, 0);//核
Imgproc.filter2D(src,src,src.depth(),kernel);
//CvType.CV_16SC1 表示图像包含一个通道(c1),图像中每个像素包含一个16比特有符号整数(16s)
下面附上效果图
膨胀
膨胀是一种奖图像中亮点区域拓张的办法。
我们可以使用OpenCv函数getStructuringElement()获取需要的核,用于执行膨胀
Mat kernelDliate=Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(5,5));
Imgproc.dilate(src,src,kernelDliate);
如果使用矩形的结构元素 图像就以矩形的形式生长,相似的 如果我们使用椭圆的结构元素,图像就以椭圆的形式生长
下面附上效果图
腐蚀
腐蚀是一种将图像中暗区域扩张的方法 可以用来出去图像中的噪声
Mat kernelErode=Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(5,5));
Imgproc.erode(src,src,kernelErode);
附上效果图
阈值化
阈值化是一种将我们想要在图像中分析的区域分割出来的方法 以为二值阈值化为例
Imgproc.threshold(src,src,100,255,Imgproc.THRESH_BINARY);//二值阈值化 100是阈值 255是最大值(白色) Imgproc.THRESH_BINARY二值化的类型
下面附上效果图
自适应阈值
对于执行图像的分割来说 设置一个全局性阈值并不是一个好的选择 光照条件影响像素的亮度。为了克服这个限制 尝试根据邻域像素为任意像素计算阈值
Imgproc.cvtColor(src,src,Imgproc.COLOR_BGR2GRAY);
Imgproc.adaptiveThreshold(src,src,255,Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY,3,0);//自定义阈值化
自定义的方法 可能会有道两种方法
参数一
Imgproc.ADAPTIVE_THRESH_MEAN_C 阈值是邻域像素的均值
Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C 阈值是邻域像素的加权和 权重来自高斯核
参数二
邻域的大小
参数三
这是从对每个像素计算得到的均值或加权均值减去的常量
附上效果图
最后把源码附上