|
@@ -1,297 +0,0 @@
|
|
|
-package com.management.platform.util;
|
|
|
-
|
|
|
-import java.awt.HeadlessException;
|
|
|
-import java.awt.image.BufferedImage;
|
|
|
-import java.io.ByteArrayInputStream;
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileInputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.io.UnsupportedEncodingException;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-import javax.imageio.ImageIO;
|
|
|
-
|
|
|
-import org.opencv.core.*;
|
|
|
-import org.opencv.imgcodecs.Imgcodecs;
|
|
|
-import org.opencv.imgproc.Imgproc;
|
|
|
-import org.opencv.utils.Converters;
|
|
|
-
|
|
|
-public class ImageCompare {
|
|
|
- static {
|
|
|
- System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
|
|
- //注意程序运行的时候需要在VM option添加该行 指明opencv的dll文件所在路径
|
|
|
- //-Djava.library.path=$PROJECT_DIR$\opencv\x64
|
|
|
- }
|
|
|
- private boolean compareResult = false;
|
|
|
- private String mark = "_compareResult";
|
|
|
- /**
|
|
|
- * 通过两张图对比,判断是否是游戏电影类型
|
|
|
- * @param imagePath1 图片1的路径
|
|
|
- * @param imagePath2 图片2的路径
|
|
|
- */
|
|
|
- public boolean isMoviePlay(String imagePath1, String imagePath2)
|
|
|
- {
|
|
|
- Mat mat1 = readMat(imagePath1);
|
|
|
- Mat mat2 = readMat(imagePath2);
|
|
|
- mat1 = Imgcodecs.imdecode(mat1, Imgcodecs.IMREAD_UNCHANGED);
|
|
|
- mat2 = Imgcodecs.imdecode(mat2, Imgcodecs.IMREAD_UNCHANGED);
|
|
|
- if(mat1.cols() == 0 || mat2.cols() == 0 || mat1.rows() == 0 || mat2.rows() == 0)
|
|
|
- {
|
|
|
- System.out.println("图片文件路径异常,获取的图片大小为0,无法读取");
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(mat1.cols() != mat2.cols() || mat1.rows() != mat2.rows())
|
|
|
- {
|
|
|
- System.out.println("两张图片大小不同,无法比较");
|
|
|
- return false;
|
|
|
- }
|
|
|
- mat1.convertTo(mat1, CvType.CV_8UC1);
|
|
|
- mat2.convertTo(mat2, CvType.CV_8UC1);
|
|
|
- Mat mat1_gray = new Mat();
|
|
|
- Imgproc.cvtColor(mat1, mat1_gray, Imgproc.COLOR_BGR2GRAY);
|
|
|
- Mat mat2_gray = new Mat();
|
|
|
- Imgproc.cvtColor(mat2, mat2_gray, Imgproc.COLOR_BGR2GRAY);
|
|
|
- mat1_gray.convertTo(mat1_gray, CvType.CV_32F);
|
|
|
- mat2_gray.convertTo(mat2_gray, CvType.CV_32F);
|
|
|
- double result = Imgproc.compareHist(mat1_gray, mat2_gray, Imgproc.CV_COMP_CORREL);
|
|
|
- if(result == 1)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-// System.out.println("相似度数值为:"+result);
|
|
|
- Mat mat_result = new Mat();
|
|
|
- //计算两个灰度图的绝对差值,并输出到一个Mat对象中
|
|
|
- Core.absdiff(mat1_gray, mat2_gray, mat_result);
|
|
|
- //将灰度图按照阈值进行绝对值化
|
|
|
- mat_result.convertTo(mat_result, CvType.CV_8UC1);
|
|
|
- List<MatOfPoint> mat2_list = new ArrayList<MatOfPoint>();
|
|
|
- Mat mat2_hi = new Mat();
|
|
|
- //寻找轮廓图
|
|
|
- Imgproc.findContours(mat_result, mat2_list, mat2_hi, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
|
|
|
- Mat mat_result1 = mat1;
|
|
|
- Mat mat_result2 = mat2;
|
|
|
- //使用红色标记不同点
|
|
|
- System.out.println(mat2_list.size());
|
|
|
- List<Point> allPoints = new ArrayList<Point>();
|
|
|
- //按照目标区域的面积大小, 长宽不低于480*480
|
|
|
- Point leftTop = null;
|
|
|
- Point rightTop = null;
|
|
|
- Point leftBottom = null;
|
|
|
- Point rightBottom = null;
|
|
|
- for (MatOfPoint matOfPoint : mat2_list)
|
|
|
- {
|
|
|
- Rect rect = Imgproc.boundingRect(matOfPoint);
|
|
|
- if ((rect.width >= 640 && rect.height >= 480) || (rect.width >= 480 && rect.height >= 640)) {
|
|
|
-// System.out.println("位置==["+rect.x +","+ rect.y+"], 大小=" +rect.width+"x"+rect.height+", 包含点=" + matOfPoint.toList().size());
|
|
|
- Imgproc.rectangle(mat_result1, rect.tl(), rect.br(), new Scalar(0, 0, 255),2);
|
|
|
- Imgproc.rectangle(mat_result2, rect.tl(), rect.br(), new Scalar(0, 0, 255),2);
|
|
|
- allPoints = matOfPoint.toList();
|
|
|
- leftTop = new Point(rect.x, rect.y);
|
|
|
- rightTop = new Point(rect.x + rect.width -1, rect.y);
|
|
|
- leftBottom = new Point(rect.x, rect.y + rect.height -1);
|
|
|
- rightBottom = new Point(rect.x + rect.width -1, rect.y + rect.height -1);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- for (Point p : allPoints) {
|
|
|
- Imgproc.drawMarker(mat_result1, p, new Scalar(0, 255, 0),2);
|
|
|
- }
|
|
|
- //找到四个顶点
|
|
|
- System.out.println("allPoints size=="+allPoints.size());
|
|
|
- if (allPoints.size() == 0) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- System.out.println(leftTop);
|
|
|
- System.out.println(rightTop);
|
|
|
- System.out.println(leftBottom);
|
|
|
- System.out.println(rightBottom);
|
|
|
- //统计在矩形边上的点数量
|
|
|
- int hitCount = 0;
|
|
|
- for (Point p : allPoints) {
|
|
|
- if ((Math.abs(p.x - leftTop.x) <= 6 || Math.abs(p.y - leftTop.y) <= 6)
|
|
|
- || (Math.abs(p.x - rightBottom.x) <= 6 || Math.abs(p.y - rightBottom.y) <= 6)) {
|
|
|
- hitCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- System.out.println("hitCount="+hitCount+", percent="+(100*hitCount/allPoints.size())+"%");
|
|
|
- int percent = (100*hitCount/allPoints.size());
|
|
|
- //分析占比
|
|
|
- if (percent > 80) {
|
|
|
- return true;//
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void writeImage(Mat mat, String outPutFile)
|
|
|
- {
|
|
|
- MatOfByte matOfByte = new MatOfByte();
|
|
|
- Imgcodecs.imencode(".png", mat, matOfByte);
|
|
|
- byte[] byteArray = matOfByte.toArray();
|
|
|
- BufferedImage bufImage = null;
|
|
|
- try {
|
|
|
- InputStream in = new ByteArrayInputStream(byteArray);
|
|
|
- bufImage = ImageIO.read(in);
|
|
|
- ImageIO.write(bufImage, "png", new File(outPutFile));
|
|
|
- } catch (IOException | HeadlessException e)
|
|
|
- {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private String getFileName(String filePath)
|
|
|
- {
|
|
|
- File f = new File(filePath);
|
|
|
- return f.getName();
|
|
|
- }
|
|
|
-
|
|
|
- private String getParentDir(String filePath)
|
|
|
- {
|
|
|
- File f = new File(filePath);
|
|
|
- return f.getParent();
|
|
|
- }
|
|
|
-
|
|
|
- private Mat readMat(String filePath)
|
|
|
- {
|
|
|
- try {
|
|
|
- File file = new File(filePath);
|
|
|
- FileInputStream inputStream = new FileInputStream(filePath);
|
|
|
- byte[] byt = new byte[(int) file.length()];
|
|
|
- int read = inputStream.read(byt);
|
|
|
- List<Byte> bs = convert(byt);
|
|
|
- Mat mat1 = Converters.vector_char_to_Mat(bs);
|
|
|
- return mat1;
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- e.printStackTrace();
|
|
|
- } catch (IOException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- return new Mat();
|
|
|
- }
|
|
|
-
|
|
|
- private List<Byte> convert(byte[] byt)
|
|
|
- {
|
|
|
- List<Byte> bs = new ArrayList<Byte>();
|
|
|
- for (int i = 0; i < byt.length; i++)
|
|
|
- {
|
|
|
- bs.add(i, byt[i]);
|
|
|
- }
|
|
|
- return bs;
|
|
|
- }
|
|
|
-
|
|
|
- public boolean test(String imagePath1, String imagePath2)
|
|
|
- {
|
|
|
- Mat mat1 = readMat(imagePath1);
|
|
|
- Mat mat2 = readMat(imagePath2);
|
|
|
- mat1 = Imgcodecs.imdecode(mat1, Imgcodecs.IMREAD_UNCHANGED);
|
|
|
- mat2 = Imgcodecs.imdecode(mat2, Imgcodecs.IMREAD_UNCHANGED);
|
|
|
- /*Mat mat1 = Imgcodecs.imread(imagePath1, Imgcodecs.IMREAD_UNCHANGED);
|
|
|
- Mat mat2 = Imgcodecs.imread(imagePath2, Imgcodecs.IMREAD_UNCHANGED);*/
|
|
|
- if(mat1.cols() == 0 || mat2.cols() == 0 || mat1.rows() == 0 || mat2.rows() == 0)
|
|
|
- {
|
|
|
- System.out.println("图片文件路径异常,获取的图片大小为0,无法读取");
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(mat1.cols() != mat2.cols() || mat1.rows() != mat2.rows())
|
|
|
- {
|
|
|
- System.out.println("两张图片大小不同,无法比较");
|
|
|
- return false;
|
|
|
- }
|
|
|
- mat1.convertTo(mat1, CvType.CV_8UC1);
|
|
|
- mat2.convertTo(mat2, CvType.CV_8UC1);
|
|
|
- Mat mat1_gray = new Mat();
|
|
|
- Imgproc.cvtColor(mat1, mat1_gray, Imgproc.COLOR_BGR2GRAY);
|
|
|
- Mat mat2_gray = new Mat();
|
|
|
- Imgproc.cvtColor(mat2, mat2_gray, Imgproc.COLOR_BGR2GRAY);
|
|
|
- mat1_gray.convertTo(mat1_gray, CvType.CV_32F);
|
|
|
- mat2_gray.convertTo(mat2_gray, CvType.CV_32F);
|
|
|
- double result = Imgproc.compareHist(mat1_gray, mat2_gray, Imgproc.CV_COMP_CORREL);
|
|
|
- if(result == 1)
|
|
|
- {
|
|
|
- compareResult = true;//此处结果为1则为完全相同
|
|
|
- return false;
|
|
|
- }
|
|
|
- System.out.println("相似度数值为:"+result);
|
|
|
- Mat mat_result = new Mat();
|
|
|
- //计算两个灰度图的绝对差值,并输出到一个Mat对象中
|
|
|
- Core.absdiff(mat1_gray, mat2_gray, mat_result);
|
|
|
- //将灰度图按照阈值进行绝对值化
|
|
|
- mat_result.convertTo(mat_result, CvType.CV_8UC1);
|
|
|
- List<MatOfPoint> mat2_list = new ArrayList<MatOfPoint>();
|
|
|
- Mat mat2_hi = new Mat();
|
|
|
- //寻找轮廓图
|
|
|
- Imgproc.findContours(mat_result, mat2_list, mat2_hi, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
|
|
|
- Mat mat_result1 = mat1;
|
|
|
- Mat mat_result2 = mat2;
|
|
|
- //使用红色标记不同点
|
|
|
- System.out.println(mat2_list.size());
|
|
|
- List<Point> allPoints = new ArrayList<Point>();
|
|
|
- //按照目标区域的面积大小, 长宽不低于480*480
|
|
|
- Point leftTop = null;
|
|
|
- Point rightTop = null;
|
|
|
- Point leftBottom = null;
|
|
|
- Point rightBottom = null;
|
|
|
- for (MatOfPoint matOfPoint : mat2_list)
|
|
|
- {
|
|
|
- Rect rect = Imgproc.boundingRect(matOfPoint);
|
|
|
- if (rect.width >= 280 && rect.height >= 280) {
|
|
|
- System.out.println("位置==["+rect.x +","+ rect.y+"], 大小=" +rect.width+"x"+rect.height+", 包含点=" + matOfPoint.toList().size());
|
|
|
- Imgproc.rectangle(mat_result1, rect.tl(), rect.br(), new Scalar(0, 0, 255),2);
|
|
|
- Imgproc.rectangle(mat_result2, rect.tl(), rect.br(), new Scalar(0, 0, 255),2);
|
|
|
- allPoints = matOfPoint.toList();
|
|
|
- leftTop = new Point(rect.x, rect.y);
|
|
|
- rightTop = new Point(rect.x + rect.width -1, rect.y);
|
|
|
- leftBottom = new Point(rect.x, rect.y + rect.height -1);
|
|
|
- rightBottom = new Point(rect.x + rect.width -1, rect.y + rect.height -1);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- for (Point p : allPoints) {
|
|
|
- Imgproc.drawMarker(mat_result1, p, new Scalar(0, 255, 0),2);
|
|
|
- }
|
|
|
- String fileName1 = getFileName(imagePath1);
|
|
|
- String targetPath1 = getParentDir(imagePath2)+File.separator+fileName1.replace(".", mark+".");
|
|
|
- String fileName2 = getFileName(imagePath2);
|
|
|
- String targetPath2 = getParentDir(imagePath2)+File.separator+fileName2.replace(".", mark+".");
|
|
|
- System.out.println(targetPath1);
|
|
|
- System.out.println(targetPath2);
|
|
|
- writeImage(mat_result1, targetPath1);
|
|
|
- writeImage(mat_result2, targetPath2);
|
|
|
- //找到四个顶点
|
|
|
- System.out.println("allPoints size=="+allPoints.size());
|
|
|
- System.out.println(leftTop);
|
|
|
- System.out.println(rightTop);
|
|
|
- System.out.println(leftBottom);
|
|
|
- System.out.println(rightBottom);
|
|
|
- //检测其他点,是否都在矩形边上
|
|
|
- int hitCount = 0;
|
|
|
- for (Point p : allPoints) {
|
|
|
- if ((Math.abs(p.x - leftTop.x) <= 6 || Math.abs(p.y - leftTop.y) <= 6)
|
|
|
- || (Math.abs(p.x - rightBottom.x) <= 6 || Math.abs(p.y - rightBottom.y) <= 6)) {
|
|
|
- hitCount++;
|
|
|
- } else {
|
|
|
-// System.out.println("失效点:"+p.x + "," + p.y);
|
|
|
- }
|
|
|
- }
|
|
|
- System.out.println("hitCount="+hitCount+", percent="+(100*hitCount/allPoints.size())+"%");
|
|
|
- int percent = (100*hitCount/allPoints.size());
|
|
|
-
|
|
|
- if (percent > 80) {
|
|
|
- return true;//
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static void main(String[] args) {
|
|
|
- String img1 = "C:\\Users\\seya\\Desktop\\e.jpg";
|
|
|
- String img2 = "C:\\Users\\seya\\Desktop\\d.jpg";
|
|
|
- ImageCompare ip = new ImageCompare();
|
|
|
- System.out.println("是电影娱乐吗?"+ip.test(img1, img2));
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
-
|