OpenCV + Java(Android) 设置ROI
来源:互联网 发布:js自定义回调函数 编辑:程序博客网 时间:2024/06/05 06:37
在处理图像时, 我们经常需要提取图片中的重要部分进行分析,滤除不重要的噪声背景。通常的操作是设置感兴趣区域(Region of Interest, ROI),然后分割图片。由于操作对象形状的不同,ROI也会具有不同的形状。从简单的矩形,到稍复杂的圆形、椭圆,以及更为复杂的不规则形状。网上有很多关于C++版本的OpenCV设置ROI的博文,但是Java语言版的颇少,本文就着重介绍一下在Java或者Android环境下如何对图像设置ROI。
1. 矩形ROI设置
矩形的ROI设置比较简单,可以直接利用Mat类的构造函数提取一块矩形区域。代码中MatView.openFile()与MatView.imshow()是我自己写的方法,Java平台上的OpenCV并没有提供显示图片imshow()函数。方法体内容可参考我的另一篇博文:绘制灰度直方图(OpenCV + Java)
Mat imgOrigin = new Mat();try { imgOrigin = MatView.openFile("picture/clock.jpg"); // 读取一张图片 } catch (Exception e) { e.printStackTrace();}MatView.imshow(imgOrigin, "Original Image"); // 在JFrame中显示读取的图片Rect rect = new Rect(30, 120, 340, 350); // 设置矩形ROI的位置Mat imgRectROI= new Mat(imgOrigin, rect); // 从原图中截取图片MatView.imshow(imgRectROI, "Rectangle ROI"); // 显示截取后的图片
2. 圆形ROI设置
圆形ROI的设置需要用到mask掩膜。首先新建一个大小和原图一样的mask,得到原图感兴趣区域的轮廓并在mask相同的地方画出,这一步可以通过Canny等边缘检测算子实现。然后利用漫水填充法将mask中闭合区域填充为自己设置的颜色(这里我们选择填充为白色)。最后可以通过copyto()方法,结合自己创建的mask将ROI区域提取出来。
漫水填充法floodFill()的详细讲解可以参考博文:【OpenCV入门教程之十五】水漫金山:OpenCV漫水填充算法(Floodfill)。需要注意的是,C++环境中提供了两个版本的floodFill()函数,第一个版本没有mask形参,第二个版本带有mask形参。然而,在Java环境中此方法都要设置mask形参,而且floodFill的mask的width和height都必须比输入图像大至少两个像素,否则程序会报错。floodFill和copyto都有mask,注意区分。由于floodFill必须要有mask形参,所以要创建一个尺寸较大的mask,而我们真正想要的是copyTo()方法的mask。
Mat maskCopyTo = Mat.zeros(imgOrigin.size(), CV_8UC1); // 创建copyTo方法的mask,大小与原图保持一致Mat maskFill = Mat.zeros(new Size(imgOrigin.cols() + 2, imgOrigin.rows() + 2), CV_8UC1); // 创建floodFill方法的mask,尺寸比原图大一些Imgproc.circle(maskCopyTo, new Point(207, 290), 165, Scalar.all(255), 2, 8, 0); // 画出圆的轮廓Imgproc.floodFill(maskCopyTo, maskFloodFill, new Point(207, 290), Scalar.all(255), null, Scalar.all(20), Scalar.all(20), 4 ); // 漫水填充法填充圆的内部MatView.imshow(maskFloodFill, "Mask of floodFill"); // 画出copyTo方法的maskMatView.imshow(maskCopyTo, "Mask of copyTo"); // 画出floodFill方法的maskMat imgCircularROI = new Mat();imgOrigin.copyTo(imgCircularROI, maskCopyTo); // 提取圆形的ROIMatView.imshow(imgCircularROI, "Circular ROI"); // 显示圆形的ROI
mask的逻辑是:mask某个位置为0,此位置上的操作不起作用;某个位置如果不为0,在此位置上的操作起作用。
在创建maskCopyTo与maskFloodFill 两个掩膜时,最好要初始化为0,不能简单的new Mat()。new出的mask可能会包涵非零像素点,这些像素点在提取ROI时会起作用,从而导致存在一些噪声。
3. 不规则形状ROI设置
不规则形状的ROI设置基本思想与圆形ROI一致。首先需要得到一张轮廓掩膜图(Canny或者findCounters等方法),然后通过漫水填充等方法生成mask,最后利用copyTo方法提取。
Mat maskCopyTo2 = Mat.zeros(imgOrigin.size(), CV_8UC1); // 创建copyTo方法的mask,大小与原图保持一致List<MatOfPoint> counter = new ArrayList<>();counter.add(new MatOfPoint(new Point(20, 230), new Point(200, 70) , new Point(380, 230), new Point(300, 460), new Point(90, 460), new Point(20, 230))); // 绘制一个不规则的多边形Imgproc.drawContours(maskCopyTo2, counter, -1, Scalar.all(255)); // 画出轮廓MatView.imshow(maskCopyTo2, "Irregular shape edge");Mat maskFloodFill2 = new Mat(imgOrigin.rows() + 2, imgOrigin.cols() + 2, CV_8UC1); // 创建floodFill方法的mask,尺寸比原图大一些Imgproc.floodFill(maskCopyTo2, maskFloodFill2, new Point(207, 290), Scalar.all(255), null, Scalar.all(20), Scalar.all(20), 4 ); // 漫水填充法填充内部MatView.imshow(maskFloodFill2, "Irregular shape:Mask of floodFill"); // 画出copyTo方法的maskMatView.imshow(maskCopyTo2, "Irregular shape:Mask of copyTo"); // 画出floodFill方法的maskMat imgIrregularROI = new Mat();imgOrigin.copyTo(imgIrregularROI, maskCopyTo2); // 提取不规则形状的ROIMatView.imshow(imgIrregularROI, "Irregular shape ROI");
附上代码的下载地址:http://download.csdn.net/detail/mengchicmc/9888844
- OpenCV + Java(Android) 设置ROI
- Android平台下使用OpenCV设置ROI
- opencv设置ROI
- opencv设置ROI
- OpenCV :ROI设置
- OpenCV中图像设置ROI
- 为什么通过设置ROI无法修改图像(opencv)
- OpenCV:设置图像的感兴趣区域(ROI)
- opencv中的ROI(感兴趣区域)的设置
- C/C++ OpenCV设置感兴趣区域ROI
- C/C++ OpenCV设置感兴趣区域ROI
- opencv roi
- opencv ROI
- opencv:ROI
- OPENCV不规则ROI-圆形ROI
- OpenCV中的ROI讨论(未完)
- OpenCV之感兴趣区域(ROI)
- opencv学习之感兴趣区域(ROI)
- RxJava2.0教程操作符
- scala入门及相关知识
- 【easyUI】datagrid使用分页时跳转到第一页
- Android中在string.xml中使用特殊字符
- 数据库(第一范式,第二范式,第三范式)
- OpenCV + Java(Android) 设置ROI
- 这几天遇到的es6新玩意儿
- 60. Permutation Sequence(C++)
- Android RecyclerView+StaggeredGridLayoutManager实现瀑布流图片闪烁问题
- DroidPlugin开源插件研究资料整理
- Ubuntu16.04/16.10下Tensorflow demo在Android上的移植
- zxing乱码解决
- Arduino+ESP8266WIFI(1)——模块测试
- DM8168 + Linux RS485控制