将错误级别分析的 C++ 实现转换为 C#
Converting a C++ implementation of Error Level Analysis to C#
我正在尝试在 C# 中实现 Error Level Analysis。我在 C++ 中找到了使用 OpenCV 和 Python 使用 PIL 的示例,但在 C# 中找不到任何示例,因此我尝试使用 OpenCvSharp 库转换 C++ 代码。
这是我用过的例子:
// Control
int scale = 15,
quality = 75;
// Image containers
cv::Mat input_image,
compressed_image;
void processImage(int, void*)
{
// Setting up parameters and JPEG compression
std::vector<int> parameters;
parameters.push_back(CV_IMWRITE_JPEG_QUALITY);
parameters.push_back(quality);
cv::imwrite("temp.jpg", input_image, parameters);
// Reading temp image from the disk
compressed_image = cv::imread("temp.jpg");
if (compressed_image.empty())
{
std::cout << "> Error loading temp image" << std::endl;
exit(EXIT_FAILURE);
}
cv::Mat output_image = cv::Mat::zeros(input_image.size(), CV_8UC3);
// Compare values through matrices
for (int row = 0; row < input_image.rows; ++row)
{
const uchar* ptr_input = input_image.ptr<uchar>(row);
const uchar* ptr_compressed = compressed_image.ptr<uchar>(row);
uchar* ptr_out = output_image.ptr<uchar>(row);
for (int column = 0; column < input_image.cols; column++)
{
// Calc abs diff for each color channel multiplying by a scale factor
ptr_out[0] = abs(ptr_input[0] - ptr_compressed[0]) * scale;
ptr_out[1] = abs(ptr_input[1] - ptr_compressed[1]) * scale;
ptr_out[2] = abs(ptr_input[2] - ptr_compressed[2]) * scale;
ptr_input += 3;
ptr_compressed += 3;
ptr_out += 3;
}
}
// Shows processed image
cv::imshow("Error Level Analysis", output_image);
}
这是我目前的尝试:
[STAThread]
static void Main(string[] args)
{
// Control
int scale = 15;
int quality = 75;
string test_img_path = "";
// Image container
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "C# Corner Open File Dialog";
fdlg.InitialDirectory = @"c:\Documents\Pictures";
fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
test_img_path = fdlg.FileName;
}
Mat input_image = Cv2.ImRead(test_img_path);
Mat compressed_image;
// Setting up parameters and JPEG compression
int[] Params = new int[2];
Params.Append(95);
Params.Append(50);
Cv2.ImWrite("temp.jpg", input_image, Params);
// Reading temp image from the disk
compressed_image = Cv2.ImRead("temp.jpg");
if (compressed_image.Empty())
{
Trace.WriteLine("File empty");
}
Mat output_image = Mat.Zeros(input_image.Size(), MatType.CV_8UC3);
// Compare values through matrices
for (int row = 0; row < input_image.Rows; ++row)
{
unsafe
{
char* ptr_input = (char*)input_image.Ptr(row);
char* ptr_compressed = (char*)compressed_image.Ptr(row);
char* ptr_out = (char*)output_image.Ptr(row);
for (int column = 0; column < input_image.Cols; column++)
{
// Calc abs diff for each color channel multiplying by a scale factor
ptr_out[0] = (char)((ptr_input[0] - ptr_compressed[0]) * scale);
ptr_out[1] = (char)(Math.Abs(ptr_input[1] - ptr_compressed[1]) * scale);
ptr_out[2] = (char)(Math.Abs(ptr_input[2] - ptr_compressed[2]) * scale);
ptr_input += 3;
ptr_compressed += 3;
ptr_out += 3;
}
}
}
// Shows processed image
Cv2.ImShow("Error Level Analysis", output_image);
}
以上不会编译,并导致错误:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
任何转换方面的帮助,或使用 C# 执行 ELA 的方法,我们将不胜感激。
//控制
整数比例= 15;
内部质量 = 75;
// Image containers
Mat input_image = new Mat();
Mat compressed_image;
// Setting up parameters and JPEG compression
int[] Params = new int[2];
Params.Append(95);
Params.Append(50);
Cv2.ImWrite("temp.jpg", input_image, Params);
// Reading temp image from the disk
compressed_image = Cv2.ImRead("temp.jpg");
if (compressed_image.Empty())
{
Trace.WriteLine("File empty");
}
Mat output_image = Mat.Zeros(input_image.Size(), MatType.CV_8UC3);
// Compare values through matrices
for (int row = 0; row < input_image.Rows; ++row)
{
unsafe
{
char* ptr_input = (char*)input_image.Ptr(row);
char* ptr_compressed = (char*)compressed_image.Ptr(row);
char* ptr_out = (char*)output_image.Ptr(row);
for (int column = 0; column < input_image.Cols; column++)
{
// Calc abs diff for each color channel multiplying by a scale factor
ptr_out[0] = (char)((ptr_input[0] - ptr_compressed[0]) * scale);
ptr_out[1] = (char)(Math.Abs(ptr_input[1] - ptr_compressed[1]) * scale);
ptr_out[2] = (char)(Math.Abs(ptr_input[2] - ptr_compressed[2]) * scale);
ptr_input += 3;
ptr_compressed += 3;
ptr_out += 3;
}
}
}
// Shows processed image
Cv2.ImShow("Error Level Analysis", output_image);
可以通过以下代码访问像素值。您不能通过指针访问受保护的内存。
using Mat mat = new Mat(FilePath.Image.Lenna, ImreadModes.Color);
for (int y = 0; y < mat.Height; y++)
{
for (int x = 0; x < mat.Width; x++)
{
Vec3b color = mat.Get<Vec3b>(y, x);
Vec3b newColor = new Vec3b(color.Item2, color.Item1, color.Item0);
mat.Set<Vec3b>(y, x, newColor);
}
}
有很多如何在c#中使用opencv的例子。检查 here.
您可以使用 EmguCV instead, which you can install from here。然后你可以像这样将代码转换为C#。
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
class Program
{
// Control
readonly int scale = 15, quality = 75;
// Image containers
Mat input_image, compressed_image;
void ProcessImage()
{
// Setting up parameters and JPEG compression
KeyValuePair<ImwriteFlags, int> parameters = new KeyValuePair<ImwriteFlags, int>(ImwriteFlags.JpegQuality, quality);
CvInvoke.Imwrite("temp.jpg", input_image, parameters);
// Reading temp image from the disk
compressed_image = CvInvoke.Imread("temp.jpg");
if (compressed_image.IsEmpty)
{
Console.WriteLine("> Error loading temp image");
Environment.Exit(1);
}
Mat output_image = Mat.Zeros(input_image.Rows, input_image.Cols, DepthType.Cv8U, 3);
byte[] input, compressed, output;
input = new byte[input_image.Rows* input_image.Cols* 3];
compressed = new byte[input_image.Rows * input_image.Cols * 3];
output = new byte[input_image.Rows * input_image.Cols * 3];
input_image.CopyTo(input);
compressed_image.CopyTo(compressed);
// Compare values through matrices
for (int row = 0; row < input_image.Rows; ++row)
for (int column = 0; column < input_image.Cols; column++)
for (int channel = 0; channel < 3; channel++)
// Calc abs diff for each color channel multiplying by a scale factor
output[(row * input_image.Cols + column) * 3 + channel] = (byte)(Math.Abs(input[(row * input_image.Cols + column) * 3 + channel] - compressed[(row * input_image.Cols + column) * 3 + channel]) * scale);
byte[] t = new byte[1];
for (int i = 0; i < output.Length; i++)
{
t[0] = output[i];
Marshal.Copy(t, 0, output_image.DataPointer + i, 1);
}
// Shows processed image
CvInvoke.Imshow("Error Level Analysis", output_image);
}
}
我正在尝试在 C# 中实现 Error Level Analysis。我在 C++ 中找到了使用 OpenCV 和 Python 使用 PIL 的示例,但在 C# 中找不到任何示例,因此我尝试使用 OpenCvSharp 库转换 C++ 代码。
这是我用过的例子:
// Control
int scale = 15,
quality = 75;
// Image containers
cv::Mat input_image,
compressed_image;
void processImage(int, void*)
{
// Setting up parameters and JPEG compression
std::vector<int> parameters;
parameters.push_back(CV_IMWRITE_JPEG_QUALITY);
parameters.push_back(quality);
cv::imwrite("temp.jpg", input_image, parameters);
// Reading temp image from the disk
compressed_image = cv::imread("temp.jpg");
if (compressed_image.empty())
{
std::cout << "> Error loading temp image" << std::endl;
exit(EXIT_FAILURE);
}
cv::Mat output_image = cv::Mat::zeros(input_image.size(), CV_8UC3);
// Compare values through matrices
for (int row = 0; row < input_image.rows; ++row)
{
const uchar* ptr_input = input_image.ptr<uchar>(row);
const uchar* ptr_compressed = compressed_image.ptr<uchar>(row);
uchar* ptr_out = output_image.ptr<uchar>(row);
for (int column = 0; column < input_image.cols; column++)
{
// Calc abs diff for each color channel multiplying by a scale factor
ptr_out[0] = abs(ptr_input[0] - ptr_compressed[0]) * scale;
ptr_out[1] = abs(ptr_input[1] - ptr_compressed[1]) * scale;
ptr_out[2] = abs(ptr_input[2] - ptr_compressed[2]) * scale;
ptr_input += 3;
ptr_compressed += 3;
ptr_out += 3;
}
}
// Shows processed image
cv::imshow("Error Level Analysis", output_image);
}
这是我目前的尝试:
[STAThread]
static void Main(string[] args)
{
// Control
int scale = 15;
int quality = 75;
string test_img_path = "";
// Image container
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "C# Corner Open File Dialog";
fdlg.InitialDirectory = @"c:\Documents\Pictures";
fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
test_img_path = fdlg.FileName;
}
Mat input_image = Cv2.ImRead(test_img_path);
Mat compressed_image;
// Setting up parameters and JPEG compression
int[] Params = new int[2];
Params.Append(95);
Params.Append(50);
Cv2.ImWrite("temp.jpg", input_image, Params);
// Reading temp image from the disk
compressed_image = Cv2.ImRead("temp.jpg");
if (compressed_image.Empty())
{
Trace.WriteLine("File empty");
}
Mat output_image = Mat.Zeros(input_image.Size(), MatType.CV_8UC3);
// Compare values through matrices
for (int row = 0; row < input_image.Rows; ++row)
{
unsafe
{
char* ptr_input = (char*)input_image.Ptr(row);
char* ptr_compressed = (char*)compressed_image.Ptr(row);
char* ptr_out = (char*)output_image.Ptr(row);
for (int column = 0; column < input_image.Cols; column++)
{
// Calc abs diff for each color channel multiplying by a scale factor
ptr_out[0] = (char)((ptr_input[0] - ptr_compressed[0]) * scale);
ptr_out[1] = (char)(Math.Abs(ptr_input[1] - ptr_compressed[1]) * scale);
ptr_out[2] = (char)(Math.Abs(ptr_input[2] - ptr_compressed[2]) * scale);
ptr_input += 3;
ptr_compressed += 3;
ptr_out += 3;
}
}
}
// Shows processed image
Cv2.ImShow("Error Level Analysis", output_image);
}
以上不会编译,并导致错误:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
任何转换方面的帮助,或使用 C# 执行 ELA 的方法,我们将不胜感激。
//控制 整数比例= 15; 内部质量 = 75;
// Image containers
Mat input_image = new Mat();
Mat compressed_image;
// Setting up parameters and JPEG compression
int[] Params = new int[2];
Params.Append(95);
Params.Append(50);
Cv2.ImWrite("temp.jpg", input_image, Params);
// Reading temp image from the disk
compressed_image = Cv2.ImRead("temp.jpg");
if (compressed_image.Empty())
{
Trace.WriteLine("File empty");
}
Mat output_image = Mat.Zeros(input_image.Size(), MatType.CV_8UC3);
// Compare values through matrices
for (int row = 0; row < input_image.Rows; ++row)
{
unsafe
{
char* ptr_input = (char*)input_image.Ptr(row);
char* ptr_compressed = (char*)compressed_image.Ptr(row);
char* ptr_out = (char*)output_image.Ptr(row);
for (int column = 0; column < input_image.Cols; column++)
{
// Calc abs diff for each color channel multiplying by a scale factor
ptr_out[0] = (char)((ptr_input[0] - ptr_compressed[0]) * scale);
ptr_out[1] = (char)(Math.Abs(ptr_input[1] - ptr_compressed[1]) * scale);
ptr_out[2] = (char)(Math.Abs(ptr_input[2] - ptr_compressed[2]) * scale);
ptr_input += 3;
ptr_compressed += 3;
ptr_out += 3;
}
}
}
// Shows processed image
Cv2.ImShow("Error Level Analysis", output_image);
可以通过以下代码访问像素值。您不能通过指针访问受保护的内存。
using Mat mat = new Mat(FilePath.Image.Lenna, ImreadModes.Color);
for (int y = 0; y < mat.Height; y++)
{
for (int x = 0; x < mat.Width; x++)
{
Vec3b color = mat.Get<Vec3b>(y, x);
Vec3b newColor = new Vec3b(color.Item2, color.Item1, color.Item0);
mat.Set<Vec3b>(y, x, newColor);
}
}
有很多如何在c#中使用opencv的例子。检查 here.
您可以使用 EmguCV instead, which you can install from here。然后你可以像这样将代码转换为C#。
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
class Program
{
// Control
readonly int scale = 15, quality = 75;
// Image containers
Mat input_image, compressed_image;
void ProcessImage()
{
// Setting up parameters and JPEG compression
KeyValuePair<ImwriteFlags, int> parameters = new KeyValuePair<ImwriteFlags, int>(ImwriteFlags.JpegQuality, quality);
CvInvoke.Imwrite("temp.jpg", input_image, parameters);
// Reading temp image from the disk
compressed_image = CvInvoke.Imread("temp.jpg");
if (compressed_image.IsEmpty)
{
Console.WriteLine("> Error loading temp image");
Environment.Exit(1);
}
Mat output_image = Mat.Zeros(input_image.Rows, input_image.Cols, DepthType.Cv8U, 3);
byte[] input, compressed, output;
input = new byte[input_image.Rows* input_image.Cols* 3];
compressed = new byte[input_image.Rows * input_image.Cols * 3];
output = new byte[input_image.Rows * input_image.Cols * 3];
input_image.CopyTo(input);
compressed_image.CopyTo(compressed);
// Compare values through matrices
for (int row = 0; row < input_image.Rows; ++row)
for (int column = 0; column < input_image.Cols; column++)
for (int channel = 0; channel < 3; channel++)
// Calc abs diff for each color channel multiplying by a scale factor
output[(row * input_image.Cols + column) * 3 + channel] = (byte)(Math.Abs(input[(row * input_image.Cols + column) * 3 + channel] - compressed[(row * input_image.Cols + column) * 3 + channel]) * scale);
byte[] t = new byte[1];
for (int i = 0; i < output.Length; i++)
{
t[0] = output[i];
Marshal.Copy(t, 0, output_image.DataPointer + i, 1);
}
// Shows processed image
CvInvoke.Imshow("Error Level Analysis", output_image);
}
}