java 盲水印_Java使用OpenCV 基于离散傅里叶变换算法 实现图片盲水印添加

这篇博客介绍了如何使用Java结合OpenCV库,通过离散傅里叶变换算法来添加图片的盲水印。作者yangxiaohui详细展示了从优化图像尺寸到执行傅里叶变换,再到添加文本水印的完整过程。
摘要由CSDN通过智能技术生成

import org.opencv.core.*;importorg.opencv.imgproc.Imgproc;importjava.util.ArrayList;importjava.util.List;/***@authoryangxiaohui

* @Date: Create by 2018-10-25 19:14

* @Description: 添加图片盲水印工具类*/

public classImgWatermarkUtil {private static List planes = new ArrayList();private static List allPlanes = new ArrayList();/***

 
 

* 添加图片文字水印

*

 
 

*@authorYangxiaohui

* @date 2018-10-25 19:16

*@paramimage 图片对象

*@paramwatermarkText 水印文字*/

public staticMat addImageWatermarkWithText(Mat image, String watermarkText){

Mat complexImage= newMat();//优化图像的尺寸//Mat padded = optimizeImageDim(image);

Mat padded =splitSrc(image);

padded.convertTo(padded, CvType.CV_32F);

planes.add(padded);

planes.add(Mat.zeros(padded.size(), CvType.CV_32F));

Core.merge(planes, complexImage);//dft

Core.dft(complexImage, complexImage);//添加文本水印

Scalar scalar = new Scalar(0, 0, 0);

Point point= new Point(40, 40);

Core.putText(complexImage, watermarkText, point, Core.FONT_HERSHEY_DUPLEX, 1D, scalar);

Core.flip(complexImage, complexImage,-1);

Core.putText(complexImage, watermarkText, point, Core.FONT_HERSHEY_DUPLEX, 1D, scalar);

Core.flip(complexImage, complexImage,-1);returnantitransformImage(complexImage, allPlanes);

}/***

 
 

* 获取图片水印

*

 
 

*@authorYangxiaohui

* @date 2018-10-25 19:58

*@paramimage*/

public staticMat getImageWatermarkWithText(Mat image){

List planes = new ArrayList();

Mat complexImage= newMat();

Mat padded=splitSrc(image);

padded.convertTo(padded, CvType.CV_32F);

planes.add(padded);

planes.add(Mat.zeros(padded.size(), CvType.CV_32F));

Core.merge(planes, complexImage);//dft

Core.dft(complexImage, complexImage);

Mat magnitude=createOptimizedMagnitude(complexImage);

planes.clear();returnmagnitude;

}private staticMat splitSrc(Mat mat) {

mat=optimizeImageDim(mat);

Core.split(mat, allPlanes);

Mat padded= newMat();if (allPlanes.size() > 1) {for (int i = 0; i < allPlanes.size(); i++) {if (i == 0) {

padded=allPlanes.get(i);break;

}

}

}else{

padded=mat;

}returnpadded;

}private static Mat antitransformImage(Mat complexImage, ListallPlanes) {

Mat invDFT= newMat();

Core.idft(complexImage, invDFT, Core.DFT_SCALE| Core.DFT_REAL_OUTPUT, 0);

Mat restoredImage= newMat();

invDFT.convertTo(restoredImage, CvType.CV_8U);if (allPlanes.size() == 0) {

allPlanes.add(restoredImage);

}else{

allPlanes.set(0, restoredImage);

}

Mat lastImage= newMat();

Core.merge(allPlanes, lastImage);returnlastImage;

}/***

 
 

* 为加快傅里叶变换的速度,对要处理的图片尺寸进行优化

*

 
 

*@authorYangxiaohui

* @date 2018-10-25 19:33

*@paramimage

*@return

*/

private staticMat optimizeImageDim(Mat image) {

Mat padded= newMat();int addPixelRows =Core.getOptimalDFTSize(image.rows());int addPixelCols =Core.getOptimalDFTSize(image.cols());

Imgproc.copyMakeBorder(image, padded,0, addPixelRows - image.rows(), 0, addPixelCols -image.cols(),

Imgproc.BORDER_CONSTANT, Scalar.all(0));returnpadded;

}private staticMat createOptimizedMagnitude(Mat complexImage) {

List newPlanes = new ArrayList();

Mat mag= newMat();

Core.split(complexImage, newPlanes);

Core.magnitude(newPlanes.get(0), newPlanes.get(1), mag);

Core.add(Mat.ones(mag.size(), CvType.CV_32F), mag, mag);

Core.log(mag, mag);

shiftDFT(mag);

mag.convertTo(mag, CvType.CV_8UC1);

Core.normalize(mag, mag,0, 255, Core.NORM_MINMAX, CvType.CV_8UC1);returnmag;

}private static voidshiftDFT(Mat image) {

image= image.submat(new Rect(0, 0, image.cols() & -2, image.rows() & -2));int cx = image.cols() / 2;int cy = image.rows() / 2;

Mat q0= new Mat(image, new Rect(0, 0, cx, cy));

Mat q1= new Mat(image, new Rect(cx, 0, cx, cy));

Mat q2= new Mat(image, new Rect(0, cy, cx, cy));

Mat q3= new Mat(image, newRect(cx, cy, cx, cy));

Mat tmp= newMat();

q0.copyTo(tmp);

q3.copyTo(q0);

tmp.copyTo(q3);

q1.copyTo(tmp);

q2.copyTo(q1);

tmp.copyTo(q2);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值