public unsafe partial class 图片找茬 : Form
{
public 图片找茬()
{
InitializeComponent();
}
private string selectedImagePath1;
private string selectedImagePath2;
private void pictureBox1_Click(object sender, EventArgs e)
{
using OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Image Files (*.bmp, *.jpg, *.png)|*.bmp;*.jpg;*.png";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
selectedImagePath1 = openFileDialog.FileName;
Image selectedImage = Image.FromFile(selectedImagePath1);
if (pictureBox1.Image != null)
pictureBox1.Image.Dispose();
pictureBox1.Image = selectedImage;
}
}
private void pictureBox2_Click(object sender, EventArgs e)
{
using OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Image Files (*.bmp, *.jpg, *.png)|*.bmp;*.jpg;*.png";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
selectedImagePath2 = openFileDialog.FileName;
Image selectedImage = Image.FromFile(selectedImagePath2);
if (pictureBox2.Image != null)
pictureBox2.Image.Dispose();
pictureBox2.Image = selectedImage;
}
}
private void Set()
{
//加载两张图片
using Mat image1 = Cv2.ImRead(selectedImagePath1);
using Mat image2 = Cv2.ImRead(selectedImagePath2);
using Mat result_image = image2.Clone();
// 调整图像尺寸使其匹配
if (image1.Size() != image2.Size())
{
Cv2.Resize(image1, image1, image2.Size());
}// 调整图像通道数使其匹配
if (image1.Channels() != image2.Channels())
{
if (image1.Channels() == 1 && image2.Channels() == 3)
{
Cv2.CvtColor(image1, image1, ColorConversionCodes.GRAY2BGR);
}
else if (image1.Channels() == 3 && image2.Channels() == 1)
{
Cv2.CvtColor(image2, image2, ColorConversionCodes.GRAY2BGR);
}
}
//创建一个空的Mat对象用于存储差异
using Mat difference = new Mat();
//计算两张图片的差异
Cv2.Absdiff(image1, image2, difference);
//模糊
Cv2.Blur(difference, difference, new OpenCvSharp.Size(5, 5));
//转换为灰度图
Cv2.CvtColor(difference, difference, ColorConversionCodes.BGR2GRAY);
//膨胀5次
using Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.Dilate(difference, difference, kernel, null, 5);
//二值化
Cv2.Threshold(difference, difference, 20, 200, ThresholdTypes.Binary);
//找出轮廓
OpenCvSharp.Point[][] contours = null;
HierarchyIndex[] hierarchly;
Cv2.FindContours(difference, out contours, out hierarchly, RetrievalModes.External, ContourApproximationModes.ApproxNone, new OpenCvSharp.Point(0, 0));
Rect rect;
for (int i = 0; i < contours.Length; i++)
{
rect = Cv2.BoundingRect(contours[i]);
Cv2.Rectangle(result_image, rect, new Scalar(0, 255, 0), 2, LineTypes.Link8);
}
if (pictureBox3.Image != null)
pictureBox3.Image.Dispose();
pictureBox3.Image = new Bitmap(result_image.ToMemoryStream());
}
private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(selectedImagePath1) || string.IsNullOrEmpty(selectedImagePath2))
{
MessageBox.Show("请选择图片");
return;
}
Set();
}
}