OpenCVSharp是OpenCV的.NET wrapper,是一名日本工程师开发的,项目地址为:https://github.com/shimat/opencvsharp。

该源码是 BSD开放协议,BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布或商业化销售。

1.OpenCVSharp的下载

可以直接从上面的github上下载源码,自行编译引用;

也可用vs中的nuget包管理器下载;

打开【工具】->【库程序包管理器】->【管理解决方案的NuGet程序包】,在其中搜索OpenCVSharp,选择合适的点击【安装】(最好安装最新的)。一直等待完成。

我的环境是vs2017,下载之后最好直接拷贝OpenCVSharp系列dll到项目中引用即可。

2.拟合圆并求取圆心

本次举例比较贴近实际,我们求如下原始图片的中间部分圆的圆心,选取的图片故意只留了一半:

源码如下:

using OpenCvSharp;

namespace FitCircleDemo
{
public class CircleFit
{
public Mat Run(string imgPath)
{
//读取图片
//var img = Cv2.ImRead("Data/Image/c1.bmp");
var img = Cv2.ImRead(imgPath);
//显示图片
//Cv2.ImShow("Input Image", img); //转换成灰度图
Mat gray = img.CvtColor(ColorConversionCodes.BGR2GRAY); //阈值操作 阈值参数可以用一些可视化工具来调试得到
Mat ThresholdImg = gray.Threshold(, , ThresholdTypes.Binary);
Cv2.ImShow("Threshold", ThresholdImg); //降噪
//方法一:高斯变化
//Mat gaussImg= ThresholdImg.GaussianBlur(new Size(5, 5), 0.8);
//Cv2.ImShow("GaussianBlur", gaussImg);
//方法二:中值滤波降噪
//Mat medianImg = ThresholdImg.MedianBlur(5);
//Cv2.ImShow("MedianBlur", medianImg); //方法三:膨胀+腐蚀
////膨胀处理
//Mat kernel = new Mat(15, 15, MatType.CV_8UC1);
//Mat DilateImg = ThresholdImg.Dilate(kernel);
////腐蚀处理
//Mat binary = DilateImg.Erode(kernel);
////显示中间结果
//Cv2.ImShow("Dilate & Erode", binary);
Mat element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(, ));
Mat openImg = ThresholdImg.MorphologyEx(MorphTypes.Open, element);
Cv2.ImShow("Dilate & Erode", openImg); //设置感兴趣的区域
int x = , y = , w = , h = ;
Rect roi = new Rect(x, y, w, h);
Mat ROIimg = new Mat(openImg, roi);
//Cv2.ImShow("ROI Image", ROIimg); //寻找图像轮廓
Point[][] contours;
HierarchyIndex[] hierachy;
Cv2.FindContours(ROIimg, out contours, out hierachy, RetrievalModes.List, ContourApproximationModes.ApproxTC89KCOS);
//根据找到的轮廓点,拟合椭圆
for (int i = ; i < contours.Length; i++)
{
//拟合函数必须至少5个点,少于则不拟合
if (contours[i].Length < ) continue;
//椭圆拟合
var rrt = Cv2.FitEllipse(contours[i]); //ROI复原
rrt.Center.X += x;
rrt.Center.Y += y; //画椭圆
Cv2.Ellipse(img, rrt, new Scalar(, , ), , LineTypes.AntiAlias);
//画圆心
Cv2.Circle(img, (int)(rrt.Center.X), (int)(rrt.Center.Y), , new Scalar(, , ), -, LineTypes.Link8, );
} Cv2.ImShow("Fit Circle", img);
return img;
}
}
}

中间处理过程效果图如下:

分别是阈值分割后,中值滤波后,拟合圆之后

对上图中第一张进行降噪方法有很多,经测试最有效的是中值滤波(MedianBlur)和腐蚀&膨胀(MorphologyEx)处理

中值滤波基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,让周围的像素值接近真实的值从而消除孤立的噪声点。

高级形态学变换:
开运算:
先腐蚀,再膨胀,可清除一些小东西(亮的),放大局部低亮度的区域
闭运算:
先膨胀,再腐蚀,可清除小黑点
形态学梯度:
膨胀图与腐蚀图之差,提取物体边缘
顶帽:
原图像-开运算图,突出原图像中比周围亮的区域
黑帽:
闭运算图-原图像,突出原图像中比周围暗的区域

1.腐蚀
首先说腐蚀,腐蚀是缩小图像,去除小沟壑细节的一种操作,腐蚀的概念很好理解,但是公式看起来却很麻烦,我这里主要说概念。
腐蚀操作需要两个元素,一个待处理对象A,一个element B,B对A的腐蚀得到的结果是由A中能够包含整个B的像素点所组成的,如下图所示:

其中比较关键的是B的锚点,就是B的锚点在A中扫描时,A能将B完全包住的B的锚点所扫描的像素点。

腐蚀的作用:去除图像中不想要的小细节,比如一张二值图片中的噪点或者小细节。
符号:⊖ \ominus⊖

2.膨胀
膨胀的需要与腐蚀完全相同只是他们的作用相反,element B膨胀图形A的结果是,A和B的并集产生的,如下:

