绘制灰度直方图(OpenCV + Java)

来源:互联网 发布:java字符串相等的判断 编辑:程序博客网 时间:2024/05/17 07:21

本文介绍一下如何使用Java语言绘制灰度图的直方图。由于Java环境下OpenCV不提供Mat图像的显示方法,如imshow(),因此需要使用SWing组件自己编写显示方法。同时,OpenCV的Jar包也并没有提供相关的抽象数据类型和方法,比如CvHistogram等。

灰度直方图是灰度级的函数,描述图像中该灰度级的像素个数(或该灰度级像素出现的频率):其横坐标是灰度级,纵坐标表示图像中该灰度级出现的个数(频率)。下面的方法是绘制一张灰度图的直方图:

    /**     * Plot histogram of a single channel grayscale image     *     * @param img a single channel grayscale image     */    public static void plotGrayHistogram(Mat img) {        java.util.List<Mat> images = new ArrayList<>();        images.add(img);         MatOfInt channels = new MatOfInt(0); // 图像通道数,0表示只有一个通道         MatOfInt histSize = new MatOfInt(256); // CV_8U类型的图片范围是0~255,共有256个灰度级        Mat histogramOfGray = new Mat(); // 输出直方图结果,共有256行,行数的相当于对应灰度值,每一行的值相当于该灰度值所占比例        MatOfFloat histRange = new MatOfFloat(0, 255);        Imgproc.calcHist(images, channels, new Mat(), histogramOfGray, histSize, histRange, false);  // 计算直方图         // 按行归一化        Core.normalize(histogramOfGray, histogramOfGray, 0, histogramOfGray.rows(), Core.NORM_MINMAX, -1, new Mat());        // 创建画布        int histImgRows = 300;        int histImgCols = 300;        int colStep = (int) Math.floor(histImgCols / histSize.get(0, 0)[0]);        Mat histImg = new Mat(histImgRows, histImgCols, CvType.CV_8UC3, new Scalar(255,255,255));  // 重新建一张图片,绘制直方图        for (int i = 0; i < histSize.get(0, 0)[0]; i++) {  // 画出每一个灰度级分量的比例,注意OpenCV将Mat最左上角的点作为坐标原点            Imgproc.line(histImg,                    new org.opencv.core.Point(colStep * i, histImgRows - 20),                    new org.opencv.core.Point(colStep * i, histImgRows - Math.round(histogramOfGray.get(i, 0)[0]) - 20),                    new Scalar(0, 0,0), 2,8,0);              if (i%50 == 0) {                 Imgproc.putText(histImg, Integer.toString(i), new org.opencv.core.Point(colStep * i, histImgRows - 5), 1, 1, new Scalar(0, 0, 0));  // 附上x轴刻度            }        }        MatView.imshow(histImg, "Gray Histogram");    }

下面的方法是在Java环境下显示一张Mat图像:

     /**     * Display Mat image     *     * @param image     * @param windowName     */    public static void imshow(Mat image, String windowName){       try {            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (UnsupportedLookAndFeelException e) {            e.printStackTrace();        }        JFrame jFrame = new JFrame(windowName);        JLabel imageView = new JLabel();        final JScrollPane imageScrollPane = new JScrollPane(imageView);        imageScrollPane.setPreferredSize(new Dimension(500, 500));  // set window size        jFrame.add(imageScrollPane, BorderLayout.CENTER);        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);        Image loadedImage = Mat2BufferedImage(image);        imageView.setIcon(new ImageIcon(loadedImage));        jFrame.pack();        jFrame.setLocationRelativeTo(null);        jFrame.setVisible(true);    }

下图分别是测试原图图与其对应的灰度图和直方图:
这里写图片描述

这里写图片描述这里写图片描述

原创粉丝点击