添加C#实现
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using System.Collections.Generic;
|
||||
using OpenCvSharp;
|
||||
|
||||
namespace Com.Lmc.ShuiYin.Two.Utils
|
||||
{
|
||||
public class WaterMarkDFT
|
||||
{
|
||||
public static void Embed(string imagePath, string watermark, string outputPath)
|
||||
{
|
||||
Mat image = Cv2.ImRead(imagePath);
|
||||
List<Mat> allPlanes = new List<Mat>();
|
||||
Cv2.Split(image, out Mat[] splitPlanes);
|
||||
allPlanes.AddRange(splitPlanes);
|
||||
|
||||
Mat processImage = allPlanes[0];
|
||||
processImage.ConvertTo(processImage, MatType.CV_32F);
|
||||
|
||||
List<Mat> planes = new List<Mat>();
|
||||
planes.Add(processImage);
|
||||
planes.Add(Mat.Zeros(processImage.Size(), MatType.CV_32F));
|
||||
|
||||
Mat complexImage = new Mat();
|
||||
Cv2.Merge(planes.ToArray(), complexImage);
|
||||
|
||||
Cv2.Dft(complexImage, complexImage);
|
||||
|
||||
Scalar scalar = new Scalar(2, 2, 2);
|
||||
Point point = new Point(40, 40);
|
||||
|
||||
Cv2.PutText(complexImage, watermark, point, HersheyFonts.HersheyComplex, 1.5, scalar, 3, LineTypes.Link8, false); // Java: 20 -> bottomLeftOrigin? No, putText last arg is bottomLeftOrigin. Java code says 20??
|
||||
// Java putText signature: (img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)
|
||||
// Java code: putText(complexImage, watermark, point, FONT_HERSHEY_COMPLEX, 1.5, scalar, 3, 20);
|
||||
// Wait, 20 is not boolean.
|
||||
// Check Java params:
|
||||
// putText(Mat img, String text, Point org, int fontFace, double fontScale, Scalar color, int thickness)
|
||||
// or
|
||||
// putText(Mat img, String text, Point org, int fontFace, double fontScale, Scalar color, int thickness, int lineType, boolean bottomLeftOrigin)
|
||||
// The code has 8 arguments.
|
||||
// putText(complexImage, watermark, point, FONT_HERSHEY_COMPLEX, 1.5, scalar,3, 20);
|
||||
// Arg 8 is 20? 20 is not boolean.
|
||||
// Maybe they mean lineType=20? But lineType is usually 8, 4, CV_AA (16).
|
||||
// Maybe it is calling a different overload?
|
||||
// Actually, in the Java code: `putText(complexImage, watermark, point, FONT_HERSHEY_COMPLEX, 1.5, scalar,3, 20);`
|
||||
// If I assume 20 is lineType? CV_AA? No.
|
||||
// Let's assume standard parameters: thickness=3, lineType=20?
|
||||
// I will use standard LineTypes.Link8 and false for bottomLeftOrigin.
|
||||
|
||||
Cv2.Flip(complexImage, complexImage, FlipMode.XY); // -1
|
||||
Cv2.PutText(complexImage, watermark, point, HersheyFonts.HersheyComplex, 1.5, scalar, 3, LineTypes.Link8, false);
|
||||
Cv2.Flip(complexImage, complexImage, FlipMode.XY); // -1
|
||||
|
||||
Mat invDFT = new Mat();
|
||||
Cv2.Idft(complexImage, invDFT, DftFlags.Scale | DftFlags.RealOutput);
|
||||
|
||||
invDFT.ConvertTo(invDFT, MatType.CV_8U);
|
||||
|
||||
allPlanes[0] = invDFT;
|
||||
|
||||
Cv2.Merge(allPlanes.ToArray(), invDFT);
|
||||
Cv2.ImWrite(outputPath, invDFT);
|
||||
}
|
||||
|
||||
public static void Extract(string targetImage, string outputWatermark)
|
||||
{
|
||||
Mat image = Cv2.ImRead(targetImage);
|
||||
List<Mat> allPlanes = new List<Mat>();
|
||||
Cv2.Split(image, out Mat[] splitPlanes);
|
||||
allPlanes.AddRange(splitPlanes);
|
||||
|
||||
Mat processImage = allPlanes[0];
|
||||
processImage.ConvertTo(processImage, MatType.CV_32F);
|
||||
|
||||
List<Mat> planes = new List<Mat>();
|
||||
planes.Add(processImage);
|
||||
planes.Add(Mat.Zeros(processImage.Size(), MatType.CV_32F));
|
||||
|
||||
Mat complexImage = new Mat();
|
||||
Cv2.Merge(planes.ToArray(), complexImage);
|
||||
|
||||
Cv2.Dft(complexImage, complexImage);
|
||||
|
||||
List<Mat> newPlanes = new List<Mat>();
|
||||
Mat mag = new Mat();
|
||||
Cv2.Split(complexImage, out Mat[] splitComplex);
|
||||
newPlanes.AddRange(splitComplex);
|
||||
|
||||
Cv2.Magnitude(newPlanes[0], newPlanes[1], mag);
|
||||
Cv2.Add(Mat.Ones(mag.Size(), MatType.CV_32F), mag, mag);
|
||||
Cv2.Log(mag, mag);
|
||||
|
||||
// Crop
|
||||
mag = mag.SubMat(new Rect(0, 0, mag.Cols & -2, mag.Rows & -2));
|
||||
int cx = mag.Cols / 2;
|
||||
int cy = mag.Rows / 2;
|
||||
|
||||
Mat q0 = new Mat(mag, new Rect(0, 0, cx, cy));
|
||||
Mat q1 = new Mat(mag, new Rect(cx, 0, cx, cy));
|
||||
Mat q2 = new Mat(mag, new Rect(0, cy, cx, cy));
|
||||
Mat q3 = new Mat(mag, new Rect(cx, cy, cx, cy));
|
||||
Mat tmp = new Mat();
|
||||
q0.CopyTo(tmp);
|
||||
q3.CopyTo(q0);
|
||||
tmp.CopyTo(q3);
|
||||
q1.CopyTo(tmp);
|
||||
q2.CopyTo(q1);
|
||||
tmp.CopyTo(q2);
|
||||
|
||||
mag.ConvertTo(mag, MatType.CV_8UC1);
|
||||
Cv2.Normalize(mag, mag, 0, 255, NormTypes.MinMax, (int)MatType.CV_8UC1);
|
||||
Cv2.ImWrite(outputWatermark, mag);
|
||||
}
|
||||
|
||||
private static Mat OptimizeImageDimensions(Mat image)
|
||||
{
|
||||
Mat padded = new Mat();
|
||||
int addPixelRows = Cv2.GetOptimalDFTSize(image.Rows);
|
||||
int addPixelCols = Cv2.GetOptimalDFTSize(image.Cols);
|
||||
Cv2.CopyMakeBorder(image, padded, 0, addPixelRows - image.Rows,
|
||||
0, addPixelCols - image.Cols, BorderTypes.Constant, Scalar.All(0));
|
||||
return padded;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user