OpenCV Java binary (black and white) image noise filtering algorithm



OpenCV Java binary (black and white) image noise filtering algorithm

In image processing applications, we often encounter the situation that the noise points in the image affect the segmentation and processing of the image. There are not many Java examples of OpenCV . This article gives an image noise filtering algorithm in the OpenCV + Java environment.

OpenCV version: 3.4

Java1.8

 

Filter the noise points in the black and white (binary) image, you can specify the size of the filter area.

Algorithm description:

  1. Input the image to be filtered (black and white binary).

  2. Extending the image (increasing the length and width by 2 each ) is equivalent to adding a circle around the image for easy processing and reducing many boundary detection operations.

  3. Start looping from the first pixel.

  4. With the specified pixel as the center (and the size of the filter area needs to be considered), extract the sub-image of the specified area. The size of the extracted area is the size of the area to be filtered plus an enclosing circle.

  5. Assign a value of 0 (black) to the middle part surrounded by the extracted area except ;

  6. Find the mean of the subimages ( Core.mean() );

  7. If the mean value is not 0 , it means that there are points (white points) that are not 0 , and no filtering is performed.

  8. If the mean value is 0 , it means that the outer surround is a circle of black dots ( 0 ), then perform filtering (assign the middle area of ​​the original image to 0 ).

 

source code:

    // Image filtering, remove noise points

    /**

     * @param src - the input binary (black and white) image, the algorithm will directly modify the input image, and the returned result is also this parameter

     * @param size - the size of the noise block that needs to be filtered, the default is a square block with size as the size

     */

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

        // image height, width

        int rows = src.rows();

        int cols = src.cols();

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

            return;

        }

        // extend the image

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

        // Copy the original image to the extended image

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

        Mat m = rslt .submat( roi );

        src.copyTo(m);

        // Filter parameter preparation

        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. 算法的效率还有改进之处,当图片比较大时,可能需要秒级的处理时间。

 

 

Guess you like

Origin blog.csdn.net/wangyulj/article/details/79082896