Android和OpenCV的学习mat运算/颜色转换
1 Mat
1.1 Mat的概念
Mat类主要用来定义Mat对象,切割Mat对象。常规的Bitmap位图在OpenCV中都需要转换为Mat,。
Android中对图像是用bitmap格式来进行处理,而openCV中是采用Mat格式进行处理。所以我们在Android中使用OpenCV也要将Bitmp转化为Mlat格式。Mat类用于表示一个多维的单通道或者多通道的数组。能够用来保存实数或复数的向量、矩阵,灰度或彩色图像,立体元素,张量以及直方图。简而言之,Mat就是用来保存多维的矩阵的。Mat对象中包含了图像的各种基本信息与图像像素数据。Mat是由头部与数据部分组成的,其中头部还包含一个指向数据的指针。我们把Mat可以视作就是图像矩阵。
1.2 Bitmap和Mat的转换
Bitmat转Mat
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.f001);//图片名称
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat);
直接用mat加载图片
try {
mat1 = Utils.loadResource(this, R.drawable.f001);//图片名称
} catch (IOException e) {
e.printStackTrace();
}
Mat转Bitmat在Android UI上显示
bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mat, bitmap);
imageView.setImageBitmap(bitmap);
1.3 Mat的位运算和算术运算
Core类主要用于Mat的运算,提供了很多运算功能的静态函数。
Mat格式的图像可以直接进行位运算和算术运算。位运算主要支持按位非、按位与、按位或、按位异或。算术运算主要支持加减乘除。这些运算其实实际上都是矩阵的运算。
方法 | 操作 |
public static void bitwise_not ( Mat mat,Mat dst) | 按位非 |
public static void bitwise_and (Mat mat, Mat mat1, Mat dst) | 按位与 |
public static void bitwise_or(Mat mat,Mat mat1,Mat dst) | 按位或 |
public static void bitwise_xor(Mat mat, Mat mat1, Mat dst) | 按位异或 |
方法 | 操作 |
public static void add(Mat mat, Mat mat1, Mat dst) | 矩阵加法 |
public static void subtract(Mat mat, Mat mat1, Mat dst) | 矩阵减法 |
public static void multiply(Mat mat, Mat mat1, Mat dst) | 矩阵乘法 |
public static void divide(Mat mat, Mat mat1, Mat dst,double scale,int dtype) | 矩阵除法 |
使用例子
//按位和 两张图片宽高一样
Core.bitwise_and(mat1,mat2,dst);
bitmap =Bitmap.createBitmap(dst.width(),dst.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dst,bitmap);
img1.setImageBitmap(bitmap);
1.4 Mat的release
protected void onDestroy(){
super. onDestroy();
mat.release();
}
2 颜色转换
2.1 图像色彩模式
图像的色彩模式主要有以下几种:
位图模式 位图模式是图像中最基本的格式,图像只有黑色和白色像素,是色彩模式中占有空间最小的,同样也叫做黑白图,它包含的信息量最少,无法包含图像中的细节,相当于只有0或者1。一副彩色图如果要转换成黑白模式,则一般不能直接转换,需要首先将图像转换成灰度模式。
灰度模式 灰度模式即使用单一色调来表示图像,与位图模式不同,不像位图只有0和1,使用256级的灰度来表示图像,一个像素相当于占用8位一个字节,每个像素值使用0到255的亮度值代表,其中0为黑色,255为白色,相当于从黑->灰->白的过度,通常我们所说的黑白照片就是这种模式,与位图模式相比,能表现出一定的细节,占用空间也比位图模式较大。
RGB模式 RGB模式为我们经常见到的,被称为真色彩。RGB模式的图像有3个颜色通道,分布为红(Red) ,绿(Green)和蓝(Bule),每个都占用8位一个字节来表示颜色信息,这样每个颜色的取值范围为O~255,那么就三种颜色就可以有多种组合,当三种基色的值相等时表现出为灰色,三种颜色都为255即为白色,三种颜色都为O,即为黑色。RGB模式的图像占用空间要比位图,灰度图都要大,但表现出的细节更加明显。
HSV模式 是根据日常生活中人眼的视觉对色彩的观察得而制定的一套色彩模式,最接近与人类对色彩的辨认的思考方式,所有的颜色都是用色彩三属性来描述
- H:(色相):是指从物体反射或透过物体传播的颜色
- S:(饱和度):是指颜色的强度或纯度,表示色相中灰色成分所占的比例
- V:(亮度):是指颜色的相对明暗程度,通常100%定义为白色;0%为黑色
- 另外还有CMYK模式、YUV模式等。
2.2 cvtColor()颜色转换函数
OpenCv中主要使用cvtColor()函数进行颜色转换操作。
Imgproc.cvtColor(source mat,destination mat1,Color_Conversion_Code);
Color_Conversion_Code:颜色转换模式
常用的颜色转换模式
颜色码 | 功能 |
COLOR_BGR2RGB | 颜色空间转换 |
COLOR_BGR2GRAY | BGR转换到灰度空间 |
COLOR_GRAY2RGB | 灰度转换到RGB |
COLOR_RGB2HSV | RGB转换到HSV |
COLOR_RGB2RGBA | 添加alpha通道 |
灰度转换例子
Bitmap bp= BitmapFactory.decodeResource(getResources(),R.drawable.f001);//图片名字
Utils.bitmapToMat(bp,mat1);
Imgproc.cvtColor(mat1,mat2,Imgproc.COLOR_BGRA2GRAY);
Utils.matToBitmap(mat2,bp);
img1.setImageBitmap(bp);
2.3 threshold()阈值函数
图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。转换二值图的关键就是确定一个阈值,整张图片中高于阈值的点都置为255,低于阈值的点都置为0,就可以呈现出明显的二值黑白效果。阈值的确定有两种方法,一种是手动指定,由开发者手动确定一个阈值,在一些专用场景下可以通过实验效果调整。手动阀值法手动阈值法所使用的函数的是: Imgproc.threshold ()。另一种自动阈值法,OpenCV中也可以使用算法来自动计算阈值。OpenCV支持均值算法和高斯均值算法。它不是计算全局图像的阈值,而是根据图像不同区域亮度分布,计算其局部阈值,所以对于图像不同区域,能够自适应计算不同的阈值,因此被称为自适应阈值法。使用的函数的是:Imgproc.adaptiveThreshold()
手动阈值
threshold(Mat mat,Mat dst,double thresh,double maxval, int type);
参数:
- mat:Mat 输入图像
- dst:Mat 输入图像 阈值操作结果填充在此图像
- thres:double 自己指定的阈值
- maxval:double 当type为THRESH_BINARY 或 THRESH_BINARY_INV时的最大值
- type:int,阈值类型,对对象取阈值的方式0:THRESH_BINARY : src(x,y) > thresh ? maxval : 0。当前像素点的灰度值>当前像素点值为maxval,反之为0。
- THRESH_BINARY_INV : src(x,y) > thresh ? 0 : maxval。当前像素点灰度值 > thresh,当前像素点值为О反之为 maxval。
- THRESH_TRUNC : src(x,y) > thresh ? threshold : src(x,y)。当前像素点灰度值 > thresh,设定为thvesh,反之保持不变。
- THRESH_ TOZERO :src(x,y) > thresh ? src(x,y):0。当前像素点灰度值>thresh,当前像素点值保持不变,其他情况为0。
- THRESH_TOZERO_INV : src(x,y) > thresh ? 0 : src(x,y)。当前像素点灰度值>thresh,当前像素点值为0,其他情况保持不变。
Imgproc.threshold(mat,dst,125,255,Imgproc.THRESH_BINARY);
自动阈值
public static adaptiveThreshold(Nat src,Hat dst ,double maxNalue,int adaptivetMethod,int thresholdType,int blockSize,double C)
参数:
- src : Mat输入图像
- dst : Mat输出图像阈值操作结果填充在此图像
- maxValue : double 分配给满足条件的像素的非零值
- adaptiveMethod : int自定义使用的阈值算法,ADAPTIVE_THRESH_MEAN_C、ADAPTIVE_THRESH_GAUSSIAN_C --ADAPTIVE_THRESH_MEAN_C时,T(x,y) = blockSize * blockSize [b] blockSize [b]=邻域内(x,y)- C --ADAPTIVE_THRESH_GAUSSIAN_C时,T(x,y) = blockSize * blockSize [b] blockSize [b]=邻域内(x,y)-C与高斯窗交叉相关的加权总和
- thresholdType : int阈值类型,只能是THRESH_BINARY、THRESH_BINARY_INV
- blockSize : int 用来计算阈值的邻域尺寸3,5,7等等,奇数
- C : double 减去平均值或加权平均值的常数,通常情况下,它是正的,但也可能是零或负。
Imgproc.adaptiveThreshold(mat,dst ,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,13,5);