资讯详情

OpenCV中的图像基本操作--B站视频教程笔记(六)

学习B站教学视频时记录的笔记

OpenCV TensorFlow】迪哥带你去做项目!深度学习! 计算机视觉实战 纯实战教学 技能点加满


6.1 Canny边缘检测

  • 1)使用高斯滤波器平滑图像,过滤噪音。

  • 2)计算图像中每个像素点的梯度强度和方向。

  • 3)应用非极大值(Non-Maximum Suppression)抑制边缘检测引起的杂散响应。

  • 4)应用双阈值(Double-Threshold)检测来确定真是的和潜在的边缘。

  • 5)边缘检测最终通过抑制鼓励的弱边缘完成。

过程参考以前的滤波计算过程。

使用的算子是Sobel算子

假设人脸识别时出现了假设ABC 三个结果三个结果而异。然后保留最大的确定性A,放弃相对较小的BC是非极大值抑制。如图所示:

  • A点的梯度值大于A点maxValA是边界。

  • 对于D小于minVal然后放弃D点。(图中没有画出来,可以想象D位于minVal红线以下)

  • 对于BC当点小于maxVal且大于minVal比如C点。然后分析具体情况。如果C点可以连接到A点,则保留。如果是B,不能连接A,就放弃。

minVal设置越小,条件越低,通过筛选的点越多。

maxVal设置越大,条件越低,通过筛选的点越多。

#Canny img = cv2.imread('H:\Peronal\lena.jpg',cv2.IMREAD_GRAYSCALE) v1 = cv2.Canny(img,80,150) v2 = cv2.Canny(img,50,100)  res = np.hstack((v1,v2)) cv2.imshow('res',res) cv2.waitKey(0) cv2.destroyAllWindows()
 

左侧是80-150 右侧是50-100

以car.jpg例如,代码如下:

#Canny img = cv2.imread('H:\Peronal\car.png',cv2.IMREAD_GRAYSCALE) v1 = cv2.Canny(img,130,250) v2 = cv2.Canny(img,50,100)  res = np.hstack((v1,v2)) cv2.imshow('res',res) cv2.waitKey(0) cv2.destroyAllWindows()

区别还是很明显的,左边130-250,右边50-100,右边边界明显更大。

6.2 图像金字塔

  • 高斯金字塔

  • 拉普拉斯金字塔

图像可以处理成不同尺寸的图像。

layer0 : 800x800

layer1 : 400x400

layer2 : 200x200

layer3: 100x100

layer4 : 50x50

在后续处理过程中,每层都可以提取特征,每层的特征提取结果很可能不同。

6.2.1 高斯金字塔

制作金字塔的方法:

在示意图上理解向下采样是向上的过程。

首先创建卷积核,然后过滤图像,最后去除所有偶数线和列。

在示意图上理解向上采样是向下的过程。

向上采样过程:

1将图像在每个方向扩展到原来的两倍,新行列以0填充。

2 使用相同的内核(乘以4)和放大的图像卷积获得近似值。

代码如下:

# 高斯金字塔 img = cv2.imread('H:\Peronal\AM.png') cv2.imshow('img',img) img.shape up = cv2.pyrUp(img) cv2.imshow('up',up) up.shape down = cv2.pyrDown(img) cv2.imshow('down',down) cv2.waitKey(0) cv2.destroyAllWindows() down.shape

左边是原始图像,中间是上采样,右边是下采样。尺寸的变化很明显。

注:上采样,下采样可连续执行多次。

img = cv2.imread('H:\Peronal\AM.png') up = cv2.pyrUp(img) down = cv2.pyrDown(up)  res = np.hstack((img,down)) cv2.imshow('res',res) cv2.waitKey(0) cv2.destroyAllWindows()

连续采样后,虽然尺寸相同,但清晰度大大降低。

6.2.拉普拉斯金字塔

与高斯金字塔类似,拉普拉斯金字塔也是多层的,每层都是通过相同的公式计算出来的。公式如下:

Gi 为输入图像(img)

代码如下:

