OpenCV中通过Mat类完成对图像的基本操作,包括对图像的写入、输出和处理都依赖于对Mat矩阵的操作。OpenCV通过将图像实例化为矩阵的方式,使得我们可以在最大的限度内对图像进行处理和更改,关于这部分之后我们之后再详细的进行说明。那么,我们就从Mat类和图像的输入输出开始吧。
一、Mat类的创建
在调用OpenCV类之前,需要载入库文件
static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);};
第一章的时候我们写过一小段简单的代码创建一个对角矩阵。我们很容易就能实例化一个Mat类对象:
Mat test = new Mat();
这样可以生成一个空的矩阵,通过调用Mat下的方法,也可以生成零矩阵,值全唯一的矩阵等(Mat.diag、Mat.eye、Mat.ones、Mat.zeros)
同样,我们可以在Mat类的同时设置矩阵的基本参数:
Mat test = new Mat(3, 3, CvType.CV_8UC1);
第一个参数代表矩阵的行数(rows),第二个参数代表矩阵的列数(cols),第三个参数(type)代表矩阵中像素点的位数和通道数。灰度图一个参数代表一个点,彩图三个数代表一个点,数值的范围均为0~255,数值越大,亮度越高,具体的含义我们在第一章:在Java中安装与配置OpenCV的末尾也有提到。Type可以取到的值列在了下面的表里:
Modifier and Type | Field and Description |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int | |
static int |
命名原则:
CV_<bit-depth>{U|S|F}C<number_of_channels>
其中,U是无符号整型,S是有符号整型,F是浮点型,C是通道数
bit-depth对应位数,有8位,16位,32位,64位可选
number_of_channels是通道数,有1,2,3,4可选
二、图像的输入和输出
OpenCV可以简单的载入图象并处理输出,输入输出操作对应imread()、imwrite()两个方法,值得一提的是,OpenCV目前并没有在Java中实现C++里的imshow()函数,所以如果在项目中如果需要查看载入的图片的话只能通过imwrite()输出后在文件夹中看效果,略微有些麻烦。当然我们也可以动手自己写一个包来实现imshow()的功能,如果有空的话我会写一个放上来的。
图象的读写操作全部通过Imgcodecs类实现,可以从文件或内存中读取/写入图片,具体可以看一下第二章:OpenCV组件浅析中的相关介绍。
2.1 imread方法
具体形式如下所示:
Mat Imgcodecs.imread(const string& filename, intflags=1 );
第一个参数filename,需要我们填想要载入的图片路径名。Windows下OpenCV支持如下图象格式:
· Windows位图 - *.bmp, *.dib
· JPEG文件 - *.jpeg, *.jpg, *.jpe
· JPEG 2000文件- *.jp2
· PNG图片 - *.png
· 便携文件格式- *.pbm, *.pgm, *.ppm
· Sun rasters光栅文件 - *.sr, *.ras
· TIFF 文件 - *.tiff, *.tif
第二个参数intflags,是一个标志表明加载图象的颜色类型,它可以指导将原图读取时进行一定的转换,可以不填,缺省值为IMREAD_LOAD_GDAL,缺省情况下默认输入三通道(RGB)图像。如果想要直接处理原图的话,可以设置为IMREAD_UNCHANED。顺带一提,OpenCV中三原色的顺序和一般情况相反,依次是BGR,下面是intflags可以设置的值:
Modifier and Type | Field and Description |
IMREAD_UNCHANGED | If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). |
IMREAD_GRAYSCALE | If set, always convert image to the single channel grayscale image. |
IMREAD_COLOR | If set, always convert image to the 3 channel BGR color image. |
IMREAD_ANYDEPTH | If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. |
IMREAD_ANYCOLOR | If set, the image is read in any possible color format. |
IMREAD_LOAD_GDAL | If set, use the gdal driver for loading the image. |
IMREAD_REDUCED_GRAYSCALE_2 | If set, always convert image to the single channel grayscale image and the image size reduced 1/2. |
IMREAD_REDUCED_COLOR_2 | If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2. |
IMREAD_REDUCED_GRAYSCALE_4 | If set, always convert image to the single channel grayscale image and the image size reduced 1/4. |
IMREAD_REDUCED_COLOR_4 | If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4. |
IMREAD_REDUCED_GRAYSCALE_8 | If set, always convert image to the single channel grayscale image and the image size reduced 1/8. |
IMREAD_REDUCED_COLOR_8 | If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8. |
2.2 imwrite方法
我们用同样的方式介绍一下imwrite()方法,imwrite方法用于输出图片到文件,它的声明如下:
Imgcodecs.imwrite(const string& filename,InputArray img, const vector<int>& params=vector<int>() );
第一个参数为字符串类型的文件输出位置,执行命令后图片会被保存在我们指定的目录下需要写出文件的全名,形如“123.jpg”这样。
第二个参数为将要输出为图片的源矩阵的名字,它是一个我们读入或处理过的Mat类型的参数。
第三个参数是const vector<int>&类型的params,表示为特定格式保存的参数编码,它有默认值vector<int>(),所以一般情况下不需要填写。而如果要填写的话,有下面这些需要了解的地方:
- 对于JPEG格式的图片,这个参数表示从0到100的图片质量(CV_IMWRITE_JPEG_QUALITY),默认值是95.
- 对于PNG格式的图片,这个参数表示压缩级别(CV_IMWRITE_PNG_COMPRESSION)从0到9。较高的值意味着更小的尺寸和更长的压缩时间,而默认值是3。
- 对于PPM,PGM,或PBM格式的图片,这个参数表示一个二进制格式标志(CV_IMWRITE_PXM_BINARY),取值为0或1,而默认值是1。
2.3 imencode方法和imdecode方法
这两个方法用来从内存中读取(imencode)和写入(imdecode)图片,有兴趣的话可以在深入了解一下,形式如下:
-
Imgcodecs.imdecode(buf, flags);
-
Imgcodecs.imencode(ext, img, buf);
这里是一个小例子,作用是写入一张图片并输出它的灰度图
-
package opencv;
-
-
import org.opencv.core.*;
-
import org.opencv.imgcodecs.Imgcodecs;
-
import org.opencv.imgproc.Imgproc;
-
-
public class one {
-
static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}; //用来调用OpenCV库文件,必须添加
-
-
publicstatic void main(String args[]){
-
Matimg = Imgcodecs.imread("F:/workspace/opencv/girl.jpg",Imgcodecs.IMREAD_GRAYSCALE); //用灰度图的方式读取一张图片
-
-
Imgcodecs.imwrite("F:/workspace/opencv/girl_1.jpg",img);
-
}
-
}
原图:
输出的灰度图: