OpenCV Java 二值(黑白)图像噪声滤波算法



OpenCV Java 二值(黑白)图像噪声滤波算法

在图像处理应用中,我们经常会遇到图像中的噪声点影响图像的分割和处理的情况,OpenCVJava示例不多,本文给出一个OpenCV + Java环境下的图像噪声滤波算法。

OpenCV版本:3.4

Java1.8

 

过滤黑白(二值)图像中的噪声点,可以指定过滤区域的大小。

算法说明:

  1. 输入待过滤图像(黑白二值)。

  2. 扩展图像(长、宽各增2),相当于在图像周围加了一圈以方便处理,减少许多的边界检测操作。

  3. 从第一个像素开始循环处理。

  4. 以指定像素为中心(同时需要考虑滤波区域的大小),提取指定区域的子图像。提取区域的大小为需过滤区域大小外加一个包围圈。

  5. 将所提取区域除外包围的中间部分赋值为0(黑色);

  6. 求子图像的均值(Core.mean());

  7. 如果均值不为0,则表示外包围有不为0的点(白色点),则不进行过滤。

  8. 如果均值为0,则表示外包围为一圈黑色点(0),则执行过滤(将原图像中间区域赋值为0)。

 

源码:

    // 图像滤波,去除噪声点

    /**

     * @param src - 输入的二值(黑白)图像,算法将直接修改输入图像,返回的结果也是本参数

     * @param size - 需要过滤的噪声块大小,默认为以size为大小的正方形块

     */

    public static void noiseFilter(Mat src, int size) {

        // 图像高、宽

        int rows = src.rows();

        int cols = src.cols();

        if(size < 1 || size > rows || size > cols || src.channels() != 1) {

            return;

        }

        // 扩展图像

        Mat rslt = Mat.zeros(rows+2, cols+2, CvType.CV_8UC1);

        // 拷贝原图到扩展图像

        Rect roi = new Rect(1, 1, cols, rows);

        Mat m = rslt.submat(roi);

        src.copyTo(m);

        // 滤波参数准备

        Mat mCheck = Mat.zeros(size+2, size+2, CvType.CV_8UC1);

        Mat mMask =  Mat.zeros(size, size, CvType.CV_8UC1);

        Rect roiCheck = new Rect(0, 0, size+2, size+2);

        Rect roiMask = new Rect(1, 1, size, size);

        Mat mRoiSrc, mRoiMask;

        Scalar mean;

        for(int i=1; i<=(rows-size+1); i++) {

            for(int j=1; j<=(cols-size+1); j++) {

                roiCheck.x = j-1;

                roiCheck.y = i-1;

                // 截取原图(实际是基于扩展后的图像操作)一部分执行检测

                mRoiSrc = rslt.submat(roiCheck);

                // 拷贝到检测对象以免操作影响到原图

                mRoiSrc.copyTo(mCheck);

                // 以黑点覆盖检测图像中心部分

                mRoiMask = mCheck.submat(roiMask);

                mMask.copyTo(mRoiMask);

                // 求图像均值,如果不为0,则继续循环;如果为0,则执行过滤操作

                mean = Core.mean(mCheck);

                if((byte)mean.val[0] != 0) {

                    continue;

                }

                // 执行过滤操作

                // mRoiMask为空(全黑),则以黑色小方块覆盖原图

                mRoiMask = src.submat(new Rect(j-1,i-1,size,size));

                mMask.copyTo(mRoiMask);

            }

        }

    }

 

 

说明:

  1. 所示例算法基于图像背景为黑色点(值为0),前景为白色点(值为255)计算,如果黑白反转,可方便的调整代码适应。

  2. 算法的效率还有改进之处,当图片比较大时,可能需要秒级的处理时间。

 

 

猜你喜欢

转载自blog.csdn.net/wangyulj/article/details/79082896