《Java图像处理:基于OpenCV与JVM》 ——1.8 利用子矩阵修剪图像
1.8 利用子矩阵修剪图像
问题定义
只保存图像指定的子区域。
解决方法
这篇简短的攻略的主要目标是介绍submat函数。submat的返回值是一个矩阵对象,内容是原图的子矩阵或子区域。
工作原理
读入一张猫咪图片,通过submat来截取我们想要的那部分内容。这个例子使用的猫咪图片如图1-12所示。
图1-12 一只猫咪
当然,可以使用任何一张你喜欢的猫咪图片。现在,让我们使用imread来读取这个文件。
根据观察可知,println输出了矩阵对象本身的一些信息。它的大部分信息与内存有关,所以你可以直接访问内存,同时它也显示了这个矩阵对象是否是一个子矩阵。在这个例子中,由于这个矩阵对象是原始图片,所以它的isSubmat值是false。
如图1-13所示,Atom编辑器中的自动补全功能会向你提示不同版本的submat函数。
图1-13 使用不同参数的submat函数
现在我们使用submat函数的第一种形式,输入参数是每一行和每一列的起始和终止值。
输出的对象显示新创建的矩阵对象确实是一个子矩阵。
你可以像处理普通矩阵对象那样来处理这个新建的子矩阵,例如可以尝试保存它。
由于边界值是根据原始猫咪图片精心挑选的,我们可以得到图1-14中的漂亮结果。
有一件很好的事情是,当你对子矩阵进行了操作之后,原始矩阵也会受到同样的影响。例如,你对子矩阵中猫咪的脸进行了模糊处理,并且保存了整个矩阵(不是子矩阵),那么就只有猫咪的脸会变得模糊。具体操作如下所示:
blur是org.opencv.imgproc.Imgproc类中的一个核心函数,它的输入参数是size对象,用来指明每个像素模糊区域大小,size越大,模糊的效果也越强。
模糊的结果如图1-15所示,当你仔细看的时候会发现,只有猫咪的脸部被模糊了,这也是我们之前保存的子矩阵的位置。
图1-15 可怜的模糊猫咪
你之前也见到过submat函数的其他定义,还有两种方法可以获得子矩阵。
一种是采用两个Range参数,第一个代表行(y或高度)的范围,第二个代表列(x或宽度)的范围,都是使用Range类来创建的。
另一种方法是使用矩形,首先给出左上角的坐标,然后是矩形的大小。
后一种方法最常用,因为它最自然。同时,当在图片中检测物体时,你可以用该物体的包围框,它的类型是Rect对象。
值得注意的是,修改子矩阵会破坏原矩阵的效果。如果你想把子矩阵改成蓝色:
submat3_2.png和submat3_3.png都会变成如图1-16所示的蓝***咪脸。
图1-16 蓝***咪脸
同时原矩阵也会被变成如图1-17所示的样子!
图1-17 大图中的蓝***咪脸
这里想表达的观点是,无论在何时何地使用submat函数,一定要小心谨慎,通常情况下,它是一个强有力的图像处理工具。
- 点赞
- 收藏
- 关注作者
评论(0)