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圖像處理之獲取用戶感興趣的區域的文章就介紹到這瞭,更多相關Java獲取用戶感興趣區域內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 基於OpenCv與JVM實現加載保存圖像功能(JAVA 圖像處理)
- C#使用opencv截取旋轉矩形區域圖像的實現示例
- Java OpenCV圖像處理之自定義圖像濾波算子
- Java OpenCV圖像處理之SIFT角點檢測詳解
- java中lambda(函數式編程)一行解決foreach循環問題