B的锚点在A的边界进行扫描,A与B的并集就是B对A进行膨胀的结果。

使用C#版OpenCV进行圆心求取的更多相关文章

  1. OpenCV 最小二乘拟合方法求取直线倾角

    工业相机拍摄的图像中,由于摄像质量的限制,图像中的直线经过处理后,会表现出比较严重的锯齿.在这种情况下求取直线的倾角(其实就是直线的斜率),如果是直接选取直线的开始点和结束点来计算,或是用opencv ...

  2. java 求取某一段时间内的每一天、每一月、每一年

    1.求取某一段时间内的每一天 Date date0 = new SimpleDateFormat("yyyy-MM-dd").parse("2014-01-01" ...

  3. php自定义函数求取平方根

    <?phpfunction sqare($a, $left, $right){ $mid = ($left + $right)/2; if($mid * $mid == $a || (abs($ ...

  4. oracle 当前年到指定年的年度范围求取

    如下面公式所示,求取2015到当前年(2018)的年度范围,当前年是由系统获取的,用到了sysdate和函数to_char,to_date. 当然,当前年也可以换成指定年份 SELECT TO_CHA ...

  5. poj 1523Tarjan算法的含义——求取割点可以分出的连通分量的个数

    poj 1523Tarjan算法的含义——求取割点可以分出的连通分量的个数 题目大意:如题目所示 给你一些关系图——连通图,想要问你有没有个节点,损坏后,可以生成几个互相独立的网络(也就是连通分量), ...

  6. python 库 Numpy 中如何求取向量范数 np.linalg.norm(求范数)(向量的第二范数为传统意义上的向量长度),(如何求取向量的单位向量)

    求取向量二范数,并求取单位向量(行向量计算) import numpy as np x=np.array([[0, 3, 4], [2, 6, 4]]) y=np.linalg.norm(x, axi ...

  7. K:求取数组中最大连续子序列和的四个算法

    相关介绍:  求取数组中最大连续子序列和问题,是一个较为"古老"的一个问题.该问题的描述为,给定一个整型数组(当然浮点型也是可以的啦),求取其下标连续的子序列,且其和为该数组的所有 ...

  8. 第3节 mapreduce高级:8、9、自定义分区实现分组求取top1

    自定义GroupingComparator求取topN GroupingComparator是mapreduce当中reduce端的一个功能组件,主要的作用是决定哪些数据作为一组,调用一次reduce ...

  9. 通过spark rdd 求取 特征的稀疏向量

    通过spark rdd 求取  特征的稀疏向量 spark 类标签的稀疏 特征向量 - bonelee - 博客园 http://www.cnblogs.com/bonelee/p/7814081.h ...

随机推荐

  1. .Net开发中的@ 和 using 使用技巧

    一.@符号的妙用 1.可以作为保留关键字的标识符 C#规范当中,不允许使用保留关键字(class.bool等)当作普通的标识符来命名,这时候@符号作用就体现 出来了,可以通过@符号前缀把这些保留关键字 ...

  2. 图解Laravel的生命周期

    先来张图大致理解下laravel的生命周期. 下面对应相应的代码,解释上图. //文件路径:laravel/public/index.php /** * laravel的启动时间 */ define( ...

  3. JS使用replace替换字符串中的某段或某个字符

    函数的介绍参考:http://www.w3school.com.cn/jsref/jsref_replace.asp 下列代码将Hello World!中的World替换为Jim <html&g ...

  4. 第三方登录---微信(使用laravel插件)

    转发: https://www.jianshu.com/p/7be757655814 TP框架: http://www.php.cn/php-weizijiaocheng-363509.html

  5. javascript基础工具清单

  6. 使用JMeter进行API功能测试

    使用JMeter进行API功能测试 Apache JMeter是一种流行的开源软件,用于性能测试. 在本博客中,我们将阐明如何使用JMeter for REST API自动化进行功能测试. 我们使用了 ...

  7. Vue中全局导入和按需导入的区别

    export {router} //按需导出 import {router} from './router' //按需导入路由模块 export default //全局导出store模块 store ...

  8. Unraveling the JPEG file

    (文章还剩实践部分没写,答辩过后补上...) JPEG文件在当下数字化生活中是无处不在的,但是在熟悉的JPEG面纱背后,隐藏着一些算法,它们去除了人类眼中无法察觉到的细节.这产生了最高的视觉质量与最小 ...

  9. CCF201612-1 中间数(二分思想)

    问题链接:CCF201612试题. .对n个数进行排序,找出中间那个数,然后将中间那个数的左右与其相等的数去掉,看左右剩下的数个数是否相等,如果相等则中间那个数就是答案,否在输出-1. 问题描述 问题 ...

  10. HDU6438:Buy and Resell(贪心+数据结构)

    题意 : 给出一些数.你可以从左到右对这些数进行三种操作花费 Ai 买入东西.以 Ai 价格卖出你当前有的东西.或者什么都不做.现在问你可以获取的最大利益是多少 分析:对每一个元素产生的贡献可以先计算 ...