一、腐蚀(Erode)

  取符合模板的点, 用区域最小值代替中心位置值(锚点)

  作用: 平滑对象边缘、弱化对象之间的连接。

opencv 中相关函数:(erode)

 //      C++
/**
shape: 形状
MORPH_RECT 矩形
MORPH_CROSS 交叉形 十字型
MORPH_ELLIPSE 椭圆形
esize : 大小
anchor: 锚点,默认为中心
**/
Mat getStructuringElement(int shape, Size esize, Point anchor = Point(-, -)); /**
src: input Mat
dst: output Mat
element : kernel element
完整参数:https://docs.opencv.org/4.1.0/d4/d86/group__imgproc__filter.html#gaeb1e0c1033e3f6b891a25d0511362aeb
**/
erode(const Mat& src, Mat&dst , const Mat& element) // 基本参数
 # python
# dst = cv.erode( src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] ) import cv2 as cv
import numpy as np im = cv.imread("test.jpg")
gray = cv.cvtColor(im,cv.COLOR_BGR2GRAY)
ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU) # 获取 kerenl element
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
# 腐蚀
dst = cv.erode(binary,kernel)

二、 膨胀(Dilate)

  实现: 使用kernel 划过图像,将区域的最大值赋给锚点位置。

  作用: 致使图像的亮区扩展,能起到平滑边缘的作用。

// C++
/**
src: input Mat
dst: output Mat
kernel : kernel element
完整参数:https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#ga4ff0f3318642c4f469d0e11f242f3b6c
**/
#include<opencv2\imgproc\imgproc.hpp>
void dilate(InputArray src, OutputArray dst , InputArray kernel) // 基本参数

三、边缘检测

边缘检测一般步骤:

  平滑去噪

对比度增强

计算梯度

过滤判断边缘

1、Canny 边缘检测

 // C++
#include<opencv2\imgproc\imgproc.hpp> /**
image : 输入图像
edges : 输出图像
threshold1: 阈值1,高于该值 被认为时边缘
threshold2: 阈值2, 低于该值可认为不是边缘
若在两值之间,该像素仅连接一个高阈值的像素时被保留。
apertureSize : kernel 大小,默认3 sobel kernel ,;取值 1 3 5 7 (奇数,<31)
L2gradient : L2 norm 求梯度 详细参数: https://docs.opencv.org/3.4/dd/d1a/group__imgproc__feature.html#ga04723e007ed888ddf11d9ba04e2232de
**/
void Canny (InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = , bool L2gradient = false )
 import numpy as np
import cv2 as cv # edges = cv.Canny( image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]] ) img = cv2.imread('3.jpg',0)
edges = cv2.Canny(img,100,200)

2、 sobel

sobel kernel:

X 方向3X3:                                                                                                       Y方向3x3:

                                             

X 方向5x5:

在opencv sobel 函数中当ksize =-1 时:kernel 为:SCHARR

opencv 中函数:
 // C++
#include <opencv2/imgproc.hpp> /** https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#gacea54f142e81b6758cb6f375ce782c8d
src: 输入图像
dst: 输出图像
ddepth: output image depth
src.depth() = CV_8U --------------- ddepth =-1/CV_16S/CV_32F/CV_64F
src.depth() = CV_16U/CV_16S ----- ddepth =-1/CV_32F/CV_64F
src.depth() = CV_64F --------------- ddepth = -1/CV_64F
dx / dy : 差分阶数 0 or 1
ksize: 取奇数 -1 : SCHARR (3x3) 1: 1x3 or 3x1
**/
void cv::Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy,int ksize=, double scale=, double delta=, int borderType = BORDER_DEFAULT )
 import cv2 as cv
import numpy as np # dst = cv.Sobel( src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]] ) img = cv.imread('flower.jpg',0)
#默认ksize=3
sobelx = cv.Sobel(img,cv2.CV_64F,1,0,ksize=3)

四、二值图像的轮廓分析

opencv  中可以使用 findContours()工具,分析二值图像的拓扑结构

void findContours//提取轮廓,用于提取图像的轮廓
(
    InputOutputArray image,//输入图像,必须是8位单通道图像,并且应该转化成二值的
    OutputArrayOfArrays contours,//检测到的轮廓,每个轮廓被表示成一个point向量
    OutputArray hierarchy,//可选的输出向量,包含轮廓的拓扑信息。其中元素的个数和检测到的轮廓的数量相等
    int mode,     //说明需要的轮廓类型和希望的返回值方式
    int method,//轮廓近似方法
    Point offset = Point()
)

参数说明:

hierarchy:  每一个轮廓,都包含4个整型数据,分别表示:后一个轮廓的序号前一个轮廓的序号子轮廓的序号父轮廓的序号

