基于Opencv和Java识别图片中的黑色矩形

基于Opencv和Java识别图片中的黑色矩形

思路:

  • 二值化,将纯黑的保留,其他颜色转为白色
  • 去噪,将散乱的黑点去掉,
  • 求边缘轮廓,求出最大的边缘
  • 从最大边缘中求出最小的 x,最小的y,最大的x,最大的y.(不规则图形就去它的外接矩形)

1.官网下载Opencv

2.在eclipse中添加jar包

3.在jvm中添加参数,-Djava.library.path=C:\Java\opencv\build\java\x64(path后的路径是opecv中一个dll路径的目录,可以参照我的目录去寻找)

全文代码:

package com.ebupt.ringtone_video_hub.create_video.taskv2.render;

import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.javatuples.Quartet;
import org.junit.Test;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class FindBlackArea {
    Quartet<Integer, Integer, Integer, Integer> quartet;

    public Quartet<Integer, Integer, Integer, Integer> find(BufferedImage image){
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);//加载本地dll文件
       // Mat originalMat= Imgcodecs.imread(inputPath,Imgcodecs.IMREAD_GRAYSCALE);//加载图片时灰度处理
        Mat originalMat=BufImg2Mat(image,image.getType(), CvType.CV_8UC3);
        Imgproc.threshold(originalMat, originalMat, 0, 255,Imgproc.THRESH_BINARY);//二值化
        Mat dst = originalMat.clone();
        Imgproc.medianBlur(originalMat, dst, 7);//去除噪点
        List contours=find_contours(dst);
        return  calculate(contours);
    }

    public List find_contours(Mat img) {
        Imgproc.threshold(img, img, 0, 255, Imgproc.THRESH_BINARY);
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Mat firstMat = new Mat();
        Imgproc.findContours(img, contours, firstMat, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
        return contours;
    }

    public Quartet<Integer, Integer, Integer, Integer>calculate(List<MatOfPoint> contours){
        int maxSizeIndex=-1;
        int maxSize=Integer.MIN_VALUE;
        //找出轮廓面积最大的轮廓
        for(int i=0;i<contours.size();i++){
            Mat mat=(MatOfPoint)contours.get(i);
            int size=mat.width()*mat.height();
            if(size>maxSize){
                maxSize=size;
                maxSizeIndex=i;
            }
        }
        if(maxSizeIndex!=-1){
            String dump=contours.get(maxSizeIndex).dump();
            return stringToArray(dump);
        }
        return  null;
    }

    public Quartet<Integer, Integer, Integer, Integer>  stringToArray(String dump){
        int minX=Integer.MAX_VALUE;
        int minY=Integer.MAX_VALUE;
        int maxX=Integer.MIN_VALUE;
        int maxY=Integer.MIN_VALUE;
        dump=dump.substring(1, dump.length()-1);
        String[] stringArray=dump.split(";");
        for(String s:stringArray) {
            String[] l=s.split(",");
            int x=Integer.valueOf(l[0].trim());
            int y=Integer.valueOf(l[1].trim());
            minX=Math.min(x, minX);
            maxX=Math.max(x,maxX);
            minY=Math.min(y,minY);
            maxY=Math.max(y, maxY);
        }
        System.out.println(" x1 "+minX+" y1:"+minY);
        System.out.println(" x2 "+maxX+" y2:"+maxY);
        int width=maxX-minX;
        int height=maxY-minY;
        System.out.println(" width"+width+" height:"+height);
        quartet=new Quartet<>(minX,minY,width,height);
        return quartet;
    }

    public  Mat BufImg2Mat (BufferedImage original, int imgType, int matType) {
        if (original == null) {
            throw new IllegalArgumentException("original == null");
        }
        // Don't convert if it already has correct type
        if (original.getType() != imgType) {
            // Create a buffered image
            BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);
            // Draw the image onto the new buffer
            Graphics2D g = image.createGraphics();
            try {
                g.setComposite(AlphaComposite.Src);
                g.drawImage(original, 0, 0, null);
            } finally {
                g.dispose();
            }
        }

        byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();
        Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType);
        mat.put(0, 0, pixels);
        Mat sc=new Mat();
        Imgproc.cvtColor(mat, sc, Imgproc.COLOR_BGR2GRAY);
        return sc;
    }

    @Test
    public void test(){
        String inputpathString="C:\\Users\\86130\\Desktop\\pictures\\2019-12-30-17-41.jpg";
        try {
            BufferedImage image= ImageIO.read(new File(inputpathString));
            find(image);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }






}

posted @ 2020-01-02 10:05  李成洪  阅读(2870)  评论(0编辑  收藏  举报