实例介绍
【实例简介】
【实例截图】
【核心代码】
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using Sunny.UI;
namespace OpenCVSharpPictureDeal
{
public partial class Form1 : UIForm
{
public Form1()
{
InitializeComponent();
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
}
private Image image = null;
private Mat dst = new Mat();
private Mat src_img;
string filePath = "";
//private static int Num = 20;
private List<Mat> reList = new List<Mat>();
private int step = 1;
private void openImage_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "选择操作的图片";
openFileDialog.Filter = "图片 *.jpg|*.jpg|图像*.png|*.png";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
image = Image.FromFile(filePath);
src_img = Cv2.ImRead(filePath);
Mat tem1 = new Mat();
src_img.CopyTo(tem1);
if (reList.Count > 0)
{
reList[0] = tem1;
}
else
{
reList.Add(tem1);
}
}
if (filePath != "")
{
picBoxShowDel.Image = image;
picShowOri.Image = image;
}
}
private void meanKernel_Scroll(object sender, EventArgs e)
{
if (meanKernelX.Value < 1)
{
meanKernelX.Value = 1;
}
Blur();
}
/// <summary>
/// 中值滤波
/// </summary>
private void Blur()
{
OpenCvSharp.Point point = new OpenCvSharp.Point(SharpPoint.Value, SharpPoint.Value);
Cv2.Blur(src_img, dst, new OpenCvSharp.Size(meanKernelX.Value, meanKernelY.Value), point);
picBoxShowDel.Image = dst.ToBitmap();
}
/// <summary>
/// 高斯滤波
/// </summary>
private void GaussianBlur()
{
Cv2.GaussianBlur(src_img, dst, new OpenCvSharp.Size(gussX.Value, gussY.Value), gussPX.Value, gussPY.Value); //高斯模
picBoxShowDel.Image = dst.ToBitmap();
}
/// <summary>
/// 均值滤波
/// </summary>
private void MedianBlur()
{
Cv2.MedianBlur(src_img, dst, MedianBlurValue.Value); //中值滤波。参数:1,输入;2,输出;3,卷积核,大于1的奇数
picBoxShowDel.Image = dst.ToBitmap();
}
/// <summary>
/// 透视转换
/// </summary>
private void WarpPerspective()
{
var srcPoints = new Point2f[] //指定变换前的四角点 //手工测量的坐标位置,实际使用中可以通过鼠标获取
{
new Point2f(Points[0].X,Points[0].Y),
new Point2f(Points[1].X,Points[1].Y),
new Point2f(Points[3].X,Points[3].Y),
new Point2f(Points[2].X,Points[2].Y),
//new Point2f(0,0),
//new Point2f(src_img.Width-1,0),
//new Point2f(0,src_img.Height-1),
//new Point2f(src_img.Width-1,src_img.Height-1),
};
int x = Math.Abs(Points[0].X - Points[1].X);
int y = Math.Abs(Points[0].Y - Points[1].Y);
int width = (int)Math.Sqrt(x * x y * y);
x = Math.Abs(Points[2].X - Points[1].X);
y = Math.Abs(Points[2].Y - Points[1].Y);
int height = (int)Math.Sqrt(x * x y * y);
//OpenCvSharp.Size size = new OpenCvSharp.Size(width 100,height 100);
var dstPoints = new Point2f[] ////指定变换后的四角点
{
new Point2f(Points[3].X,Points[0].Y),
new Point2f(Points[2].X,Points[0].Y),
new Point2f(Points[3].X,Points[3].Y),
new Point2f(Points[2].X,Points[3].Y),
//new Point2f(0,0),
//new Point2f(width,0),
//new Point2f(0,height),
//new Point2f(width,height),
};
try
{
Mat TransformMatrix = Cv2.GetPerspectiveTransform(srcPoints, dstPoints); //根据变换前后四个角点坐标,计算变换矩阵
Cv2.WarpPerspective(src_img, dst, TransformMatrix, src_img.Size()); //透视变换函数
picBoxShowDel.Image = dst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 颜色转换
/// </summary>
private void CVTColor()
{
if (cmBoxCVTColor.Text == "")
{
return;
}
ColorConversionCodes aaa = (ColorConversionCodes)Enum.Parse(typeof(ColorConversionCodes), cmBoxCVTColor.Text);
try
{
Cv2.CvtColor(src_img, dst, aaa); //转换为灰度图
picBoxShowDel.Image = dst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 二值化
/// </summary>
private void Threshold()
{
if (cmBoxThre.Text == "")
{
return;
}
ThresholdTypes aaa = (ThresholdTypes)Enum.Parse(typeof(ThresholdTypes), cmBoxThre.Text);
try
{
Cv2.Threshold(src_img, dst, tkBarThresh.Value, tkBarMaxValue.Value, aaa);//阈值二值化
picBoxShowDel.Image = dst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 膨胀 腐蚀
/// </summary>
private void Dilate()
{
if (cmBoxMorph.Text == "")
{
return;
}
try
{
OpenCvSharp.Point point = new OpenCvSharp.Point(SharpPoint.Value, SharpPoint.Value);
MorphShapes aaa = (MorphShapes)Enum.Parse(typeof(MorphShapes), cmBoxMorph.Text);
Mat structuringElement = Cv2.GetStructuringElement(aaa, new OpenCvSharp.Size(tkBarPZFS.Value, tkBarPZFS.Value), point);
/* 参数 1,MorphShapes shape 结果元素的形状
2,Size ksize 结构元素的大小
3,Point anchor 结构元素的锚点(中心点)
*/
if (rdBtnPZ.Checked)
{
Cv2.Dilate(src_img, dst, structuringElement, point, DilateCount.Value); //膨胀
/* 参数:1, 源图像
2, 输出图像
3, 结构元素,奇数
4, 锚点位置,默认是null
5, 应用膨胀的次数。[默认情况下这是1] */
}
else
{
Cv2.Erode(src_img, dst, structuringElement, point, DilateCount.Value); //腐蚀
/* 参数:1,源图像 2,输出图像 3,结构元素,奇数 4, 锚点位置,默认是null 5,应用膨胀的次数。[默认情况下这是1] */
}
picBoxShowDel.Image = dst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 开闭\运算 顶帽 黑帽。。。、
/// </summary>
private void MorphologyEx()
{
if (cmBoxMorphologyEx.Text == "")
{
return;
}
if (cmBoxMorphType.Text == "")
{
return;
}
MorphShapes aaa = (MorphShapes)Enum.Parse(typeof(MorphShapes), cmBoxMorphologyEx.Text);
MorphTypes bbb = (MorphTypes)Enum.Parse(typeof(MorphTypes), cmBoxMorphType.Text);
OpenCvSharp.Point point = new OpenCvSharp.Point(SharpPoint.Value, SharpPoint.Value);
try
{
InputArray kernel = Cv2.GetStructuringElement(aaa, new OpenCvSharp.Size(tkBarMorphology.Value, tkBarMorphology.Value), point); //结构元素
/* 参数 1,MorphShapesshape 结果元素的形状
2,Sizeksize 结构元素的大小
3,Pointanchor结构元素的锚点(中心点) */
Cv2.MorphologyEx(src_img, dst, bbb, kernel, point, MorpholoCount.Value); //形态学运算
/* 参数 1,源图像 2, 输出图像 3, 形态操作类型 4, 结构数组 5, 锚点位置(中心点)
6, 应用腐蚀和膨胀的次数。[默认情况下这是1] 7, 边缘处理方法
*/
picBoxShowDel.Image = dst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 边缘检测Canny
/// </summary>
private void Canny()
{
int hole = 0;
if (!int.TryParse(txtBoxCannyHole.Text, out hole))
{
return;
}
try
{
Cv2.Canny(src_img, dst, tkBarCannyMin.Value, tkBarCannyMax.Value, hole, rbBtnTrue.Checked);
//cannny算子。参数:1,8 bit 输入图像;2,输出边缘图像,一般是二值图像,背景是黑色;3,低阈值。值越大,找到的边缘越少;4,高阈值;5,表示应用Sobel算子的孔径大小,其有默认值3;6,计算图像梯度幅值的标识,有默认值false。
//低于阈值1的像素点会被认为不是边缘;
//高于阈值2的像素点会被认为是边缘;
//在阈值1和阈值2之间的像素点,若与一阶偏导算子计算梯度得到的边缘像素点相邻,则被认为是边缘,否则被认为不是边缘。
picBoxShowDel.Image = dst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 霍夫变换之 直线检测
/// </summary>
private void HoughLinesP()
{
try
{
LineSegmentPoint[] lineSegmentPoint;
src_img.CopyTo(dst);
lineSegmentPoint = Cv2.HoughLinesP(dst, tkBarFBL.Value, Cv2.PI / 180, tkBarThreshold.Value, tkBarMinLength.Value, tkBarMaxGap.Value);
/*使用概率霍夫变换查找二进制图像中的线段。最终输出的是直线的两个点坐标,返回值类型:LineSegmentPoint[]
参数:1,输入图像,8位、单通道、二进制源图像。
2,累加器的距离分辨率(以像素为单位),(生成极坐标时的像素扫描的步长)
3,累加器的角度分辨率(以弧度为单位) (生成极坐标的角度步长,一般为 1°)
4,阈值参数,只有获取足够交点的极坐标才能看作直线
5,最小线长度。比这短的线段将被拒绝。[默认值为0]
6,同一条线上的点之间连接它们的最大允许间隙。[默认值为0] */
Mat ndst = new Mat();
reList[0].CopyTo(ndst);
for (int i = 0; i < lineSegmentPoint.Length; i )
{
Cv2.Line(ndst, lineSegmentPoint[i].P1, lineSegmentPoint[i].P2, Scalar.Red, 6); //依据点集画线
}
picBoxShowDel.Image = ndst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// <summary>
/// 霍夫变换之 圆检测
/// </summary>
private void HoughCircle()
{
try
{
src_img.CopyTo(dst);
CircleSegment[] circleSegment;
circleSegment = Cv2.HoughCircles(dst, HoughModes.Gradient, tkBarDP.Value, tkBarMinDist.Value, tkBarParam1.Value, tkBarParam2.Value, tkBarMinRadius.Value, tkBarMaxRadius.Value);
//霍夫圆检测:使用霍夫变换查找灰度图像中的圆。
/*
* 参数:
* 1:输入参数:8位、单通道、灰度输入图像
* 2:实现方法
* 3: dp :累加器分辨率与图像分辨率的反比。默认=1
* 4:minDist: 检测到的圆的中心之间的最小距离。
* 5:param1: 第一个方法特定的参数。[默认值是100]canny边缘检测阈值低
* 6:param2: 第二个方法特定于参数。[默认值是100]中心点累加器阈值 – 候选圆心
* 7:minRadius: 最小半径
* 8:maxRadius: 最大半径 */
Mat ndst = new Mat();
reList[0].CopyTo(ndst);
for (int i = 0; i < circleSegment.Count(); i )
{
//画圆、圆心
Cv2.Circle(ndst, (int)circleSegment[i].Center.X, (int)circleSegment[i].Center.Y, (int)circleSegment[i].Radius, Scalar.Red, 2, LineTypes.AntiAlias);
Cv2.Circle(ndst, (int)circleSegment[i].Center.X, (int)circleSegment[i].Center.Y, 3, Scalar.Red, 2, LineTypes.AntiAlias);
}
picBoxShowDel.Image = ndst.ToBitmap();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private void meanKernelY_Scroll(object sender, EventArgs e)
{
if (meanKernelY.Value < 1)
{
meanKernelY.Value = 1;
}
Blur();
}
private bool TranFlag = false;
private void uiButton1_Click(object sender, EventArgs e)
{
if (btnTransf.Text == "开始转换")
{
TranFlag = true;
this.picBoxShowDel.Cursor = Cursors.Cross;
btnTransf.Text = "结束转换";
btnTransf.Style = UIStyle.Red;
}
else
{
pointCount = 0;
TranFlag = false;
this.picBoxShowDel.Cursor = Cursors.Default;
btnTransf.Text = "开始转换";
btnTransf.Style = UIStyle.Blue;
this.picBoxShowDel.Refresh();
}
}
private void gussX_Scroll(object sender, EventArgs e)
{
if (gussX.Value % 2 == 0)
{
gussX.Value = 1;
}
GaussianBlur();
}
private void gussY_Scroll(object sender, EventArgs e)
{
if (gussY.Value % 2 == 0)
{
gussY.Value = 1;
}
GaussianBlur();
}
private void gussPX_ValueChanged(object sender, int value)
{
if (gussPX.Value < 0)
{
gussPX.Value = 0;
}
GaussianBlur();
}
private void gussPY_ValueChanged(object sender, int value)
{
if (gussPY.Value < 0)
{
gussPY.Value = 0;
}
GaussianBlur();
}
private void MedianBlurValue_Scroll(object sender, EventArgs e)
{
if (MedianBlurValue.Value % 2 == 0)
{
MedianBlurValue.Value = 1;
}
MedianBlur();
}
private System.Drawing.Point[] Points = new System.Drawing.Point[4];
private int pointCount = 0;
private void picBoxShowDel_MouseMove(object sender, MouseEventArgs e)
{
if (pointCount > 0 && pointCount < 4)
{
Points[pointCount] = e.Location;
Console.WriteLine(Points[pointCount].X "---" Points[pointCount].Y);
PritLine();
}
else if (pointCount > 3)
{
pointCount = 0;
WarpPerspective();
TranFlag = false;
this.picBoxShowDel.Cursor = Cursors.Default;
btnTransf.Text = "开始转换";
btnTransf.Style = UIStyle.Blue;
}
}
private void picBoxShowDel_MouseDown(object sender, MouseEventArgs e)
{
if (TranFlag == true)
{
Points[pointCount] = e.Location;
Console.WriteLine(Points[pointCount].X "******" Points[pointCount].Y);
pointCount ;
}
}
private void picBoxShowDel_MouseUp(object sender, MouseEventArgs e)
{
}
private void PritLine()
{
Graphics g = this.picBoxShowDel.CreateGraphics();//创建GDI对像
//创建画笔(颜色)
Pen npen = new Pen(Brushes.Red);
Refresh();
for (int i = 0; i < pointCount - 1; i )
{
g.DrawLine(npen, Points[i], Points[i 1]);
}
//创建两个点
g.DrawLine(npen, Points[pointCount - 1], Points[pointCount]);
g.DrawString(Points[pointCount].X "," Points[pointCount].Y,new Font(FontFamily.GenericSansSerif, 9,FontStyle.Italic),Brushes.DarkSalmon, Points[pointCount]);
}
string[] names = System.Enum.GetNames(typeof(ColorConversionCodes));
private string[] thresholdTypes = Enum.GetNames(typeof(ThresholdTypes));
private string[] morphShapes = Enum.GetNames(typeof(MorphShapes));
private string[] morphTypes = Enum.GetNames(typeof(MorphTypes));
private void Form1_Load(object sender, EventArgs e)
{
cmBoxCVTColor.Items.AddRange(names);
cmBoxThre.Items.AddRange(thresholdTypes);
cmBoxMorph.Items.AddRange(morphShapes);
cmBoxMorphologyEx.Items.AddRange(morphShapes);
cmBoxMorphType.Items.AddRange(morphTypes);
}
private void cmBoxCVTColor_SelectedIndexChanged(object sender, EventArgs e)
{
CVTColor();
}
private void cmBoxThre_SelectedIndexChanged(object sender, EventArgs e)
{
Threshold();
}
private void tkBarThresh_Scroll(object sender, EventArgs e)
{
Threshold();
}
private void tkBarMaxValue_Scroll(object sender, EventArgs e)
{
Threshold();
}
private void cmBoxMorph_SelectedIndexChanged(object sender, EventArgs e)
{
Dilate();
}
private void tkBarPZFS_Scroll(object sender, EventArgs e)
{
if (tkBarPZFS.Value % 2 == 0)
{
tkBarPZFS.Value = 1;
}
Dilate();
}
private void DilateCount_ValueChanged(object sender, int value)
{
if (DilateCount.Value < 1)
{
DilateCount.Value = 1;
}
Dilate();
}
private void MorpholoCount_ValueChanged(object sender, int value)
{
if (MorpholoCount.Value < 1)
{
MorpholoCount.Value = 1;
}
MorphologyEx();
}
private void cmBoxMorphologyEx_SelectedIndexChanged(object sender, EventArgs e)
{
MorphologyEx();
}
private void tkBarMorphology_Scroll(object sender, EventArgs e)
{
if (tkBarMorphology.Value < 1)
{
tkBarMorphology.Value = 1;
}
MorphologyEx();
}
private void cmBoxMorphType_SelectedIndexChanged(object sender, EventArgs e)
{
MorphologyEx();
}
private void btnSave_Click(object sender, EventArgs e)
{
if (dst.Rows == 0)
{
return;
}
Mat tem = new Mat();
dst.CopyTo(tem);
dst.CopyTo(src_img);
reList.Add(tem);
if (reList.Count > 1 && btnReturn.Enabled == false)
{
btnReturn.Enabled = true;
}
btnReturn.Text = (reList.Count - 1).ToString();
//step ;
}
private void btnReturn_Click(object sender, EventArgs e)
{
if (reList.Count > 1)
{
Mat tem = reList[reList.Count - 2];
tem.CopyTo(src_img);
tem.CopyTo(dst);
picBoxShowDel.Image = tem.ToBitmap();
if (reList.Count > 1)
{
reList.RemoveAt(reList.Count - 1);
}
btnReturn.Text = (reList.Count - 1).ToString();
}
if (reList.Count == 1)
{
btnReturn.Enabled = false;
}
}
private void rbBtnTrue_CheckedChanged(object sender, EventArgs e)
{
Canny();
}
private void tkBarCannyMin_Scroll(object sender, EventArgs e)
{
if (tkBarCannyMin.Value < 0)
{
tkBarCannyMin.Value = 0;
}
Canny();
}
private void tkBarCannyMax_Scroll(object sender, EventArgs e)
{
if (tkBarCannyMax.Value < 0)
{
tkBarCannyMax.Value = 0;
}
Canny();
}
private void tkBarFBL_ValueChanged(object sender, EventArgs e)
{
HoughLinesP();
}
private void tkBarThreshold_ValueChanged(object sender, EventArgs e)
{
HoughLinesP();
}
private void tkBarMinLength_ValueChanged(object sender, EventArgs e)
{
HoughLinesP();
}
private void tkBarMaxGap_ValueChanged(object sender, EventArgs e)
{
HoughLinesP();
}
private void tkBarDP_Scroll(object sender, EventArgs e)
{
HoughCircle();
}
private void tkBarMinDist_Scroll(object sender, EventArgs e)
{
HoughCircle();
}
private void tkBarParam1_Scroll(object sender, EventArgs e)
{
HoughCircle();
}
private void tkBarParam2_Scroll(object sender, EventArgs e)
{
HoughCircle();
}
private void tbBarMinRadius_Scroll(object sender, EventArgs e)
{
HoughCircle();
}
private void tbBarMaxRadius_Scroll(object sender, EventArgs e)
{
HoughCircle();
}
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论