mode: 轮廓检索模式

  method :

      1)、CV_CHAIN_APPROX_NONE  边界上所有连续点

2)、CV_CHAIN_APPROX_SIMPLE   拐点

      3)and 4) 、 CV_CHAIN_APPROX_TC89_L1  、  CV_CHAIN_APPROX_TC89_KCOS  使用teh-Chinl chain 近似法

# python
import cv2 as cv
import numpy as np # contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]] ) img = cv.imread('12.jpeg')
gray = cv.cvtColor ( img , cv2.COLOR_BGR2GRAY )
ret , binary = cv.threshold ( gray , 220 , 255 , cv2.THRESH_BINARY ) # 检测轮廓
contours , hierarchy = cv.findContours ( binary , cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE ) # 画出轮廓
cv.drawContours(img,contours,-1,(0,0,255),3) '''
void cv::drawContours ( InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
#image:输入输出图像,Mat类型即可
#contours:使用findContours检测到的轮廓数据,每个轮廓以点向量的形式存储,point类型的vector
#contourIdx:绘制轮廓的只是变量,如果为负值则绘制所有输入轮廓
#color:轮廓颜色
#thickness:绘制轮廓所用线条粗细度,如果值为负值,则在轮廓内部绘制
#lineTpye:线条类型,有默认值LINE_8
'''

五、 凸包 和 多边形拟合

凸包:

opencv 中使用 convexHull() 函数来查找对象的凸包。

void cv::convexHull (   InputArray  points,
                        OutputArray     hull,
                        bool    clockwise = false,
                        bool    returnPoints = true
)

参数: points: input 2D point set, stored in std::vector or Mat.

hull : 输出参数,用于输出函数调用后找到的凸包

clockwise : 操作方向,true顺时针,fasle逆时针

详细参考: https://docs.opencv.org/master/d3/dc0/group__imgproc__shape.html#ga014b28e56cb8854c0de4a211cb2be656

多边形拟合:

opencv 中使用 approxPolyDP() 函数对图像的轮廓点进行多边形拟合。

void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)

参数:

    curve : Input vector of a 2D point stored in std::vector or Mat

approxCurve : 表示输出的多边形点集

    epsilon:    精度,两个轮廓点之间的最大距离数

closed:  表示输出的多边形是否封闭

#include<opencv2\opencv.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream> using namespace std;
using namespace cv; int main()
{
// 三通道二值图像
Mat img = imread("E:\\pcblabels\\labels2019-11-01-094405.jpg");
cout << "read image end..." << endl; // 膨胀
Mat kernel = getStructuringElement(MORPH_RECT, Size(6, 6));
Mat dilateImg;
dilate(img, dilateImg, kernel);
cout << "dilate end....." << endl; // 腐蚀
Mat erodeImg;
erode(dilateImg, erodeImg, kernel);
cout << "erode end....." << endl; // canny
Mat cannyImg;
Canny(dilateImg, cannyImg, 5, 2, 5); // ksize: 奇数
cout << "Canny end....." << endl; // find contours
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
// 只检测最外层轮廓,并且保存轮廓上所有点
findContours(cannyImg, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point());
drawContours(contours, hierarchy, img.size()); // 找一个点数最多的轮廓
int index = 0;
for (int i = 0; i< contours.size(); i++)
{
if (contours[i].size() > contours[index].size())
{
index = i;
}
}
cout << "findContours end....." << endl; //凸包
Mat hullImg = img.clone();
vector<Point> hull;
convexHull(Mat(contours[index]), hull, true);
drawContours(hullImg, vector<vector<Point>>{hull}, 0, Scalar(0,0,255), 1, 8, vector<Vec4i>(), 0, Point());
cout << "draw hull end....." << endl; // 多边形拟合
Mat approxImg = img.clone();
Mat approxImgRes = Mat::zeros(img.size(), CV_8UC1);
vector<Point> approxPloy;
approxPolyDP(contours[index], approxPloy, 1, true);
drawContours(approxImg, contours, index, Scalar(255, 0, 0), 1, 8, hierarchy);
drawContours(approxImgRes, vector<vector<Point>>{approxPloy}, 0, Scalar(255), 2, 8, vector<Vec4i>(), 0, Point());
cout << "draw approxPolyDP end....." << endl; return 0;
}

  

   

  

