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