添加C#实现

This commit is contained in:
ShaoHua
2025-12-27 20:36:56 +08:00
parent a5303d6f3e
commit ce394c0646
21 changed files with 1312 additions and 0 deletions
@@ -0,0 +1,13 @@
using OpenCvSharp;
namespace Com.Lmc.ShuiYin.One.Converter
{
public interface Converter
{
Mat Start(Mat src);
void Inverse(Mat com);
void AddTextWatermark(Mat com, string watermark);
void AddImageWatermark(Mat com, Mat watermark);
Mat ShowWatermark(Mat src);
}
}
@@ -0,0 +1,77 @@
using OpenCvSharp;
using Com.Lmc.ShuiYin.One.Util;
namespace Com.Lmc.ShuiYin.One.Converter
{
public class DctConverter : Converter
{
public Mat Start(Mat src)
{
if ((src.Cols & 1) != 0)
{
Cv2.CopyMakeBorder(src, src, 0, 0, 0, 1, BorderTypes.Constant, Scalar.All(0));
}
if ((src.Rows & 1) != 0)
{
Cv2.CopyMakeBorder(src, src, 0, 1, 0, 0, BorderTypes.Constant, Scalar.All(0));
}
src.ConvertTo(src, MatType.CV_32F);
Cv2.Dct(src, src);
return src;
}
public void Inverse(Mat com)
{
Cv2.Idct(com, com);
}
public void AddTextWatermark(Mat com, string watermark)
{
Cv2.PutText(com, watermark,
new Point(com.Cols >> 2, com.Rows >> 2),
HersheyFonts.HersheyComplex, 2.0,
new Scalar(2, 2, 2, 0), 2, LineTypes.Link8, false);
}
public void AddImageWatermark(Mat com, Mat watermark)
{
Mat mask = new Mat();
Cv2.InRange(watermark, new Scalar(0, 0, 0, 0), new Scalar(0, 0, 0, 0), mask);
Mat i2 = new Mat(watermark.Size(), watermark.Type(), new Scalar(2, 2, 2, 0));
i2.CopyTo(watermark, mask);
watermark.ConvertTo(watermark, MatType.CV_32F);
int row = (com.Rows - watermark.Rows) >> 1;
int col = (com.Cols - watermark.Cols) >> 1;
Cv2.CopyMakeBorder(watermark, watermark, row, row, col, col, BorderTypes.Constant, Scalar.All(0));
Utils.FixSize(watermark, com);
Cv2.AddWeighted(watermark, 0.03, com, 1, 0.0, com);
}
public Mat ShowWatermark(Mat src)
{
src.ConvertTo(src, MatType.CV_8UC3); // COLOR_RGB2HSV requires 8-bit or 16-bit usually, Java code says convertTo(src, COLOR_RGB2HSV). Wait.
// Java: src.convertTo(src, COLOR_RGB2HSV);
// Actually convertTo is for type conversion (e.g. to float). cvtColor is for color space.
// The Java code in DctConverter.java says: src.convertTo(src, COLOR_RGB2HSV);
// This looks like a mistake in the Java code or I am misreading.
// Core.java doesn't have COLOR_RGB2HSV constant for convertTo. Imgproc has it.
// Imgproc.cvtColor(src, src, Imgproc.COLOR_RGB2HSV); is the correct way.
// The Java code provided: `src.convertTo(src, COLOR_RGB2HSV);`
// `COLOR_RGB2HSV` is an int (usually 40 or 41). `convertTo` takes rtype (int).
// If they are using `convertTo` with a color conversion code, they might be doing something wrong or it's valid in Java OpenCV to use it as a type? No.
// `CV_32F` is a type. `COLOR_RGB2HSV` is a conversion code.
// Let's assume they meant `Imgproc.cvtColor`.
// Wait, checking the Java code again: `src.convertTo(src, COLOR_RGB2HSV);`
// If I look at `DctConverter.java` line 76: `src.convertTo(src, COLOR_RGB2HSV);`
// This is very suspicious.
// However, `COLOR_RGB2HSV` is likely imported statically from `Imgproc`.
// In OpenCV C++, `convertTo` changes the depth.
// I will use `Cv2.CvtColor` because that's what makes sense for HSV.
Cv2.CvtColor(src, src, ColorConversionCodes.RGB2HSV);
Cv2.InRange(src, new Scalar(0, 0, 0, 0), new Scalar(16, 16, 16, 0), src);
Cv2.Normalize(src, src, 0, 255, NormTypes.MinMax, (int)MatType.CV_8UC1);
return src;
}
}
}
@@ -0,0 +1,93 @@
using System.Collections.Generic;
using OpenCvSharp;
using Com.Lmc.ShuiYin.One.Util;
using Com.Lmc.ShuiYin; // For ShuiYinUtils
namespace Com.Lmc.ShuiYin.One.Converter
{
public class DftConverter : Converter
{
public Mat Start(Mat src)
{
src.ConvertTo(src, MatType.CV_32F);
List<Mat> planes = new List<Mat>();
Mat com = new Mat();
planes.Add(src);
planes.Add(Mat.Zeros(src.Size(), MatType.CV_32F));
Cv2.Merge(planes.ToArray(), com);
Cv2.Dft(com, com);
return com;
}
public void Inverse(Mat com)
{
List<Mat> planes = new List<Mat>();
Cv2.Idft(com, com);
Cv2.Split(com, out Mat[] splitPlanes);
planes.AddRange(splitPlanes);
Cv2.Normalize(planes[0], com, 0, 255, NormTypes.MinMax, (int)MatType.CV_8UC3);
}
public void AddTextWatermark(Mat com, string watermark)
{
Scalar s = new Scalar(255, 255, 255, 0);
Point p = new Point(0, com.Rows / 3);
int thickness = 3;
// Note: ShuiYinUtils needs to be implemented. Assuming it exists.
double fontScale = ShuiYinUtils.GetFontScale(new Size(com.Cols, com.Rows / 2), watermark, HersheyFonts.HersheyComplex, thickness);
Cv2.PutText(com, watermark, p, HersheyFonts.HersheyComplex, fontScale, s, thickness, LineTypes.Link8, false);
Cv2.Flip(com, com, FlipMode.X); // -1 in OpenCV is both axes, but here it seems they use -1. In OpenCvSharp FlipMode.XY is -1.
// Wait, Java code says -1. OpenCvSharp FlipMode: X=0, Y=1, XY=-1.
// Let's check Java docs: 0 means flipping around the x-axis... wait.
// OpenCV: 0 means flipping around the x-axis and positive value (for example, 1) means flipping around y-axis. Negative value (for example, -1) means flipping around both axes.
// So -1 is XY.
Cv2.Flip(com, com, FlipMode.XY);
Cv2.PutText(com, watermark, p, HersheyFonts.HersheyComplex, fontScale, s, thickness, LineTypes.Link8, false);
Cv2.Flip(com, com, FlipMode.XY);
}
public void AddImageWatermark(Mat com, Mat watermark)
{
List<Mat> planes = new List<Mat>();
List<Mat> newPlanes = new List<Mat>();
Mat temp = new Mat();
int col = (com.Cols - watermark.Cols) >> 1;
int row = ((com.Rows >> 1) - watermark.Rows) >> 1;
watermark.ConvertTo(watermark, MatType.CV_32F);
Cv2.CopyMakeBorder(watermark, watermark, row, row, col, col, BorderTypes.Constant, Scalar.All(0));
planes.Add(watermark);
Cv2.Flip(watermark, temp, FlipMode.XY);
planes.Add(temp);
// vconcat expects an array of Mats
Mat[] planesArray = planes.ToArray();
// In Java: vconcat(planes, watermark); -> watermark becomes the concatenation.
// In C#: Cv2.VConcat(planes, watermark);
Cv2.VConcat(planesArray, watermark);
newPlanes.Add(watermark);
newPlanes.Add(watermark);
Cv2.Merge(newPlanes.ToArray(), watermark);
Utils.FixSize(watermark, com);
Cv2.AddWeighted(watermark, 8, com, 1, 0.0, com);
Cv2.Split(com, out Mat[] splitCom);
// The Java code ends with split(com, planes), but doesn't return or use planes. It seems redundant or side-effect based if 'planes' was a field, but it's local.
// Actually, in Java code: split(com, planes); where planes is a local List<Mat>. This seems useless at the end of the method unless it modifies 'com' in place (it doesn't, split fills the list).
// So I can ignore it.
}
public Mat ShowWatermark(Mat src)
{
Mat mag = new Mat();
Cv2.Split(src, out Mat[] splitSrc);
// Java: magnitude(newPlanes.get(0), newPlanes.get(1), mag);
Cv2.Magnitude(splitSrc[0], splitSrc[1], mag);
Cv2.Add(Mat.Ones(mag.Size(), MatType.CV_32F), mag, mag);
Cv2.Log(mag, mag);
mag.ConvertTo(mag, MatType.CV_8UC1);
Cv2.Normalize(mag, mag, 0, 255, NormTypes.MinMax, (int)MatType.CV_8UC1);
return mag;
}
}
}
@@ -0,0 +1,32 @@
using OpenCvSharp;
namespace Com.Lmc.ShuiYin.One.Converter
{
public class DwtConverter : Converter
{
public Mat Start(Mat src)
{
return null;
}
public void Inverse(Mat com)
{
}
public void AddTextWatermark(Mat com, string watermark)
{
}
public void AddImageWatermark(Mat com, Mat watermark)
{
}
public Mat ShowWatermark(Mat src)
{
return null;
}
}
}