当前位置 : 主页 > 编程语言 > java >

你会用Java抠图吗?【图像处理】获取用户感兴趣的区域

来源:互联网 收集:自由互联 发布时间:2022-09-29
openCV根据图片生成mask掩膜,再根据mask生成ROI图片 需求背景 获取ROI图片:现在有一张图片,用户能够在坐标上选择一些点组成一个区域,这个区域称为用户感兴趣的区域,需要利用ma

openCV根据图片生成mask掩膜,再根据mask生成ROI图片

需求背景

获取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区域的形状与大小直接决定了你看到最终图像的大小与形状。

你会用Java抠图吗?【图像处理】获取用户感兴趣的区域_java

可以看出,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(){
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);
}
}

效果如下

原图片:

你会用Java抠图吗?【图像处理】获取用户感兴趣的区域_desktop_02

mask图片:

你会用Java抠图吗?【图像处理】获取用户感兴趣的区域_scala_03

ROI图片:

你会用Java抠图吗?【图像处理】获取用户感兴趣的区域_desktop_04

工具类

方法声明

//方法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经典算法-day4
下一篇:没有了
网友评论