好的,以下是C#窗体OpenCvSharp绘制图像轮廓与凸包、图像修补、绘制直方图及直方图对比的示例代码:
```csharp
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace OpenCvSharpDemo
{
public partial class MainForm : Form
{
private readonly Mat _srcImage;
private Mat _grayImage;
private Mat _binaryImage;
public MainForm()
{
InitializeComponent();
// 加载图像
_srcImage = Cv2.ImRead("test.jpg");
// 显示原图
pictureBox1.Image = BitmapConverter.ToBitmap(_srcImage);
}
private void button1_Click(object sender, EventArgs e)
{
// 转化为灰度图像
_grayImage = _srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
// 显示灰度图像
pictureBox1.Image = BitmapConverter.ToBitmap(_grayImage);
}
private void button2_Click(object sender, EventArgs e)
{
// 二值化图像
_binaryImage = _grayImage.Threshold(0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
// 显示二值化图像
pictureBox1.Image = BitmapConverter.ToBitmap(_binaryImage);
}
private void button3_Click(object sender, EventArgs e)
{
// 查找轮廓
var contours = _binaryImage.FindContoursAsArray(RetrievalModes.External, ContourApproximationModes.ApproxSimple);
// 绘制轮廓
var dstImage = _srcImage.Clone();
dstImage.DrawContours(contours, -1, Scalar.Red, 2);
// 显示绘制后的图像
pictureBox1.Image = BitmapConverter.ToBitmap(dstImage);
}
private void button4_Click(object sender, EventArgs e)
{
// 查找轮廓
var contours = _binaryImage.FindContoursAsArray(RetrievalModes.External, ContourApproximationModes.ApproxSimple);
// 查找凸包
var hulls = contours.Select(c => Cv2.ConvexHull(c)).ToList();
// 绘制凸包
var dstImage = _srcImage.Clone();
for (var i = 0; i < contours.Length; i++)
{
dstImage.DrawContours(new[] { hulls[i] }, -1, Scalar.Green, 2);
}
// 显示绘制后的图像
pictureBox1.Image = BitmapConverter.ToBitmap(dstImage);
}
private void button5_Click(object sender, EventArgs e)
{
// 查找轮廓
var contours = _binaryImage.FindContoursAsArray(RetrievalModes.External, ContourApproximationModes.ApproxSimple);
// 查找最大轮廓
var maxContour = contours.OrderByDescending(c => c.ContourArea()).First();
// 创建掩膜图像
var mask = new Mat(_binaryImage.Size(), MatType.CV_8UC1, Scalar.White);
mask.DrawContours(new[] { maxContour }, -1, Scalar.Black, -1);
// 修补图像
var dstImage = _srcImage.Clone();
Cv2.Inpaint(dstImage, mask, dstImage, 3, InpaintMethod.Telea);
// 显示修补后的图像
pictureBox1.Image = BitmapConverter.ToBitmap(dstImage);
}
private void button6_Click(object sender, EventArgs e)
{
// 计算直方图
var hist = new Mat();
Cv2.CalcHist(new[] { _srcImage }, new[] { 0 }, null, hist, 1, new[] { 256 }, new[] { new[] { 0, 256 } });
// 绘制直方图
var histImage = new Mat(new Size(512, 400), MatType.CV_8UC3, Scalar.White);
Cv2.Normalize(hist, hist, 0, histImage.Rows, NormTypes.MinMax);
var binWidth = (int)(histImage.Cols / 256.0);
for (var i = 1; i < 256; i++)
{
var x1 = (i - 1) * binWidth;
var y1 = histImage.Rows - (int)hist.Get<float>(i - 1);
var x2 = i * binWidth;
var y2 = histImage.Rows - (int)hist.Get<float>(i);
histImage.Line(new Point(x1, y1), new Point(x2, y2), Scalar.Black, 2);
}
// 显示绘制后的直方图
pictureBox1.Image = BitmapConverter.ToBitmap(histImage);
}
private void button7_Click(object sender, EventArgs e)
{
// 加载对比图像
var dstImage = Cv2.ImRead("test2.jpg");
// 计算对比直方图
var srcHist = new Mat();
Cv2.CalcHist(new[] { _srcImage }, new[] { 0 }, null, srcHist, 1, new[] { 256 }, new[] { new[] { 0, 256 } });
var dstHist = new Mat();
Cv2.CalcHist(new[] { dstImage }, new[] { 0 }, null, dstHist, 1, new[] { 256 }, new[] { new[] { 0, 256 } });
// 计算直方图相似度
var similarity = Cv2.CompareHist(srcHist, dstHist, HistCompMethods.Correl);
// 显示相似度
MessageBox.Show($"相似度:{similarity:F2}");
}
}
}
```
其中,各个按钮的功能如下:
- “灰度化”按钮:将原图像转化为灰度图像并显示;
- “二值化”按钮:将灰度图像转化为二值图像并显示;
- “绘制轮廓”按钮:在原图像上绘制轮廓并显示;
- “绘制凸包”按钮:在原图像上绘制轮廓的凸包并显示;
- “图像修补”按钮:对原图像进行修补并显示;
- “绘制直方图”按钮:计算原图像的直方图并绘制并显示;
- “直方图对比”按钮:计算原图像与对比图像的直方图相似度并显示。
注释已经在代码中添加,希望对您有所帮助。