Java圖像處理之獲取用戶感興趣的區(qū)域
需求背景
獲取ROI圖片:現(xiàn)在有一張圖片,用戶能夠在坐標上選擇一些點組成一個區(qū)域,這個區(qū)域稱為用戶感興趣的區(qū)域,需要利用mask掩膜生成,需要生成mask圖片、ROI圖片,要求使用OpenCV+Java實現(xiàn)。
概念解釋
ROI
ROI: region of interest 感興趣的區(qū)域
openCV
OpenCV(Open Source Computer Vision Library)是一個開源的計算機視覺庫,它提供了很多函數(shù),這些函數(shù)非常高效地實現(xiàn)了計算機視覺算法。
掩膜mask
什么是圖像處理中的mask(遮罩),OpenCV中是如此定義Mask的:八位單通道的Mat對象,每個像素點值為零或者非零區(qū)域。當Mask對象添加到圖像區(qū)上時,只有非零的區(qū)域是可見,Mask中所有像素值為零與圖像重疊的區(qū)域就會不可見,也就是說Mask區(qū)域的形狀與大小直接決定了你看到最終圖像的大小與形狀。
可以看出,mask的作用是可以幫助我們提取各種不規(guī)則的區(qū)域。
代碼實現(xiàn)
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:根據(jù)原圖片生成mask,再根據(jù)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的區(qū)域邊界點 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); //根據(jù)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:根據(jù)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 創(chuàng)建一張mask,根據(jù)mask生成ROI圖片 */ @Slf4j public class ImageSolveByOpenCV { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } /** * 創(chuàng)建一個掩膜 * @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())); } // 創(chuàng)建掩膜區(qū)域 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; } /** * 根據(jù)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.根據(jù)參數(shù)生成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.根據(jù)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圖像處理之獲取用戶感興趣的區(qū)域的文章就介紹到這了,更多相關Java獲取用戶感興趣區(qū)域內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中wait與sleep的區(qū)別講解(wait有參及無參區(qū)別)
這篇文章主要介紹了Java中wait與sleep的講解(wait有參及無參區(qū)別),通過代碼介紹了wait()?與wait(?long?timeout?)?區(qū)別,wait(0)?與?sleep(0)區(qū)別,需要的朋友可以參考下2022-04-04Android應用開發(fā)之將SQLite和APK一起打包的方法
這篇文章主要介紹了Android應用開發(fā)之將SQLite和APK一起打包的方法,文章時間較早,盡管現(xiàn)在開發(fā)環(huán)境已大都遷移至Android Studio上,但打包原理依然相同,需要的朋友可以參考下2015-08-08詳解Java多線程編程中CountDownLatch阻塞線程的方法
在Java中和ReadWriteLock.ReadLock一樣,CountDownLatch的本質也是一個"共享鎖",這里我們就來詳解Java多線程編程中CountDownLatch阻塞線程的方法:2016-07-07springboot+mybatis plus實現(xiàn)樹形結構查詢
實際開發(fā)過程中經(jīng)常需要查詢節(jié)點樹,根據(jù)指定節(jié)點獲取子節(jié)點列表,本文主要介紹了springboot+mybatis plus實現(xiàn)樹形結構查詢,感興趣的可以了解一下2021-07-07JDBC連接MySql數(shù)據(jù)庫步驟 以及查詢、插入、刪除、更新等
這篇文章主要介紹了JDBC連接MySql數(shù)據(jù)庫步驟,以及查詢、插入、刪除、更新等十一個處理數(shù)據(jù)庫信息的功能,需要的朋友可以參考下2018-05-05SpringMVC中使用@PathVariable綁定路由中的數(shù)組的方法
這篇文章主要介紹了SpringMVC中使用@PathVariable綁定路由中的數(shù)組的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07