java opencv 检测缺口图片是否向左凸出来的

                                                     

 

 

 

如上4张图片,其中 2 3 是向左凸出来的。

图片处理,以上图2为例,  图片 -> 高斯模糊                  -> 图片灰度化处理            ->  边缘检测    ,没有二值化处理。

 

 

 

 最后的图片,在python下,显示的像素点

 

 

 

 

思路,统计每个 x 轴(因为我是检测图片是否向左凸出来)上,rgb 等于255的个数。假设图片是像左凸出来的,那么前几个(自定义)坐标上的统计值,一定是小于最大统计值的,这里定义小于 最大值的1/3。

 

简单代码如下:

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.springframework.util.CollectionUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

public class CheckLeftOut {

    public static void main(String[] args) {
        // 这个必须要写,不写报java.lang.UnsatisfiedLinkError
        System.load("D:\\java_project\\common\\lib\\opencv_java440_x64.dll"); //绝对路径

        String name = "1600853293536";   //1600853293536  1600852044392 判断小滑块是否左凸出来 {11=3, 12=9, 13=6, 14=4, 15=4, 16=4, 17=2, 18=4, 19=2, 20=2} {11=6, 12=6, 13=6, 14=4, 15=4, 16=4, 17=2, 18=4}
        String small = "C:\\generate_captcha\\" + name + ".png";

        System.out.println(imageOut(small));
    }

    public static boolean imageOut(String path) {
        // 这个必须要写,不写报java.lang.UnsatisfiedLinkError
        System.load("D:\\java_project\\common\\lib\\opencv_java440_x64.dll"); //绝对路径

        Mat src = imread(path);
        Mat result = Dis3.gaussianBlur(src);
        //Imgcodecs.imwrite("C:\\generate_captcha\\b1_1.png", result);

        result = gray(result);
        //Imgcodecs.imwrite("C:\\generate_captcha\\b1_2.png", result);

        //可以不需要
        //result = binary(result);
        //Imgcodecs.imwrite("C:\\generate_captcha\\b1_3.jpg", result);

        result = canny(result);
        //Imgcodecs.imwrite("C:\\generate_captcha\\b1_4.png", result);


        //System.out.println(getImageGRB("C:\\generate_captcha\\b1_4.png"));

        Map<Integer, Integer> map = getImageGRB(mat2InputStream(getExtensionName(path), result));
        if(CollectionUtils.isEmpty(map)) {
            return false;
        }

        return imageOut(map);
    }

    /**
     *
     * @param map, key 是横坐标,value 是横坐标像素点大于0的统计
     * 首先算出像素点最大的值,如果图片的缺口是凸出来的,前几个横坐标(前5个,自己定义)的统计值肯定是小于最大值(一般不超过1/3,自己定义)
     * @return
     */
    public static boolean imageOut(Map<Integer, Integer> map) {
        List<Integer> xList = new ArrayList<>(); //横坐标
        List<Integer> yList = new ArrayList<>(); //横坐标像素点大于0的统计

        map.forEach((k, v) -> {
            xList.add(k);
            yList.add(v);
        });

        int max = yList.stream().mapToInt(v -> v).max().orElse(0);
        max = max / 3;
        int size = xList.size() > 5 ? 5 : xList.size();

        for(int i = 0; i < size; i ++) {
            if(map.get(xList.get(i)) >= max) {
                return false;
            }
        }

        return true;
    }


    /***
     * 获取扩展名,不包含 .
     * @param file
     * @return
     */
    public static String getExtensionName(String file) {
        int index = file.lastIndexOf(".");
        return file.substring(index + ".".length(), file.length());
    }

    /***
     * @param extensionName:文件扩展名,不包含 .
     * @param mat
     * @return
     */
    public static InputStream mat2InputStream(String extensionName, Mat mat)
    {
        MatOfByte mob = new MatOfByte();
        Imgcodecs.imencode("." + extensionName, mat, mob);
        byte[] byteArray = mob.toArray();
        return new ByteArrayInputStream(byteArray);
    }

    /**
     * 返回 map, key 是横坐标,value 是横坐标像素点大于0的统计
     * @param inputStream
     * @return
     */
    public static Map<Integer, Integer> getImageGRB(InputStream inputStream) {
        Map<Integer, Integer> map = new LinkedHashMap<>();

        try {
            BufferedImage bufImg = ImageIO.read(inputStream);
            int height = bufImg.getHeight();
            int width = bufImg.getWidth();

            for (int i = 0; i < width; i++) {
                for (int j = 0; j < height; j++) {
                    //result[i][j] = bufImg.getRGB(i, j) & 0xFFFFFF;
                    //System.out.println(bufImg.getRGB(i, j) );
                    /*if(bufImg.getRGB(i, j) > 0) {
                        System.out.println(i + "," + j);
                    }*/

                    int pixel = bufImg.getRGB(i, j); // 下面三行代码将一个数字转换为RGB数字

                    int a = (pixel & 0xff0000) >> 16;
                    int b = (pixel & 0xff00) >> 8;
                    int c = (pixel & 0xff);

                    if (a == 255 || b == 255 || c == 255) {
                        //System.out.println("i=" + i + ",j=" + j + ":(" + a + "," + b + "," + c + ")");
                        map.put(i, map.get(i) == null ? 1 : map.get(i) + 1);
                    }
                }
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // System.out.println(map);
        return map;
    }

    public static Map<Integer, Integer> getImageGRB(String filePath) {
        File file = new File(filePath);
        if(!file.exists()) {
            return null;
        }

        try {
            return getImageGRB(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }
}

 

   图片过滤方法

   /***
     * 高斯模糊处理
     * @param src
     * @return
     */
    public static Mat gaussianBlur(Mat src) {
        Mat dst = new Mat();
        //参数 3 会影响图片处理结果
        Imgproc.GaussianBlur(src, dst, new Size(3, 3), 0, 0, Core.BORDER_DEFAULT);
        // Imgcodecs.imwrite("c:\\b1_1.jpg", binary);
        return dst;
    }

    /**
     * 图片灰度化处理
     * @param src
     * @return
     */
    public static Mat gray(Mat src) {
        Mat dst = new Mat();
        Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);
        return dst;
    }

    /**
     * 图片 二值化
     * @param src
     * @return
     */
    public static Mat binary(Mat src) {
        Mat dst = new Mat();
        Imgproc.threshold(src, dst, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU); //一般
     
        return dst;
    }

    /**
     * 边缘检测
     * @param src
     * @return
     */
    public static Mat canny(Mat src) {
        Mat dst = new Mat();
        // 这里 200 300 会影响结果
        Imgproc.Canny(src, dst, 200, 300);
        return dst;
    }

 

       

 

posted @ 2020-09-24 12:43  safetys  阅读(568)  评论(0编辑  收藏  举报