Java图像处理之获取用户感兴趣的区域怎么实现
本篇内容介绍了“Java图像处理之获取用户感兴趣的区域怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
需求背景
获取ROI图片:现在有一张图片,用户能够在坐标上选择一些点组成一个区域,这个区域称为用户感兴趣的区域,需要利用mask掩膜生成,需要生成mask图片、ROI图片,要求使用OpenCV+Java实现。
概念解释
ROI
ROI: region of interest 感兴趣的区域
openCV
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法。
掩膜mask
什么是图像处理中的mask(遮罩),OpenCV中是如此定义Mask的:八位单通道的Mat对象,每个像素点值为零或者非零区域。当Mask对象添加到图像区上时,只有非零的区域是可见,Mask中所有像素值为零与图像重叠的区域就会不可见,也就是说Mask区域的形状与大小直接决定了你看到最终图像的大小与形状。
可以看出,mask的作用是可以帮助我们提取各种不规则的区域。
代码实现
import org.opencv.core.*; import org.opencv.core.Point; import org.opencv.imgproc.Imgproc; import java.util.ArrayList; import java.util.List; public class MyTest{ /** * demo:根据原图片生成mask,再根据mask生成ROI图片 */ @Test public void testCreateROI() throws IOException { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); Mat img = Imgcodecs.imread("C:\\Users\\Administrator\\Desktop\\20220720141206.jpg"); //定义mask的区域边界点 List<Point> list = new ArrayList<>(); list.add(new Point(600, 50)); list.add(new Point(400, 500)); list.add(new Point(1000, 550)); list.add(new Point(1200, 50)); // list.add(new Point(0,0)); // list.add(new Point(1296,0)); // list.add(new Point(1296,960)); // list.add(new Point(0,960)); // 构建掩膜mask List<MatOfPoint> maskArea = new ArrayList<>(); MatOfPoint maskPoints = new MatOfPoint(); maskPoints.fromList(list); maskArea.add(maskPoints); Mat mask; mask = new Mat(new Size(img.width(), img.height()), CvType.CV_8UC3, new Scalar(0, 0, 0));//定义成黑色 Imgproc.fillPoly(mask, maskArea, new Scalar(255, 255, 255));//填充多边形,生成mask,定义成白色 // 保存mask图片 Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\mask.tiff", mask); //根据mask将原图片img复制生成ROI图片dist Mat dist = new Mat(new Size(img.width(), img.height()), CvType.CV_8UC3, new Scalar(0, 0, 0)); img.copyTo(dist, mask); Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\dist.tiff", dist); } }
效果如下
原图片:
mask图片:
ROI图片:
工具类
方法声明
//方法1:生成mask public static Mat create(int width, int height, String filePath, List<PointParam> points); //方法2:根据mask生成ROI图片 public static void solve(Mat mask, String strFrom, String strTo);
ImageSolveByOpenCV 类
package com.example.phenocam.test; import lombok.extern.slf4j.Slf4j; import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import java.util.ArrayList; import java.util.List; /** * 通过 OpenCV 创建一张mask,根据mask生成ROI图片 */ @Slf4j public class ImageSolveByOpenCV { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } /** * 创建一个掩膜 * @param width: 图片的宽度 * @param height: 图片的高度 * @param filePath: 文件保存的路径 * @param points: 轮廓的顶点 * @return mask图片的mat格式 */ public static Mat create(int width, int height, String filePath, List<PointParam> points) { // 对输入的点进行预处理 List<org.opencv.core.Point> list = new ArrayList<>(); for (PointParam p : points) { list.add(new org.opencv.core.Point(p.getX(), p.getY())); } // 创建掩膜区域 List<MatOfPoint> maskArea = new ArrayList<>(); MatOfPoint maskPoints = new MatOfPoint(); maskPoints.fromList(list); maskArea.add(maskPoints); // 构建掩膜 Mat mask = new Mat(new Size(width, height), CvType.CV_8UC3, new Scalar(0, 0, 0)); Imgproc.fillPoly(mask, maskArea, new Scalar(255, 255, 255)); // 保存mask图片 Imgcodecs.imwrite(filePath,mask); log.info("mask图片:{}生成成功",filePath); return mask; } /** * 根据mask生成图片 Mat格式 * @param mask * @param strFrom * @param strTo */ public static void solve(Mat mask, String strFrom, String strTo){ int width = mask.width(); int height = mask.height(); Mat image = Imgcodecs.imread(strFrom); Mat dist = new Mat(new Size(width, height), CvType.CV_8UC3, new Scalar(0, 0, 0)); image.copyTo(dist,mask); Imgcodecs.imwrite(strTo,dist); log.info("_ROI图片:"+strTo+"生成成功"); } public static void main(String[] args) { long start = System.currentTimeMillis(); System.loadLibrary(Core.NATIVE_LIBRARY_NAME); String strFrom="C:\\Users\\Administrator\\Desktop\\20220720141206.jpg";//原图片路径 String strTo="C:\\Users\\Administrator\\Desktop\\dest.jpg";//ROI图片路径(待生成) String maskPath = "C:\\Users\\Administrator\\Desktop\\mask.jpg";//mask的保存路径(待生成) Mat source = Imgcodecs.imread(strFrom);//读入图片的mat格式 //处理边界点 List<PointParam> points = new ArrayList<>(); points.add(new PointParam(50.0, 50.0)); points.add(new PointParam(700.0, 50.0)); points.add(new PointParam(700.0, 700.0)); points.add(new PointParam(50.0, 700.0)); //=========================1.根据参数生成mask============================ Mat mask = ImageSolveByOpenCV.create(source.width(), source.height(), maskPath, points);//生成的mask System.out.println("opencv生成mask花费: " + (System.currentTimeMillis() - start) + "ms"); start=System.currentTimeMillis();//重置时间 //=========================2.根据mask生成ROI效果图============================ ImageSolveByOpenCV.solve(mask, strFrom, strTo); System.out.println("opencv生成mask花费: " + (System.currentTimeMillis() - start) + "ms"); } }
PointParam
@Data @AllArgsConstructor public class PointParam { Double x; Double y; }
“Java图像处理之获取用户感兴趣的区域怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注蜗牛博客网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。版权声明:如无特殊标注,文章均为本站原创,转载时请以链接形式注明文章出处。
评论