1. Mat - 基本图像容器
从真实世界中获取数字图像有很多方法,比如数码相机、扫描仪、CT或者磁共振成像。无论哪种方法,我们(人类)看到的是图像,而让数字设备来“看“的时候,则是在记录图像中的每一个点的数值。
关于 Mat ,首先要知道的是你不必再手动地:
- 为其开辟空间
- 在不需要时立即将空间释放
但手动地做还是可以的:大多数OpenCV函数仍会手动地为输出数据开辟空间。当传递一个已经存在的 Mat 对象时,开辟好的矩阵空间会被重用。也就是说,我们每次都使用大小正好的内存来完成任务。
2. 存储方法
这里讲述如何存储像素值。需要指定颜色空间和数据类型。颜色空间是指对一个给定的颜色,如何组合颜色元素以对其编码。最简单的颜色空间要属灰度级空间,只处理黑色和白色,对它们进行组合可以产生不同程度的灰色。
对于彩色方式则有更多种类的颜色空间,但不论哪种方式都是把颜色分成三个或者四个基元素,通过组合基元素可以产生所有的颜色。
RGB颜色空间是最常用的一种颜色空间,这归功于它也是人眼内部构成颜色的方式。它的基色是红色、绿色和蓝色,有时为了表示透明颜色也会加入第四个元素 alpha (A),ARGB。
有很多的颜色系统,各有自身优势:
-
RGB
是最常见的,这是因为人眼采用相似的工作机制,它也被显示设备所采用。 -
HSV
和HLS把颜色分解成色调、饱和度和亮度/明度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。 -
YCrCb
在JPEG图像格式中广泛使用。 -
CIE L*a*b*
是一种在感知上均匀的颜色空间,它适合用来度量两个颜色之间的距离 。
每个组成元素都有其自己的定义域,取决于其数据类型。如何存储一个元素决定了我们在其定义域上能够控制的精度。
最小的数据类型是 char ,占一个字节或者8位,可以是有符号型(0到255之间)或无符号型(-127到+127之间)。尽管使用三个 char 型元素已经可以表示1600万种可能的颜色(使用RGB颜色空间),但若使用float(4字节,32位)或double(8字节,64位)则能给出更加精细的颜色分辨能力。但同时也要切记增加元素的尺寸也会增加了图像所占的内存空间。
3. CV_<bit_depth>(S|U|F)C<number_of_channels>
CV_<bit_depth>(S|U|F)C<number_of_channels>
- bit_depth:比特数,有8bite,16bites,32bites,64bites
-
S|U|F:
S:代表signed int,有符号整形
U:代表unsigned int,无符号整形
F:代表float,单精度浮点型 -
C<number_of_channels>:代表一张图片的通道数,
比如:
//【1】CV_8UC1---则可以创建----8位无符号的单通道---灰度图片------grayImg
#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
//【2】CV_8UC3---则可以创建----8位无符号的三通道---RGB彩色图像---colorImg
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
//【3】CV_8UC4--则可以创建-----8位无符号的四通道---带透明色的RGB图像
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
一般的图像文件格式使用的是Unsigned,对应的是8bits,CvMat矩阵对应的参数类型就是CV_8UC1,CV_8UC2,CV_8UC3,CV_8UC4;
float 是32位的,对应CvMat数据结构参数就是:CV_32FC1,CV_32FC2,CV_32FC3...
double是64bits,对应CvMat数据结构参数:CV_64FC1,CV_64FC2,CV_64FC3等。
4. 在图像中截取子图并显示
这里将子图截取后转换为灰度图像:
public static Bitmap getRoi(Bitmap bitmap) {
Rect roi = new Rect(200, 150, 200, 300);//create a sub image with (x,y,width,height)
Bitmap roiMap = Bitmap.createBitmap(roi.width, roi.height, Bitmap.Config.ARGB_8888);
org.opencv.android.Utils.bitmapToMat(bitmap, sSrc);
Mat roiMat = sSrc.submat(roi);
Mat roiDstMat = new Mat();
Imgproc.cvtColor(roiMat, roiDstMat, Imgproc.COLOR_BGRA2GRAY);
org.opencv.android.Utils.matToBitmap(roiDstMat, roiMap);
//Don't forget to release all of this. Or it may cause OOM.
roiDstMat.release();
roiMat.release();
sSrc.release();
return roiMap;
}
5. 调整图像亮度与对比度
public static void contrast_ratio_adjust(Bitmap bitmap) {
org.opencv.android.Utils.bitmapToMat(bitmap, sSrc);
//This operation enables you to adjust CM in a float number.
sSrc.convertTo(sSrc, CvType.CV_32F);
Mat whiteImage = new Mat(sSrc.size(), sSrc.type(), Scalar.all(1.25));//Contrast Ratio
Mat bwImage = new Mat(sSrc.size(), sSrc.type(), Scalar.all(30));//Brightness+30
Core.multiply(whiteImage, sSrc, sSrc);
Core.add(bwImage, sSrc, sSrc);
sSrc.convertTo(sSrc, CvType.CV_8U);
org.opencv.android.Utils.matToBitmap(sSrc, bitmap);
//Don't forget to release.
bwImage.release();
whiteImage.release();
sSrc.release();
}