C#窗体OpenCvSharp绘制图像轮廓与凸包、图像修补、绘制直方图及直方图对比并附上注释
时间: 2023-08-31 13:11:57 浏览: 47
以下是C#窗体OpenCvSharp绘制图像轮廓与凸包、图像修补、绘制直方图及直方图对比的代码,并附上注释:
```csharp
using OpenCvSharp;
// 绘制图像轮廓与凸包
private void DrawContoursAndConvexHull(Mat srcImage)
{
// 转换为灰度图像
Mat grayImage = new Mat();
Cv2.CvtColor(srcImage, grayImage, ColorConversionCodes.BGR2GRAY);
// 对图像进行边缘检测
Mat edges = new Mat();
Cv2.Canny(grayImage, edges, 50, 150);
// 查找轮廓并绘制
Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(edges, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
Mat resultImage = new Mat(srcImage.Size(), MatType.CV_8UC3, Scalar.All(0));
for (int i = 0; i < contours.Length; i++)
{
// 绘制轮廓
Cv2.DrawContours(resultImage, contours, i, Scalar.RandomColor(), 2);
// 计算凸包并绘制
Point[] hull = Cv2.ConvexHull(contours[i]);
Cv2.Polylines(resultImage, new Point[][] { hull }, true, Scalar.RandomColor(), 2);
}
// 显示结果
Cv2.ImShow("Contours and Convex Hull", resultImage);
}
// 图像修补
private void Inpaint(Mat srcImage)
{
// 克隆原始图像
Mat inpaintImage = srcImage.Clone();
// 对图像进行处理
Mat grayImage = new Mat();
Cv2.CvtColor(inpaintImage, grayImage, ColorConversionCodes.BGR2GRAY);
Mat edges = new Mat();
Cv2.Canny(grayImage, edges, 50, 150);
Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(edges, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
foreach (var contour in contours)
{
Point[] hull = Cv2.ConvexHull(contour);
Rect rect = Cv2.BoundingRect(hull);
Mat mask = new Mat(srcImage.Size(), MatType.CV_8UC1, Scalar.All(0));
Cv2.DrawContours(mask, new Point[][] { hull }, -1, Scalar.All(255), -1);
Mat dst = new Mat();
Cv2.Inpaint(inpaintImage[rect], mask[rect], dst, 3, InpaintMethod.Telea);
dst.CopyTo(inpaintImage[rect]);
}
// 显示结果
Cv2.ImShow("Inpaint", inpaintImage);
}
// 绘制直方图
private void DrawHistogram(Mat srcImage)
{
// 将图像转换为灰度图像
Mat grayImage = new Mat();
Cv2.CvtColor(srcImage, grayImage, ColorConversionCodes.BGR2GRAY);
// 分离通道
Mat[] channels = Cv2.Split(srcImage);
// 计算直方图
int[] histSize = { 256 };
float[] ranges = { 0, 256 };
int histHeight = 256;
int histWidth = 512;
int binWidth = (int)Math.Round((double)histWidth / histSize[0]);
Mat histImage = new Mat(histHeight, histWidth, MatType.CV_8UC3, Scalar.All(0));
for (int i = 0; i < channels.Length; i++)
{
Mat hist = new Mat();
Cv2.CalcHist(new Mat[] { channels[i] }, new int[] { 0 }, null, hist, 1, histSize, new Rangef[] { new Rangef(ranges[0], ranges[1]) });
Cv2.Normalize(hist, hist, 0, histImage.Rows, NormTypes.MinMax);
for (int j = 1; j < histSize[0]; j++)
{
Point p1 = new Point(binWidth * (j - 1), histHeight - (int)Math.Round(hist.At<float>(j - 1)));
Point p2 = new Point(binWidth * j, histHeight - (int)Math.Round(hist.At<float>(j)));
Cv2.Line(histImage, p1, p2, Scalar.All(255), 2, LineTypes.AntiAlias, 0);
}
}
// 显示结果
Cv2.ImShow("Histogram", histImage);
}
// 绘制直方图对比
private void DrawHistogramComparison(Mat srcImage1, Mat srcImage2)
{
// 将图像转换为灰度图像
Mat grayImage1 = new Mat();
Cv2.CvtColor(srcImage1, grayImage1, ColorConversionCodes.BGR2GRAY);
Mat grayImage2 = new Mat();
Cv2.CvtColor(srcImage2, grayImage2, ColorConversionCodes.BGR2GRAY);
// 分离通道
Mat[] channels1 = Cv2.Split(srcImage1);
Mat[] channels2 = Cv2.Split(srcImage2);
// 计算直方图
int[] histSize = { 256 };
float[] ranges = { 0, 256 };
int histHeight = 256;
int histWidth = 512;
int binWidth = (int)Math.Round((double)histWidth / histSize[0]);
Mat histImage1 = new Mat(histHeight, histWidth, MatType.CV_8UC3, Scalar.All(0));
Mat histImage2 = new Mat(histHeight, histWidth, MatType.CV_8UC3, Scalar.All(0));
for (int i = 0; i < channels1.Length; i++)
{
Mat hist1 = new Mat();
Cv2.CalcHist(new Mat[] { channels1[i] }, new int[] { 0 }, null, hist1, 1, histSize, new Rangef[] { new Rangef(ranges[0], ranges[1]) });
Cv2.Normalize(hist1, hist1, 0, histImage1.Rows, NormTypes.MinMax);
Mat hist2 = new Mat();
Cv2.CalcHist(new Mat[] { channels2[i] }, new int[] { 0 }, null, hist2, 1, histSize, new Rangef[] { new Rangef(ranges[0], ranges[1]) });
Cv2.Normalize(hist2, hist2, 0, histImage2.Rows, NormTypes.MinMax);
for (int j = 1; j < histSize[0]; j++)
{
Point p1 = new Point(binWidth * (j - 1), histHeight - (int)Math.Round(hist1.At<float>(j - 1)));
Point p2 = new Point(binWidth * j, histHeight - (int)Math.Round(hist1.At<float>(j)));
Cv2.Line(histImage1, p1, p2, Scalar.All(255), 2, LineTypes.AntiAlias, 0);
p1 = new Point(binWidth * (j - 1), histHeight - (int)Math.Round(hist2.At<float>(j - 1)));
p2 = new Point(binWidth * j, histHeight - (int)Math.Round(hist2.At<float>(j)));
Cv2.Line(histImage2, p1, p2, Scalar.All(255), 2, LineTypes.AntiAlias, 0);
}
}
// 显示结果
Cv2.ImShow("Histogram Comparison 1", histImage1);
Cv2.ImShow("Histogram Comparison 2", histImage2);
}
```
注释中已对每个函数进行了简要说明,这里不再赘述。需要注意的是,在使用这些函数之前,你需要在项目中引用OpenCvSharp库,并在代码中添加如下using语句:
```csharp
using OpenCvSharp;
```
另外,在窗体中使用这些函数时,你需要先将图像转换为Mat类型,然后再传入相应的函数中。例如,你可以在窗体的PictureBox控件中显示一张图像,然后在按钮的Click事件中调用相应的函数:
```csharp
private void btnDrawContoursAndConvexHull_Click(object sender, EventArgs e)
{
Mat srcImage = BitmapConverter.ToMat((Bitmap)pictureBox1.Image);
DrawContoursAndConvexHull(srcImage);
}
private void btnInpaint_Click(object sender, EventArgs e)
{
Mat srcImage = BitmapConverter.ToMat((Bitmap)pictureBox1.Image);
Inpaint(srcImage);
}
private void btnDrawHistogram_Click(object sender, EventArgs e)
{
Mat srcImage = BitmapConverter.ToMat((Bitmap)pictureBox1.Image);
DrawHistogram(srcImage);
}
private void btnDrawHistogramComparison_Click(object sender, EventArgs e)
{
Mat srcImage1 = BitmapConverter.ToMat((Bitmap)pictureBox1.Image);
Mat srcImage2 = BitmapConverter.ToMat((Bitmap)pictureBox2.Image);
DrawHistogramComparison(srcImage1, srcImage2);
}
```
这里使用了BitmapConverter.ToMat函数将PictureBox控件中的图像转换为Mat类型。
相关推荐
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)