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;
        }

           

  • 相关阅读:
    Atitit fms Strait (海峡) lst 数据列表目录1. 4大洋 12. 著名的海大约40个,总共约55个海 13. 海区列表 23.1. 、波利尼西亚(Polynesia,
    Atitit trave islands list 旅游资源列表岛屿目录1. 东南亚著名的旅游岛屿 21.1. Cjkv 日韩 冲绳 琉球 济州岛 北海道 21.2. 中国 涠洲岛 南澳
    Atitit Major island groups and archipelagos 主要的岛群和群岛目录资料目录1. 岛群 波利尼西亚(Polynesia, 美拉尼西亚(Melanesia,
    Atitit glb 3tie city lst 三线城市列表 数据目录1. 全球范围内约90个城市 三线 12. 世界性三线城市全球共
    Atitit glb 1tie 2tie city lst 一二线城市列表数据约50个一线城市Alpha ++ 阿尔法++,,London 伦敦,,New York 纽约,,Alpha +
    Attit 现代编程语言重要特性目录第一章 类型系统 基本三大类型 2第一节 字符串 数字 bool 2第二节 推断局部变量 2第三节 动态类型 2第二章 可读性与开发效率 简单性 2
    Atitit 未来数据库新特性展望目录1. 统一的翻页 21.1. 2 Easy Top-N
    使用Chrome DevTools(console ande elements panel)进行xpath/css/js定位
    chrome -console妙用之定位xpath/js/css
    表达式树之构建Lambda表达式
  • 原文地址:https://www.cnblogs.com/heyus/p/13723544.html
Copyright © 2011-2022 走看看