Bootstrap

Java + opencv 实现图片修复(图片去水印)

一、效果展示

如效果图显示运行结果, 左边为原图, 右边为去水印(修复)后的图片. 可以看到原图中的 '你可以的 你是棒棒的小汪汪' 文字水印被去除掉了, 但是也可以明显的看到, 狗子眼里的白色光芒也被一起去掉了. 所以,本篇教程并不适用于所有的图片去水印, 至于如何局部去水印, 后面再说.

二、技术实现思路

三、pom引入的jar包说明

说明: 有些ffmpeg的包根据自己情况进行删减.

    
        1.8
        
        1.4.3
        
        3.4.3
        
        4.0.2
    

 
        
        
            org.bytedeco
            javacv-platform
            ${javacpp.version}
        
        
            org.bytedeco
            javacv
            ${javacpp.version}
        
        
        
            org.bytedeco
            javacpp
            ${javacpp.version}
        
        
        
            org.bytedeco.javacpp-presets
            ffmpeg-platform
            ${ffmpeg.version}-${javacpp.version}
        
        
            org.bytedeco.javacpp-presets
            ffmpeg
            ${ffmpeg.version}-${javacpp.version}
        

四、具体实现代码

(1)、图片转换成灰色

使用OpenCV的 cvtColor() 转换图片颜色


        String filePath = "D:\\upload\\white.jpg";
        Mat img = Imgcodecs.imread(filePath);
        // 先灰度化下
        Mat gray = new Mat();
        Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGRA2GRAY);

(2)、灰色图高斯模糊

        // 高斯模糊
        Imgproc.GaussianBlur(gray, gray, new Size(3, 3), 0);

(3)、二值化处理

        Mat thresh = new Mat();
        // 二值化处理
        threshold(gray, thresh, 0, 255,  Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);

(4)、创建尺子和形状

        // 创建形状和尺寸的结构元素
        Mat hiMask = new Mat();
        Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));

(5)、二值化后的图像进行膨胀处理, 扩张待修复的区域

        // 对Mask膨胀处理, 扩张待修复区域
        Imgproc.dilate(thresh, hiMask, kernel);

(6)、图像修复

        //图像修复
        Mat specular = new Mat();
        Photo.inpaint(img, hiMask, specular, 5, Photo.INPAINT_TELEA);

五、完整实现代码

package com.biubiu.example;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.photo.Photo;
 
import static org.opencv.imgproc.Imgproc.threshold;
/**
 * @author :张音乐
 * @date :Created in 2021/4/15 上午9:47
 * @description:图像修复
 * @email: zhangyule1993@sina.com
 * @version: 1.0
 */
public class ImageRepair {
 
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
 
    public static void main(String[] args) {
 
        String filePath = "D:\\upload\\white.jpg";
        Mat img = Imgcodecs.imread(filePath);
        // 先灰度化下
        Mat gray = new Mat();
        Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGRA2GRAY);
        // 高斯模糊
        Imgproc.GaussianBlur(gray, gray, new Size(3, 3), 0);
 
        int height = img.height();
        int width = img.width();
 
        // 图片二值化处理,把[240, 240, 240] ~ [255, 255, 255]以外的颜色变成0
        Mat thresh = new Mat();
        // 二值化处理
        // inRange(img, new Scalar(240, 240, 240), new Scalar(255, 255, 255), thresh);
 
        // 二值化处理 ,两种方式都可以实现二值化操作
        threshold(gray, thresh, 0, 255,  Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
        // 创建形状和尺寸的结构元素
        Mat hiMask = new Mat();
        Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
 
        // 对Mask膨胀处理, 扩张待修复区域
        Imgproc.dilate(thresh, hiMask, kernel);
        //图像修复
        Mat specular = new Mat();
        Photo.inpaint(img, hiMask, specular, 5, Photo.INPAINT_TELEA);
 
        // 显示原图
        HighGui.namedWindow("Image", 0);
        HighGui.resizeWindow("Image", width / 2, height / 2);
        HighGui.imshow("Image", img);
 
        // 显示修复后的图
        HighGui.namedWindow("newImage", 0);
        HighGui.resizeWindow("newImage", width / 2, height / 2);
        HighGui.imshow("newImage", specular);
 
        HighGui.waitKey(0);
        // 释放所有的窗体资源
        HighGui.destroyAllWindows();
    }
}
 
 

六、报错问题解决

windows下运行报错请参考往期文章