zoukankan      html  css  js  c++  java
  • 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;
        }

           

  • 相关阅读:
    【锁】java 锁的技术内幕
    【BlockingQueue】BlockingQueue 阻塞队列实现
    【多线程】获取多个线程任务执行完事件
    【spring cloud】源码分析(一)
    【spring boot】FilterRegistrationBean介绍
    【FAQ】服务下线
    解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)...
    实现人民币大写代码解析
    application.yml使用@符合问题:'@' that cannot start any token. (Do not use @ for indentation)
    Maven常见异常及解决方法---测试代码编译错误
  • 原文地址:https://www.cnblogs.com/heyus/p/13723544.html
Copyright © 2011-2022 走看看