面试官一定会问的几题视觉过关挑战赛 - 附源码

Posted cv君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试官一定会问的几题视觉过关挑战赛 - 附源码相关的知识,希望对你有一定的参考价值。

导读

嗨喽大家好,我是cv君,本专栏长期连载更新,速度收藏,下次就看不到了。
首先,本系列专栏适用于:
1:小白,小白需要大量努力,方向和cv君亲自整理的资料很关键,cv君有手把手实战文近百篇,点击此处查看:原创实战项目级专栏还有精选精品视觉项目,还有机器学习原理与项目
再加上本面经专栏 cv君文章,只需订阅一个专栏,百篇文章都能看哦~(订阅后联系cv君)
(即将更新100期),卷个算法岗,不上岸,来找我手把手教学,和cv君接触,你会发现,有问必答,而且还有近万的cv君朋友,在多个交流群中,欢迎订阅后进群~
2:求职者:马上要去找工作的朋友们,加油,我第一次面大厂,试试水,结果完全没准备,他问我的算法问题,我语无伦次,支支吾吾,完全被吊打,后来,我重振旗鼓,成功拿下大厂算法Offer,这段时间,我静下心来出这份面经专栏,预期更100期,能把面试官说的服帖。求职者,最需要的是项目和面经,个人感悟,所以如果你看我的面经文,会有较大帮助,cv君也不吹了哈哈哈。
3:工程师,cv君是一名擅长应用的工程师,对算法优化,模型部署有着一定研究,交流群也很多朋友做应用,本专栏还是很多数据和应用教学的,欢迎订阅后联系cv君进群交流应用哦!

图像滤波

图像滤波:在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制。

平滑:也称模糊, 是一项简单且使用频率很高的图像处理方法。平滑的一种作用就是用来减弱噪声。

1.列出常见的线性滤波器

低通滤波器 允许低频通过

高通滤波器 允许高频通过

带通滤波器 允许一定范围的频率通过

带阻滤波器 允许一定范围的频率通过并阻止其他的频率通过

全通滤波器 允许所有频率通过,只改变相位

陷波滤波器 阻止一个狭窄频率范围通过

2.线性滤波与非线性滤波

线性滤波:方框滤波 均值滤波 高斯滤波 非线性滤波:中值滤波 双边滤波

方框滤波(boxblur函数):每一个输出像素的是内核邻域像素值的平均值得到

均值滤波(Blur函数):均值滤波实际上就是用均值代替原图像中的各个像素值。

把每个像素都用周围的8个像素来做均值操作

原理:在图像上,对待处理的像素给定一个模板,该模板包括了其周围的邻近像素。将模板中的全体像素的均值来替代原来的像素值的方法。

方法:对待处理的当前像素,选择一个模板,该模板为其近邻的若干像素组成,

用模板中像素的均值来代替原像素值的方法。

优点:把每个像素都用周围的 8 个像素做均值操作,平滑图像速度快、算法简单。

缺点:1、在降低噪声的同时,使图像产生模糊,特别是边缘和细节处,而且模糊尺寸越大,图像模糊程度越大。2、对椒盐噪声的平滑处理效果不理想。(无法去掉噪声)

不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变模糊,不能很好去除噪声点。

高斯滤波(Gauss filter)

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。

高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值用。

高斯平滑滤波器对于抑制服从正态分布的噪声非常有效。

中值滤波(Median filter)

中值滤波是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像边缘细节。

双边滤波

双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。

用在对边缘信息重要,需要保留的图像去噪。缺点是由于双边滤波保证了边缘信息,所以其保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净地滤去,只能对于低频信息进行较好地滤波。

维纳滤波

维纳滤波是一种自适应最小均方差滤波器。维纳滤波的方法是一种统计方法,它用的最优准则是基于图像和噪声各自相关的相关矩阵,它能根据图像的局部方差调整滤波器的输出,局部方差越大,滤波器的平滑作用就越强。

椒盐噪声用什么滤波? 中值滤波

均值滤波,高斯滤波,中值滤波,双边滤波 代码实操

import numpy as np
import cv2
import matplotlib.pyplot as plt
########     四个不同的滤波器    #########
img = cv2.imread('cat.jpg')

# 均值滤波
img_mean = cv2.blur(img, (5,5))

# 高斯滤波
img_Guassian = cv2.GaussianBlur(img,(5,5),0)

# 中值滤波
img_median = cv2.medianBlur(img, 5)

# 双边滤波
img_bilater = cv2.bilateralFilter(img,9,75,75)

# 展示不同的图片
titles = ['srcImg','mean', 'Gaussian', 'median', 'bilateral']
imgs = [img, img_mean, img_Guassian, img_median, img_bilater]

for i in range(5):
    plt.subplot(2,3,i+1)#注意,这和matlab中类似,没有0,数组下标从1开始
    plt.imshow(imgs[i])
    plt.title(titles[i])
