1,去官网下载opencv,下载的时候需要注册一个 Oracle 账户,分分钟就能注册。然后安装。我下的是4.7的。
2,找到jar包放进项目里
3,项目结构,比较简单
4,把下载的文件放进C盘
5,主类代码
import org.opencv.core.Core;/*** @author lake* @date 2023/6/26*/ public class TestMain {static {//在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}public static void main(String[] args) {String imagePath1 = "C:\\Users\\lake45\\Desktop\\yuan.jpg";String imagePath2 = "C:\\Users\\lake45\\Desktop\\fuben.jpg";ImageCompare imageCompare = new ImageCompare();imageCompare.CompareAndMarkDiff(imagePath1, imagePath2);}}
6,工具类
import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.utils.Converters;import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; import java.util.List;/*** @author lake* @date 2023/6/26*/ public class ImageCompare {private boolean compareResult = false;private String mark = "_compareResult";/*** 比较两张图片,如不同则将不同处标记并输出到新的图片中** @param imagePath1 图片1的路径* @param imagePath2 图片2的路径*/public void CompareAndMarkDiff(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;}if (mat1.cols() != mat2.cols() || mat1.rows() != mat2.rows()) {System.out.println("两张图片大小不同,无法比较");return;}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;}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());for (MatOfPoint matOfPoint : mat2_list) {Rect rect = Imgproc.boundingRect(matOfPoint);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);}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 + ".");//图片一的带标记的输出文件;writeImage(mat_result1, targetPath1);//图片二的带标记的输出文件;writeImage(mat_result2, targetPath2);}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;}}
7,效果图。如果是一张彩色和一张黑白的图片,效果就不太理想了。
资源文件地址,我设置了0积分下载:
https://download.csdn.net/download/qq_30299243/87950327?spm=1001.2014.3001.5503