opencv---(腐蚀、膨胀、边缘检测、轮廓检索、凸包、多边形拟合)的更多相关文章

  1. OpenCV 腐蚀膨胀操作

    利用腐蚀膨胀操作实现对椭圆周围线条的消除,椭圆的大小不变 代码如下: #include "cv.h" #include "highgui.h" int main ...

  2. OpenCV探索之路(十一):轮廓查找和多边形包围轮廓

    Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...

  3. OpenCV计算机视觉学习(8)——图像轮廓处理(轮廓绘制,轮廓检索,轮廓填充,轮廓近似)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...

  4. opencv中的图像形态学——腐蚀膨胀

    腐蚀膨胀是图像形态学比较常见的处理,腐蚀一般可以用来消除噪点,分割出独立的图像元素等. 一般腐蚀操作对二值图进行处理,腐蚀操作如下图,中心位置的像素点是否与周围领域的像素点颜色一样(即是否是白色点,即 ...

  5. Opencv笔记(十八)——轮廓的更多函数及其层次结构

    凸缺陷 前面我们已经学习了轮廓的凸包,对象上的任何凹陷都被成为凸缺陷.OpenCV 中有一个函数 cv.convexityDefect() 可以帮助我们找到凸缺陷.函数调用如下: hull = cv2 ...

  6. OpenCV入门之寻找图像的凸包(convex hull)

    介绍   凸包(Convex Hull)是一个计算几何(图形学)中的概念,它的严格的数学定义为:在一个向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包.   在图像处理过程中,我们 ...

  7. OpenCV函数:提取轮廓相关函数使用方法

    opencv中提供findContours()函数来寻找图像中物体的轮廓,并结合drawContours()函数将找到的轮廓绘制出.首先看一下findContours(),opencv中提供了两种定义 ...

  8. opencv使用convexityDefects计算轮廓凸缺陷

    引自:http://www.xuebuyuan.com/1684976.html http://blog.csdn.net/lichengyu/article/details/38392473 htt ...

  9. 基于FPGA的腐蚀膨胀算法实现

    本篇文章我要写的是基于的腐蚀膨胀算法实现,腐蚀膨胀是形态学图像处理的基础,,腐蚀在二值图像的基础上做"收缩"或"细化"操作,膨胀在二值图像的基础上做" ...

随机推荐

  1. JAVA可视化闹钟源码

    概述 一些同学的Java课设有这样一个问题,比较感兴趣就做了一下 功能介绍: 1.可增加闹钟 2.可删除闹钟 3.时间到了响铃 4.关闭闹钟不会丢失闹钟(因为闹钟存储在txt文件中,不会因程序关闭就终 ...

  2. linux-linux mysql5.7主从搭建

    原理: 1:master,建立二进制日志 , 每产生语句或者磁盘变换,写进日志: 2:slave,建立relaylog日志(中继日志),分析master的binlog. 3:master,建立授权账号 ...

  3. django甜甜的弹窗

    GitHub中甜甜的弹窗地址: https://github.com/lipis/bootstrap-sweetalert 直接简单粗暴选择右下角的download,下载到本地一份文件 小猿取经中的相 ...

  4. Django基础day01

    后端(******) 软件开发结构c/s http协议的由来 sql语句的由来 统一接口统一规范 HTTP协议 1.四大特性 1.基于TCP/IP作用于应用层之上的协议 2.基于请求响应 3.无状态 ...

  5. re常用模块

    re模块:从字符串里面找到特定的字符串 re的基本语法(匹配规则) import re s = '王大炮打炮被大炮打死了 王大炮打炮被大炮打死了' ^:开头 print(re.findall('^王大 ...

  6. MVC模式与Servlet执行流程

    ##Servlet生命周期 五个部分,从加载到卸载,如同人类的出生到死亡 加载:Servlet容器自动处理 初始化:init方法 该方法会在Servlet被加载并实例化后执行 服务:service抽象 ...

  7. [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期

    生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...

  8. Litho在美团动态化方案MTFlexbox中的实践

    1. MTFlexbox MTFlexbox是美团内部应用的非常成熟的一种跨平台动态化解决方案,它遵循了CSS3中提出的Flexbox规范来抹平多平台的差异.MTFlexbox适用于重展示.轻交互的业 ...

  9. Git很麻烦?只要掌握这几个命令,轻松将代码提交远程仓库

    在上一章节,跟大家介绍了拉取代码的操作,简单暴力.这一章节要介绍的是如何将现有的项目,直接提交到仓库. 现在,如果大家有一个项目要提交到GitHub仓库,安装上一张的方法,需要先在GitHub上建一个 ...

  10. ORACLE数据库中执行计划出现INTERNAL_FUNCTION一定是隐式转换吗?

    ORACLE数据库中,我们会使用一些SQL语句找出存在隐式转换的问题SQL,其中网上流传的一个SQL语句如下,查询V$SQL_PLAN的字段FILTER_PREDICATES中是否存在INTERNAL ...