plt.show()

边缘检测

边缘检测的目的就是找到图像中亮度变化剧烈的像素点构成的集合,表现出来往往是轮廓。如果图像中边缘能够精确的测量和定位,那么,就意味着实际的物体能够被定位和测量,包括物体的面积、物体的直径、物体的形状等就能被测量。

边缘检测算子有哪些:

一阶:Roberts Cross算子, Prewitt算子, Sobel算子, Canny算子,罗盘算子

二阶:Laplacian算子,Marr-Hildreth,在梯度方向的二阶导数过零点。

1.介绍canny边缘检测

Canny边缘检测是一种非常流行的边缘检测算法,是John Canny在1986年提出的。它是一个多阶段的算法,即由多个步骤构成。

1.图像降噪2.计算图像梯度3.非极大值抑制4.阈值筛选

首先,图像降噪。我们知道梯度算子可以用于增强图像,本质上是通过增强边缘轮廓来实现的,也就是说是可以检测到边缘的。但是,它们受噪声的影响都很大。那么,我们第一步就是想到要先去除噪声,因为噪声就是灰度变化很大的地方,所以容易被识别为伪边缘。

第二步,计算图像梯度,得到可能边缘。我们在前面的关于《图像梯度》文章中有所介绍,计算图像梯度能够得到图像的边缘,因为梯度是灰度变化明显的地方,而边缘也是灰度变化明显的地方。当然这一步只能得到可能的边缘。因为灰度变化的地方可能是边缘,也可能不是边缘。这一步就有了所有可能是边缘的集合。

第三步,非极大值抑制。通常灰度变化的地方都比较集中,将局部范围内的梯度方向上,灰度变化最大的保留下来,其它的不保留,这样可以剔除掉一大部分的点。将有多个像素宽的边缘变成一个单像素宽的边缘。即“胖边缘”变成“瘦边缘”。

第四步,双阈值筛选。通过非极大值抑制后,仍然有很多的可能边缘点,进一步的设置一个双阈值,即低阈值(low),高阈值(high)。灰度变化大于high的,设置为强边缘像素,低于low的,剔除。在low和high之间的设置为弱边缘。进一步判断,如果其领域内有强边缘像素,保留,如果没有,剔除。

这样做的目的是只保留强边缘轮廓的话,有些边缘可能不闭合,需要从满足low和high之间的点进行补充,使得边缘尽可能的闭合。

canny算子是怎么做的?简述Canny算子的计算步骤

①将彩色图像转化为灰度图;②使用高斯滤波器平滑图像;③计算图像梯度的幅值和方向;④对梯度幅值进行非极大值抑制;⑤使用双阈值进行边缘的检测和连接;Canny算子使用滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值)。如果某一像素位置的幅值超过 高 阈值, 该像素被保留为边缘像素。如果某一像素位置的幅值小于 低 阈值, 该像素被排除。如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于 高 阈值的像素时被保留。

代码实操

import cv2
import PIL


img = cv2.imread('lena.jpg')
gray = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
gray = cv2.resize(gray, (400, 430))
img = cv2.resize(img, (400, 430))
sober_horizontal = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=1)
sober_vertical = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)
laplacian = cv2.Laplacian(img, cv2.CV_64F)
canny = cv2.Canny(img, 50, 240)
img_GanssianBlur = cv2.GaussianBlur(img, (3, 3), 0)
cv2.imshow('original', img)
cv2.imshow('Gray', gray)
cv2.imshow('sobel horizontal', sober_horizontal)
cv2.imshow('sobel vertical', sober_vertical)
cv2.imshow('Laplacation', laplacian)
cv2.imshow('Canny',canny)
cv2.imshow('GaussianBlur', img_GanssianBlur)
cv2.waitKey()


用法很简单,调包调参嘛,以灰度形式读图,介绍一下灰度转换原理:
RGB是三通道彩色图,在矩阵(图像)中的顺序是B,G,R;GRAY是单通道灰度图
COLOR_BGR2GRAY的原理:

GRAY = B * 0.114 + G * 0.587 + R * 0.299

利用CV_RGB2GRAY将原图src转换为灰度图rgb2gray,转换公式Gray = 0.1140R + 0.5870G + 0.2989*B,与CV_BGR2GRAY相比,转换的系数一致,不同的是系数后紧跟的通道的顺序变化了,由BGB变为RGB。

利用CV_GRAY2BGR将bgr2grayImg转换为gray2bgrImg,转换公式B = G = R = Gray

又或者 利用CV_GRAY2RGB将rgb2grayImg转换为gray2rgbImg,转换公式R = G = B = Gray

第三、第四张是sobel算子的横向检测器和纵向检测器(垂直),这个比灰度图就是真的属于调包了:
sobel算子技术,使用的是卷积运算。可以利用sobel算子作用于图像梯度上

