Opencv实现盲水印技术(三)——傅里叶变换算法及盲水印实现
Opencv实现盲⽔印技术(三)——傅⾥叶变换算法及盲⽔印
实现
前⾔
之前的⽂章中,介绍了如何构建Java⼯程和Java Web⼯程,本⽂将简单介绍对傅⾥叶变换的理解,以及使⽤opencv实现盲⽔印。关于傅⾥叶变换,有篇博⽂介绍的很详细,链接地址为:。
十二星座是按阴历还是阳历
对图像傅⾥叶变换的理解
对图像进⾏傅⾥叶变换,起始是⼀个⼆维离散傅⾥叶变换,图像的频率是指图像灰度变换的强烈程度,将⼆维图像由空间域变为频域后,图像上的每个点的值都变成了复数,也就是所谓的复频域,通过复数的实部和虚部,可以计算出幅值和相位,计算幅值即对复数取模值,将取模值后的矩阵显⽰出来,即为其频谱图。但是问题来了,复数取模后,数字有可能变的很⼤,远⼤于255,如果数据超过255,则在显⽰图像的时候会都当做255来处理,图像就成了全⽩⾊。因此,⼀般会对模值再取对数,在在0~255的范围内进⾏归⼀化,这样才能够准确的反映到图像上,发现数据之间的差别,区分⾼频和低频分量,这也是进⾏傅⾥叶变换的意义。
opencv实现盲⽔印
废话不多说,先上代码。
public class DFTUtil {
private static List<Mat> planes;
private static Mat complexImage;
private DFTUtil(){}
private static final DFTUtil dftUtil = new DFTUtil();
public static DFTUtil getInstance () {
planes = new ArrayList<>();
complexImage = new Mat();
return dftUtil;
}
public Mat transformImage(Mat image) {
// planes数组中存的通道数若开始不为空,需清空.
if (!planes.isEmpty()) {
planes.clear();
}
// optimize the dimension of the loaded image
Mat padded = this.optimizeImageDim(image);
// prepare the image planes to obtain the complex image
planes.add(padded);
planes.s(padded.size(), CvType.CV_32F));
/
/ prepare a complex image for performing the dft
<(planes, complexImage);
// dft
Core.dft(complexImage, complexImage);
// optimize the image resulting from the dft operation
Mat magnitude = ateOptimizedMagnitude(complexImage);
planes.clear();
return magnitude;
}
public void transformImageWithText(Mat image, String watermarkText, Point point, Double fontSize, Scalar scalar) {
// planes数组中存的通道数若开始不为空,需清空.
if (!planes.isEmpty()) {
planes.clear();
房改房是什么意思}
// optimize the dimension of the loaded image
//Mat padded = this.optimizeImageDim(image);
//Mat padded = this.optimizeImageDim(image);
Mat padded = image;
// prepare the image planes to obtain the complex image
planes.add(padded);
planes.s(padded.size(), CvType.CV_32F));
/
/ prepare a complex image for performing the dft
<(planes, complexImage);
// dft
Core.dft(complexImage, complexImage);
失业补助金怎么申请领取
// 频谱图上添加⽂本
Core.putText(complexImage, watermarkText, point, Core.FONT_HERSHEY_DUPLEX, fontSize, scalar,2);  Core.flip(complexImage, complexImage, -1);
Core.putText(complexImage, watermarkText, point, Core.FONT_HERSHEY_DUPLEX, fontSize, scalar,2);  Core.flip(complexImage, complexImage, -1);
planes.clear();
}
public Mat antitransformImage() {
Mat invDFT = new Mat();
Core.idft(complexImage, invDFT, Core.DFT_SCALE | Core.DFT_REAL_OUTPUT, 0);
Mat restoredImage = new Mat();
planes.clear();
return restoredImage;
}
/**
* 为加快傅⾥叶变换的速度,对要处理的图⽚尺⼨进⾏优化
*
* @param image
*            the {@link Mat} to optimize
* @return the image whose dimensions have been optimized
*/
private Mat optimizeImageDim(Mat image) {
// init
Mat padded = new Mat();
// get the optimal rows size for dft
int addPixelRows = ws());
// get the optimal cols size for dft
int addPixelCols = ls());
// apply the optimal cols and rows size to the image
return padded;
}
/**
* Optimize the magnitude of the complex image obtained from the DFT, to
* improve its visualization
*
* @param complexImage
*            the complex image obtained from the DFT
* @return the optimized image
*/
private Mat createOptimizedMagnitude(Mat complexImage) {
// init
List<Mat> newPlanes = new ArrayList<>();
Mat mag = new Mat();
// split the comples image in two planes
Core.split(complexImage, newPlanes);
// compute the magnitude
Core.(0), (1), mag);
// move to a logarithmic scale
Core.s(mag.size(), CvType.CV_32F), mag, mag);
Core.log(mag, mag);
/
/ optionally reorder the 4 quadrants of the magnitude image
this.shiftDFT(mag);
// normalize the magnitude image for the visualization since both JavaFX
我可以无所谓// and OpenCV need images with value between 0 and 255
// convert back to CV_8UC1
return mag;
}
/**
* Reorder the 4 quadrants of the image representing the magnitude, after
* the DFT
*
* @param image
*            the {@link Mat} object whose quadrants are to reorder
*/
private void shiftDFT(Mat image) {
image = image.submat(new Rect(0, 0, ls() & -2, ws() & -2));
int cx = ls() / 2;
int cy = ws() / 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, new Rect(cx, cy, cx, cy));
Mat tmp = new Mat();
生日快乐的英文pyTo(q3);
}
}
上述代码是使⽤opencv进⾏傅⾥叶变换的⼯具类,其流程⼤致是:
1. 对图像进⾏傅⾥叶变换;
2. 打⽔印⽂字,注意此处是中⼼对称的打⽔印,⾄于原因,可以去研究⼀下傅⾥叶变换,就知道为啥要对称了;
3. 傅⾥叶逆变换,取得原图像。
代码⾥注释的都很清楚,就不⼀⼀讲解代码了,有⼀篇写⽤DFT进⾏图⽚⽂字旋转的帖⼦,写的很详细,可以看下。链接为:
效果展⽰
公安警官职业学院
原图,还是上⼤美⼥lean吧。
加⽔印后的图
解⽔印的图,即拿加⽔印的图⽚再做傅⾥叶变换。⽔印⽂字为“TEST”。
⼩结
本⽂介绍了傅⾥叶变换并对实现盲⽔印的核⼼算法实现给出了源代码,希望对⼤家有所帮助,欢迎探讨。转载请注明⽂章出处。。。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。