down = cv2.pyrDown(img) down_up = cv2.pyrUp(down) l_1 = img-down_up cv2.imshow('l_1',l_1) cv2.waitKey(0) cv2.destroyAllWindows()

6.3图像轮廓

img : 待测试图像

mode : 轮廓检索模式

  • RETR_EXTERNAL:只检索外轮廓;

  • RETR_LIST:检索所有轮廓,并将其保存在链表中;

  • RETR_CCOMP : 对所有轮廓进行检索,并将其组织成两层:顶层分的外界,第二层是空界;

  • RETR_TREE: 检索所有轮廓,重构嵌套轮廓的整个层次;(最常用)

method:轮廓接近法

  • CHAIN_APPROX_NONE:以Freeman链码输出轮廓,所有其他方法输出多边形(顶点序列)

  • CHAIN_APPROX_SIMPLE:垂直和倾斜的压缩部分,即函数只保留其终点部分。

左侧图像为CHAIN_APPROX_NONE,为了进一步减少描述信息的内容,描述会有四个边界。

右侧图像CHAIN_APPROX_SIMPLE只保留了4个角点。

轮廓检测步骤:

1)使用二值图像以提高准确性。

img= cv2.imread('H:\Peronal\contours.png') gray  = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) cv_show(thresh,'thresh')

注意:cv2.threshold 高级版本返回2个值(4.5.5返回2),低级版返回3个值。

图像、轮廓、轮廓索引、颜色模式、线条厚度

#注意需要copy,否则原图会变 draw_img = img.copy() res = cv2.rawContours(draw_img,contours,-1,(0,0,255),2)
cv_show(res,'res')

cv2.drawContours(img,contours,index,color,thinkness)

  • img:参数是指明在哪幅图像上绘制轮廓;image为三通道才能显示轮廓

  • contours:参数是轮廓本身,在Python中是一个list;

  • index:参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。

  • color:绘制轮廓的笔刷颜色

  • thinkness:表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。

    当index=0时,为左下方三角形的内圈。如图:

     index=1时,为左下方三角形的外圈。如图:

cv2.contourArea(contour)

首先选定要计算的边界,然后获取面积数值,代码如图:

cnt = contours[0]
cv2.contourArea(cnt)

cv2.arcLength(cnt,bool)

  • cnt 边界

  • bool: 是否为闭合边界,True为闭合

首先选定要计算的边界,然后获取面积数值,代码如图:

cnt = contours[0]
cv2.arcLength(cnt,True)

 假设求弧线AB的近似,首先取弧线AB上一点C使得C到直线AB距离最大,距离值为d。当d<阈值T的时候直线AB就是弧线AB的近似。 

如果d>T,则画辅助线连接AC在弧线AC上找D使得D到直线AC的距离最大,距离为e。如果e<T完成弧线AC的近似求解。重复上述步骤,直至全部弧线近似求解全部完成。

 代码如下:

img= cv2.imread('H:\Peronal\contours2.png')
gray  = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
#新版本返回2个值
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
draw_img = img.copy()
res = cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
cv_show(res,'res')

 近似函数cv2.approxPolyDP(cnt,epsilon,bool)

  • cnt 轮廓

  • epsilon 距离阈值(通常是周长的百分比)

  • bool 是否是封闭轮廓

epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
draw_img = img.copy()
res = cv2.drawContours(draw_img,[approx],-1,(0,0,255),2)
cv_show(res,'res')

 注意:

阈值设置的越小,轮廓越接近轮廓实际形状。

阈值设置的越大,减少计算量,满足确定轮廓大致行形状即可。

进一步,可以用这种方式做轮廓的外接形状,如:外接矩形,外接圆,外接椭圆等等。

cv2.boundingRect(cnt)

  • cnt 轮廓

img= cv2.imread('H:\Peronal\contours.png')
gray  = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv_show(img,'img')

 计算轮廓与外接矩形面壁比

area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area
print('轮廓面积与外接矩形面积比',extent)

轮廓面积与外接矩形面积比 0.5154317244724715

标签: 3x400高压电缆电容值

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司