sobel算子主要用作边缘检测上,在技术上,他是一个离散型差分算子,用来运算图像高亮度函数的灰度的近似值,在图像中任意一点使用此算子,都会产生对应的灰度矢量或者法向量。

我上面图中没有转化成灰度图后使用sobel算子,现在演示一下灰度图下的sobel算子以及不同Ksize参数下的图案:

Sobel算子下的图像卷积过程:(正常的卷积过程就不赘述了,建议百度百科,看不懂可以私聊我讨论一下)

2.简述一下sobel算子

Sobel算子是一个主要用作边缘检测的离散微分算子(discrete differentiation operator)。它Sobel算子结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。

当内核大小为 3 时, 我们的Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值而已)。为解决这一问题,OpenCV提供了Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确。

3.简述传统算法中边缘检测的一般步骤

①滤波:滤波去除噪声;②增强:增强边缘的特征;③将边缘通过某种方式提取出来,完成边缘检测。

4.如何求边缘,45°边缘

Sobel算子实现水平边缘检测、垂直边缘检测;45度、135度角边缘检测。

5. SIFT

尺度不变特征变换(Scale-invariant feature transform, SIFT)是计算机视觉中一种检测、描述和匹配图像局部特征点的方法,通过在不同的尺度空间中检测极值点或特征点(Conrner Point, Interest Point),提取出其位置、尺度和旋转不变量,并生成特征描述子,最后用于图像的特征点匹配。

SIFT特征是如何保持旋转不变性的?

sift特征通过将坐标轴旋转至关键点的主方向来保持旋转不变性,关键点的主方向是通过统计关键点局部邻域内像素梯度的方向分布直方图的最大值得到的

SIFT特征匹配

对两幅图像中检测到的特征点,可采用特征向量的欧式距离作为特征点相似性的度量,取图像1中某个关键点,并在图像2中找到与其距离最近的两个关键点,若最近距离与次近距离的比值小于某个阈值,则认为距离最近的这一对关键点为匹配点。降低比例阈值,SIFT匹配点数量会减少,但相对而言会更加稳定。阈值ratio的取值范围一般为0.4~0.6。

SIFT特征的特点

SIFT是一种检测、描述、匹配图像局部特征点的算法,通过在尺度空间中检测极值点,提取位置、尺度、旋转不变量,并抽象成特征向量加以描述,最后用于图像特征点的匹配。SIFT特征对灰度、对比度变换、旋转、尺度缩放等保持不变性,对视角变化、仿射变化、噪声也具有一定的鲁棒性。但其实时性不高对边缘光滑的目标无法准确提取特征点

6.SURF特征匹配

加速鲁棒特征(Speed Up Robust Feature, SURF)和SIFT特征类似,同样是一个用于检测、描述、匹配图像局部特征点的特征描述子。SIFT是被广泛应用的特征点提取算法,但其实时性较差,如果不借助于硬件的加速和专用图形处理器(GPUs)的配合,很难达到实时的要求。对于一些实时应用场景,如基于特征点匹配的实时目标跟踪系统,每秒要处理数十帧的图像,需要在毫秒级完成特征点的搜索定位、特征向量的生成、特征向量的匹配以及目标锁定等工作,SIFT特征很难满足这种需求。SURF借鉴了SIFT中近似简化(DoG近似替代LoG)的思想,将Hessian矩阵的高斯二阶微分模板进行了简化,借助于积分图,使得模板对图像的滤波只需要进行几次简单的加减法运算,并且这种运算与滤波模板的尺寸无关。SURF相当于SIFT的加速改进版本,在特征点检测取得相似性能的条件下,提高了运算速度。整体来说,SUFR比SIFT在运算速度上要快数倍,综合性能更优。

7.LBP特征

局部二值模式(Local Binary Patter, LBP)是一种用来描述图像局部纹理特征的算子,LBP特征具有灰度不变性和旋转不变性等显著优点,它将图像中的各个像素与其邻域像素值进行比较,将结果保存为二进制数,并将得到的二进制比特串作为中心像素的编码值,也就是LBP特征值。LBP提供了一种衡量像素间邻域关系的特征模式,因此可以有效地提取图像的局部特征,而且由于其计算简单,可用于基于纹理分类的实时应用场景,例如目标检测、人脸识别等。

8.图像特征提取之HOG特征

方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。它通过计算和统计图像局部区域的梯度方向直方图来构成特征。Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。

9.简要阐述一下SIFT和SURF算法的异同点

①尺度空间:SIFT使用DoG金字塔与图像进行卷积操作,而且对图像有做降采样处理;SURF是用近似DoH金字塔(即不同尺度的box filters)与图像做卷积,借助积分图,实际操作只涉及到数次简单的加减运算,而且不改变图像大小。

