欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java图像处理之获取用户感兴趣的区域,

来源: javaer 分享于  点击 36528 次 点评:155

Java图像处理之获取用户感兴趣的区域,


目录
  • 需求背景
  • 概念解释
    • ROI
    • openCV
    • 掩膜mask
  • 代码实现
    • 效果如下
  • 工具类

    需求背景

    获取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图像处理之获取用户感兴趣的区域的文章就介绍到这了,更多相关Java获取用户感兴趣区域内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

    您可能感兴趣的文章:
    • 使用Java进行图像处理的一些基础操作
    • Java OpenCV图像处理之背景切换
    • Java OpenCV图像处理之背景消除
    • Java数字图像处理之图像灰度处理
    • Java实现抠图片文字或签名的完整代码
    相关栏目:

    用户点评