写点什么

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

用户头像
张音乐
关注
发布于: 1 小时前
Java + opencv 实现图片修复(图片去水印)

一、效果展示

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

二、技术实现思路

  1. 图片转换成灰色(降低为一维的灰度,减低计算强度)

  2. 对灰度图片进行高斯模糊操作, 这里进行高斯模糊的作用就是减少图像噪声, 降低细节层次,往深一点的原理, 这里不作探讨

  3. 对高斯模糊之后的图像进行二值化操作, 图像二值化是将图像上的像素点的灰度值设置为 0 或 255, 也就是将整个图像呈现出明显的黑白效果, 图像的二值化使得图像变得简单, 而且数据量减小, 能凸显出目标轮廓. 在本文这里的作用是将 255 以外的颜色变为 0, 所以就呈现出明显的黑白效果. 非黑即白.

  4. 创建一个合理的形状和尺寸的结构元素

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

  6. 进行图像修复(去水印)处理. 图片修复的原理简单来说就是标定噪声的特征, 在使用噪声周围的颜色特征推理出应该修复的图片的颜色, 从而实现图片修复.

三、pom 引入的 jar 包说明

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

    <properties>        <java.version>1.8</java.version>        <!-- javacpp当前版本 -->        <javacpp.version>1.4.3</javacpp.version>        <!-- opencv版本 -->        <opencv.version>3.4.3</opencv.version>        <!-- ffmpeg版本 -->        <ffmpeg.version>4.0.2</ffmpeg.version>    </properties>
复制代码


         <!-- javacv -->        <dependency>            <groupId>org.bytedeco</groupId>            <artifactId>javacv-platform</artifactId>            <version>${javacpp.version}</version>        </dependency>        <dependency>            <groupId>org.bytedeco</groupId>            <artifactId>javacv</artifactId>            <version>${javacpp.version}</version>        </dependency>        <!-- javacpp -->        <dependency>            <groupId>org.bytedeco</groupId>            <artifactId>javacpp</artifactId>            <version>${javacpp.version}</version>        </dependency>        <!-- ffmpeg -->        <dependency>            <groupId>org.bytedeco.javacpp-presets</groupId>            <artifactId>ffmpeg-platform</artifactId>            <version>${ffmpeg.version}-${javacpp.version}</version>        </dependency>        <dependency>            <groupId>org.bytedeco.javacpp-presets</groupId>            <artifactId>ffmpeg</artifactId>            <version>${ffmpeg.version}-${javacpp.version}</version>        </dependency>
复制代码

四、具体实现代码

(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 下运行报错请参考往期文章

Java + opencv 实现图片人脸检测

Java + opencv 实现视频人脸检测

发布于: 1 小时前阅读数: 2
用户头像

张音乐

关注

求你关注我,别不识抬举.别逼我跪下来求你. 2021.03.28 加入

还未添加个人简介

评论

发布
暂无评论
Java + opencv 实现图片修复(图片去水印)