②特征点检测:SIFT是先进行非极大值抑制,去除对比度低的点,再通过Hessian矩阵剔除边缘点。而SURF是计算Hessian矩阵的行列式值(DoH),再进行非极大值抑制。

③特征点主方向:SIFT在方形邻域窗口内统计梯度方向直方图,并对梯度幅值加权,取最大峰对应的方向;SURF是在圆形区域内,计算各个扇形范围内x、y方向的Haar小波响应值,确定响应累加和值最大的扇形方向。

④特征描述子:SIFT将关键点附近的邻域划分为4×4的区域,统计每个子区域的梯度方向直方图,连接成一个4×4×8=128维的特征向量;SURF将20s×20s的邻域划分为4×4个子块,计算每个子块的Haar小波响应,并统计4个特征量,得到4×4×4=64维的特征向量。

总体来说,SURF和SIFT算法在特征点的检测取得了相似的性能,SURF借助积分图,将模板卷积操作近似转换为加减运算,在计算速度方面要优于SIFT特征。

10.比较一下SIFT,HOG和LBP这三个特征提取算法

代码实操 SIFT

input_file = 'box.png'
img = cv2.imread(input_file)
cv2.imshow('Input image', img)

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gray = np.float32(img_gray)

img_harris = cv2.(img_gray, 7, 5, 0.04)
cv2.imshow('Harris Cornersess', img_harris)

img_harris = cv2.dilate(img_harris, None)
img[img_harris > 0.01 * img_harris.max()] = [0, 0, 0]
cv2.imshow('Harris Corners', img)
cv2.imshow('Harris Cornerses', img_harris)

cv2.waitKey()

上图实现的是使用SIFT提取图像突出的关键点,思想策略比较简单,无非是跟前面的棱角检测一样的思想,不过SIFT不仅仅是做关键点的检测的,他用的更深的是特征的提取器!

SIFT在1999年提出,在2004年加以完善 。SIFT在数字图像的特征描述方面当之无愧可称之为最红最火的一种,许多人对SIFT进行了改进,诞生了SIFT的一系列变种。SIFT已经申请了专利。

SIFT特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、微视角改变的容忍度也相当高。基于这些特性,它们是高度显著而且相对容易撷取,在母数庞大的特征数据库中,很容易辨识物体而且鲜有误认。使用SIFT特征描述对于部分物体遮蔽的侦测率也相当高,甚至只需要3个以上的SIFT物体特征就足以计算出位置与方位。在现今的电脑硬件速度下和小型的特征数据库条件下,辨识速度可接近即时运算。SIFT特征的信息量大,适合在海量数据库中快速准确匹配。

SIFT算法具有如下一些特点:

1.SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;

区分性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;

多量性,即使少数的几个物体也可以产生大量的SIFT特征向量;

高速性,经优化的SIFT匹配算法甚至可以达到实时的要求;

可扩展性,可以很方便的与其他形式的特征向量进行联合。

SIFT特征检测主要包括以下4个基本步骤:

尺度空间极值检测:

搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。

关键点定位

在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。

方向确定
基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。

关键点描述
在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。

SIFT特征匹配主要包括2个阶段:

第一阶段:SIFT特征的生成,即从多幅图像中提取对尺度缩放、旋转、亮度变化无关的特征向量。

第二阶段:SIFT特征向量的匹配。

SIFT特征的生成一般包括以下几个步骤:

  1. 构建尺度空间,检测极值点,获得尺度不变性。

特征点过滤并进行精确定位。

为特征点分配方向值。

生成特征描述子。

以特征点为中心取16×16的邻域作为采样窗口,将采样点与特征点的相对方向通过高斯加权后归入包含8个bin的方向直方图,最后获得4×4×8的128维特征描述子。示意图如下:

当两幅图像的SIFT特征向量生成以后,下一步就可以采用关键点特征向量的欧式距离来作为两幅图像中关键点的相似性判定度量。取图1的某个关键点,通过遍历找到图像2中的距离最近的两个关键点。在这两个关键点中,如果最近距离除以次近距离小于某个阈值,则判定为一对匹配点。

SIFT特征匹配的例子:

下节带来这份:SIFT合理拼接图片的源码~

下节继续带来视觉的题目,还差许多才能修成仙。
作者cv君,欢迎大家进算法交流群交流,二维码时间有限~ 也可以点击左侧公众号进入。

以上是关于面试官一定会问的几题视觉过关挑战赛 - 附源码的主要内容,如果未能解决你的问题,请参考以下文章

Vue3考点,99%面试官都会问的内容

面试官95%会问的接口测试知识

面试官95%会问的接口测试知识

面试官95%会问的接口测试知识

如果你是一个 Java 面试官,你会问哪些问题?

我明知道面试官会问TCP协议问题,但就是答不上来!