Java应用OpenCV指南其四:OpenCV获取ROI区域、图像叠加

来源:互联网 发布:数据字典 样例 编辑:程序博客网 时间:2024/05/22 17:29

我们将在本篇文章了解OpenCV中感兴趣区域的获取方法,并进行简单的图象叠加操作。

一、 ROI区域选取
ROI(Region of Interest)区域,被称为感兴趣区域,这个区域是图像分析所关注的焦点。我们通过设置感兴趣区域来选择我们图象分析的焦点,使得需要处理的图象区域大大减小,不但可以大大缩短处理的时间,而且可以提高处理的精度。OpenCV中常用到各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。

首先放一张要处理的图
这里写图片描述

定义ROI区域有两种方法。
我们可以通过调用Rect方法定义ROI区域:

Rect area=new Rect(int col, int row, int width, int height);

这是一个矩形区域
Col代表起始像素的列坐标(x轴坐标,从0开始计数,左上角为(0,0))
Row代表起始像素的行坐标(y轴坐标)
Width代表ROI区域的总长度(横轴)
Height代表ROI区域的总高度(纵轴)

然后获取区域内的图象:

Mat img = new Mat(Mat orgimg, Rect area);

另外,我们还可以通过调用Range方法选择ROI区域:

Range area = new Range(int start, int end);

这两个参数代表x或y某一个方向上的起始位置和结束位置,单位是像素。

同样,再获取区域内图象:

Mat img = new Mat(Mat orgimg, Range area1, Range area2);

简单的介绍就到这里,现在让我们看一个演示的实例:

package opencv;import org.opencv.core.*;import org.opencv.imgcodecs.Imgcodecs;public class one {    static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);};  //用来调用OpenCV库文件,必须添加    public static void main(String args[]){        Mat anima = Imgcodecs.imread("F:/workspace/opencv/animation.jpg", Imgcodecs.IMREAD_UNCHANGED);  //获取原图        Range range = new Range(250, 800);        Rect rect = new Rect(804, 129, 874, 652);        Mat ROI = new Mat(anima, rect);        Mat ROI1 = new Mat(anima, range);        Imgcodecs.imwrite("F:/workspace/opencv/anima_1.jpg", ROI);        Imgcodecs.imwrite("F:/workspace/opencv/anima_2.jpg", ROI1);    }}

利用Rect函数截取的图象
这里写图片描述

利用Range函数截取的图象
这里写图片描述

二、 图象的线性混合
在学会截取ROI区域以后,我们来用选取的图片进行一些初级的图象处理,这里介绍一下利用addWeighted函数实现的线性混合:

void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);  

• 第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat。
• 第二个参数,alpha,表示第一个数组的权重或者说透明度。
• 第三个参数,src2,表示第二个数组,它必须要和第一个数组拥有相同的尺寸和通道数。
• 第四个参数,beta,表示第二个数组的权重。
• 第五个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数。
• 第六个参数,gamma,一个加到权重总和上的标量值。看下面的式子自然会理解。
• 第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。

这个函数基于下面的表达式:
dst = src1[I]*alpha+ src2[I]*beta + gamma;

dst即为混合后矩阵的输出值。其中的I,是多维数组元素的索引值。而且,在遇到多通道数组的时候,每个通道都需要独立地进行处理。另外需要注意的是,当输出数组的深度为CV_32S时,这个函数就不适用了,这时候就会内存溢出或者算出的结果压根不对。
下面让我们看一个利用上面截取的图片进行混合的实例:

package opencv;import org.opencv.core.*;import org.opencv.imgcodecs.Imgcodecs;public class one {    static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);};  //用来调用OpenCV库文件,必须添加    public static void main(String args[]){        Mat anima = Imgcodecs.imread("F:/workspace/opencv/animation.jpg", Imgcodecs.IMREAD_UNCHANGED);  //获取原图        Mat back = Imgcodecs.imread("F:/workspace/opencv/background.jpg", Imgcodecs.IMREAD_UNCHANGED);        Range r = new Range(250, 800);        Mat ROI1 = new Mat(anima, r);        Range r1 = new Range(300, 850);        Mat ROI3 = new Mat(back, r1);        Mat mix = new Mat();        double alpha = 0.75;  //设置的人物原图的权重(透明度)        double beta;        beta = 1.0-alpha;  //用来叠加的背景的权重Core.addWeighted(ROI1, alpha, ROI3, beta, 0, mix, -1);        Imgcodecs.imwrite("F:/workspace/opencv/anima_4.jpg", mix);    }}

之前截取的图片:
这里写图片描述

混合后的图片:
这里写图片描述

阅读全文
0 0
原创粉丝点击