文章目录
- OpenCV面试问题
- 传统图像算法面试问题
-
- 1、什么是边缘检测,如何实现?
- 2、什么是二值化,如何实现?
- 3、什么是直方图均衡化,如何实现?
- 4、什么是形态学操作,有哪些常见的形态学操作?
- 5、什么是轮廓提取,如何实现?
- 6、什么是区域生长算法,如何实现?
- 7、什么是插值算法?有哪些常见的插值算法?
- 8、什么是基于模板匹配的目标识别算法,如何实现?
- 9、什么是霍夫变换,有哪些常见的霍夫变换?
- 10、什么是图形匹配,有哪些常见的图形匹配算法?
- 11、什么是图像滤波?有哪些常见的图形滤波算法?
- 12、什么是图像分割?有哪些常见的图像分割算法?
- 13、什么是图像补全?有哪些常见的图像补全算法?
- 14、什么是边缘修复?有哪些常见的边缘修复算法?
- 15、什么是颜色回复,有哪些常见的颜色恢复算法?
- 16、降噪算法
- 17、什么是凸包?如何实现凸包的计算?
- 18、关键点提取算法
- 19、什么是SIFT算法,如何实现?
- 20、什么是SURF算法?
- 21、ORB算法是什么,怎么实现?
- 22、什么是Harris角点检测算法,如何实现?
- 23、什么是FAST算法?如何实现
- 24、什么是HOG特征,如何实现?
- 25、什么是Haar-cascade分类器,怎么实现?
- 26、怎么检测图像中的直线,有哪些常见的直线检测算法?
- 27、怎么检测图像中的圆形,有哪些常见的圆形检测算法?
- 28、怎么检测图像中的椭圆?
- 29、什么是形态学重建,如何实现?
- 30、什么是灰度共生矩阵,有哪些常见的灰度共生矩阵算法?
- 31、什么是拉普拉斯算子,如何实现拉普拉斯算子?
- 32、什么是高斯金字塔,列举一些常见的高斯金字塔算法。
- 33、什么是拉普拉斯金字塔,有哪些常见的拉普拉斯金字塔算法?
- 34、什么是图像压缩,有哪些常见的图像压缩算法?
- 35、图像融合是什么?
- 36、动态规划
- 37、分形分析
- 38、颜色定位
- 39、边缘增强
- 40、自适应滤波
- 41、怎么去除图像中的条纹干扰
- 42、怎么去除图像中的毛刺点
- 43、怎么去除图像中的关照影响
- 44、什么是CAMshift算法,如何实现
- 45、什么是Mean Shift算法,如何实现
- 46、LBP算法
- 47、什么是AdaBoost算法
- 48、视觉单应性是什么?如何实现视觉单应性计算?
- 49、有哪些常见的直线检测算法
- 50、怎么检测图像中的环形结构,有哪些常见的环检测算法
- 51、什么是四位映射,有哪些常见的思维映射算法?
- 52、什么是卷积,有哪些常见的卷积算法
- 53、什么是离散傅里叶变换(DFT),有哪些常见的DFT算法
- 54、什么是小波变换?
- 55、什么是PID控制算法?如何应用到图像处理中
- 56、什么是形态学滤波,有哪些常见的形态学滤波算法?
- 57、什么膨胀和腐蚀,如何实现?
- 58、什么图像处理中的基本数学运算,包括哪些常用的数学运算?
- 59、什么是图像配准,有哪些常见图像配准算法?
- 60、什么是图像分析,有哪些常见的图像分析算法?
- 61、什么是特征点描述符?
- 62、什么是直方图匹配,如何实现?
- 63、什么是模糊边缘检测
- 64、自适应形态学算法
- 65、怎么实现图像的旋转缩放
- 66、怎么实现拉镜效果,有哪些常见的拉镜算法
- 67、怎么实现流媒体解码
- 68、什么是图像识别?有哪些图像识别算法?
- 69、什么是颜色空间?
- 70、什么是图像噪声?
- 71、怎么实现图像的透视变换
- 72、小波包分析
- 73、什么是半监督学习
- 74、什么是脊线检测
- 75、什么是密度聚类
- 76、什么是K均值聚类
- 77、什么是图像分类
- 78、图像搜索是什么?
- 79、有哪些常用的二维码识别算法
- 80、什么是光流法
- 81、图像局部特征提取是什么?
- 82、什么是缩放金字塔?
- 83、图像检索技术
- 84、运动跟踪
- 85、什么是骨架提取,怎么实现骨架提取?
- 86、什么是形态学梯度
- 87、结构化光行扫描
- 88、什么是相位相关,怎么实现?
- 89、什么是三维重建?
- 90、什么是空间变换
- 91、什么是视差估计
- 92、什么是灰度共生矩阵
- 93、变量步长直线检测
- 94、二值形态学滤波
- 95、基于深度学习的图像处理算法?
- 96、什么是Canny算法,怎么实现
- 97、什么是国际灰度共存矩阵(GLCM),怎么实现
- 98、什么是图像缩放
- 99、什么是Laplacian of Gaussian(LoG)算法,怎么实现
- 100、什么是Sobel算子,怎么实现
- 101、什么是Prewitt算子,怎么实现
- 102、什么是SUSAN算法,怎么实现
- 103、边缘连接
- 104、分水岭算法
- 105、基尔霍夫滤波
- 106、显著性检测,
- 107、什么是水平集,怎么实现
- 108、Watershed算法
- 109、形态学膨胀是什么?怎么实现
- 110、线阵相机选型的步骤
- 深度学习方向,图像检测算法面试问题
-
- 0、非常究极无敌重要
- 1、说一下池化层
- 2、说一下卷积层
- 3、说一下全连接层
- 5、说一下深度学习图像检测的基本运行原理
- 6、什么是深度学习
- 7、说一下卷积神经网络(CNN)
- 8、循环神经网络(RNN)
- 9、生成对抗网络(GAN)
- 10、强化学习是什么?
- 11、什么是梯度下降
- 12、什么是反向传播
- 13、什么是dropout
- 14、什么是批量标准化
- 15、什么是卷积核
- 16、池化
- 17、什么是卷积神经网络的层级
- 18、什么是循环神经网络的层级
- 19、循环神经网络的记忆单元(cell)是什么?
- 20、你是如何解决过拟合问题的?
- 21、你是如何选择激活函数的
- 22、怎么选择合适的分类器
- 22、怎么选择优化器
- 23、什么是超参数
- 24、怎么调整超参数
- 25、什么是学习率
- 26、什么是动量法
- 27、Adam优化器
- 28、均方误差(MSE)
- 29、什么是交叉熵(cross-entropy)损失函数
- 30、L1和L2正则化
- 31、特征提取是什么
- 32、 迁移学习
- 33、数据增强是什么
- 34、图像分割是什么
- 35、图像分类
- 36、目标检测
- 37、语义分割
- 38、实例分割
- 39、生成式对抗网络
- 40、自编码器
- 41、变分自编码器
- 42、条件生成模型
- 43、什么是强化学习的马尔科夫决策过程
- 不常见的问题
- 下一阶段学习内容
OpenCV面试问题
1、OpenCV中cv::Mat的深拷贝与浅拷贝问题
深拷贝:分配新内存的同时拷贝数据,当被赋值的容器被修改时,原始容器数据不会改变。
浅拷贝:仅拷贝数据,当被赋值的容器修改时,原始容器数据也会总同样改变。
OpenCV的Mat有几种赋值方式:
深拷贝是b = a.clone()
和a.copyTo(b)
浅拷贝是b=a
和b(a)
关于这个问题,OpenCV中ROI就是图像的截图,发现ROI也是浅拷贝。
C++中利用OpenCV存储图像的结构体是MAT。
2、OpenCV中的RGB2GRAY是怎么实现的
本质上就是寻找一个三维空间到一维空间的映射,以RGB三个轴建立空间直角坐标系,图片上每一个像素点都可以用一个点表示,就可以通过一个公式:
Gray = 0.2990XR + 0.58700XG + 0.11400XB
,来完成一维空间的映射。
3、连续图像转换为数字图像需要进行哪些操作?
取样,量化
4、数字图像中有哪些基本特
颜色特征、纹理特征、形状特征、空间关系特征等
5、图像边缘检测中常用的算子有哪些?
Roberts算子,Prewitt算子、Sobel算子、Canny算子、Laplacian算子等。
6、对霍夫变换的理解
霍夫变换常用来提取图像中的直线和圆等几何形状,它通过一种投票算法检测具有特定形状的物体,就是通过计算累计结果的局部最大值得到一个符号该几何形状的几何作为结果。
算法原理:针对每个像素点,使得θ
在
这里是引用
-90度到180度之间,用霍夫空间坐标系公式计算得到共270组(ρ,theta)代表着霍夫空间的270条直线,将这270组值存储到H中,如果一组点共线,则这组点的每个值,都会使得H(ρ,theta)加一,因此找到最大的H值,就是共线的点最多的直线,也可以通过设定阈值来判定。
7、对HOG特征的理解
HOG(方向梯度直方图)特征是一种用于目标检测和图像识别的特征描述方法,其主要思想是在图像中寻找局部区域的梯度方向直方图。
原理: HOG特征通过计算图像中每个像素点的梯度方向和大小,然后将图像分割为小的局部区域,对每个局部区域内的像素进行梯度方向直方图统计。
将相邻的若干个局部区域组成一个块(Block),对块内的多个局部区域的梯度直方图进行归一化。
最终将归一化的块向量串联起来形成最终的特征向量,用于表示整个图像。
特点: 方向性:HOG特征对图像中的边缘和纹理方向敏感,能描述物体的边缘结构和形状。
局部性:每个局部区域的梯度信息在特征中是局部的,这使得HOG特征对局部图
案的变换具有一定的鲁棒性。
不变性:HOG特征
趋势:随着深度学习技术的发展,传统HOG特征在一定场景下逐渐被深度学习取代。尤其是在大规模数据集和复杂任务下,深度学习模型通常能提供更好的性能和更高的准确率。然而,HOG特征作为一种经典的特征提取方法,仍然在一些特定场景和资源有限的环境中保持其价值,或者作为深度学习模型的辅助特征使用。
实例: 假设我们有一张简单的图像,现在想用HOG特征描述图像中的一辆车,那么步骤如下:
(1)图像预处理:如将其转换为灰度图像(因为HOG通常在灰度图像上计算)
(2)计算梯度图像:通过计算图像的水平和垂直方向上的梯度,可以得到每个像素点的梯度大小和方向。
(3)计算梯度方向直方图:将图像分割为小的像素块,对每个像素块内的梯度方向进行统计,得到每个像素块的梯度方向直方图。
(4)块归一化:对每个像素块的梯度方向直方图进行归一化,即对每个像素块内的梯度特征进行局部对比度归一化,以减少光照变化的影响。
(5)形成最终的HOG特征向量:将每个块的归一化梯度方向直方图串联起来,形成最终的HOG特征向量。
(6)应用分类器:使用SVM或者其他分类器,对HOG特征向量进行训练和预测。
8 什么是opencv,它主要用于哪些领域?
opencv是一个开源的计算机视觉和机器学习软件库。它最初由Intel开发,旨在为实时视觉应用程序提供一个通用的基础设施,现在则由一个活跃的社区维护和更新。opencv具有C++,python,java等多种编程语言接口,可在Windows/Linux/mac/OS等多个操作系统上运行。
opencv主要用于以下领域:
(1)图像处理:包括图像的基本操作(如剪切/缩放/旋转),颜色空间转换 滤波 边缘检测等。
(2)计算机视觉:用于实现面部识别 目标i检测 3D重建 运动分析 机器人视觉等功能。
(3)机器学习:opencv内置了一些简单的机器学习算法,如K-最近邻算法 支持向量机 决策树等,常用于模式识别和分类任务。
(4)实时视频处理:可以用于视频捕捉 视频流处理 视频分析等。
(5)增强现实:opencv可以用于创建增强现实应用,比如追踪图像上的特定标记来叠加虚拟对象
(6)交互式艺术作品:在艺术和创新领域,opencv可以帮助艺术家创建互动式的艺术作品,响应观众的动作或环境变化。
因其强大的功能和广泛的应用领域,opencv已经成为学术界和工业界广泛使用的工具之一。
9 opencv中的Mat对象是什么,它是如何在图像处理中使用的?
在opencv中,Mat对象是一个非常重要的数据结构,用于存储图像,Mat代表了矩阵,它是opencv库中用于图像处理和计算机视觉的核心部分。
Mat对象的特点:
(1)多维度支持:Mat可以支持2D图像处理,也可以出现更高维度的数据。
(2)数据类型灵活:它可以存储不同类型的数据,如uchar``float``double
等
(3)自动内存管理:Mat对象采用引用计数的方式自动管理内存。当没有任何对象指向某块内存时,该内存会被自动释放。
(4)高效访问和操作:提供了多种方法来访问和修改图像数据,包括直接访问单个像素 操作图像区域 图像分割等。
在图像处理中的作用
(1)图像读取和显示:利用imread
函数读取图像时,返回的就是一个Mat对象。显示图像时,也是通过imshow
函数将Match对象展示出来。
(2)图像的基本操作:对图像进行缩放 旋转 裁剪等操作时,都是在操作Mat对象。
(3)像素访问与修改:可以通过Mat对象直接访问和修改图像的每个像素值,用于图像滤波,颜色空间转换等。
(4)图像处理算法:无论是边缘检测,特征提取,图像分割,还是高级算法如面部识别,目标跟踪等,都是通过Mat对象中的数据进行操作来实现的。
(5)与其他数据结构的转换:Mat对象可以与其它图像处理相关的数据结构相互转换,也可以与标准䣌C++数据结构(如`std::vector)进行交互。
因此,Mat是opencv中用于图像处理的基石,几乎所有的opencv操作都涉及到Mat对象的使用。掌握如何高效地使用Mat对象是进行opencv编程的关键。
10 解释opencv中的图像数据结构及其各个通道。
在opencv中,图像主要是通过Mat对象来表示和存储的。这个数据结构是非常灵活和强大的,它可以处理从单色图像到高维度的多通道图像。
Mat对象的结构:
(1)数据类型:Mat
对象可以存储各种类型的数据,例如uchar``int``float``double
等。这些类型决定了每个像素点可以表示的值的范围和精度。
(2)维度:虽然在处理图像时通道时二维(宽度和高度)的,但Mat
对象可以支持多于两个维度的数据,这在处理视频或医学图像等更复杂的数据时非常有用。
(3)大小:表示图像的宽度和高度
(4)通道:这是图像数据结构中非常重要的一个概念。一个通道通常代表图像中的一种颜色信息。最常见的是三通道的彩色图像,分别代表红色 绿色和蓝色
图像通道:
(1)单通道:灰度图像只有一个通道,表示亮度和灰度信息,每个像素值一般是从0(黑色)~255(白色)
(2)三通道(RGB):彩色图像通常有三个通道,分别对应红色个 绿色和蓝色。每个通道都有一个亮度值,通过这三个值的组合来表示不同的颜色。
(3)四通道(RGBA):在RGB的基础上增加了一个透明度通道,用于表示图像的透明度。
在图像处理中的作用:
(1)通道的分离与合并:在某些i情况下,你可以需要对图像的单独通道进行操作。例如,调整彩色图像中的忒的那个颜色,或者在图像处理算法中只关注一个颜色通道。opencv提供了方便的函数来分离和合并这些通道。
(2)颜色空间转换:opencv可以轻松地在不同的颜色空间之间转换图像,例如从RGB转换到HSV或其他颜色空间。这在某些类型的图像处理中非常有用,比如在复杂光照条件下的颜色检测。了解和操作这些数据结构是进行有效图像处理的关键。opencv提供了丰富的API来处理这些结构,使得图像分析和处理变得更加高效和直观。
11 opencv中的图像类型和深度有哪些?
opencv中的图像类型和图像深度时通过Mat对象的数据类型来定义的。这个数据类型是由两部分组成:数据的深度和通道数。数据的深度决定了每个像素可以表示的值的范围和精度,而通道数决定了图像可以包含的颜色信息量。
图像深度
在opencv中,图像深度是指每个像素值的位数,常见的图像深度包括:
(1)CV_8U:
(2)CV_8S
(3)CV_16U
(4)CV_16S
(5)CV_32S
(6)CV_32F
通道数
图像的通道数表示每个像素点可以包含的颜色信息量,常见的通道数包括:
(1)单通道:一般用于灰度图像
(2)三通道:
(3)四通道
图像类型的表示
在opencv中,图像类型通道是通过将深度和通道数结合起来的一个整数来表示的。例如,CV_8UC3表示一个8为无符号整数 3通道的图像类型,也就是常见的24位彩色图像(8位X3通道)。
掌握这些图像类型和深度对于理解和实现不同的图像处理任务是非常重要的,因为不同的任务可能需要对图像数据进行不同的操作和处理。
传统图像算法面试问题
1、什么是边缘检测,如何实现?
边缘检测是一种计算机视觉技术,用于检测图像的边缘区域。边缘区域是指图像中亮度变化较大的地方,通常表示了物体的轮廓和纹理信息。边缘检测算法通常通过分析图像中相邻像素的亮度值差异,来确定图像中的边缘位置和方向,并对边缘进行增强和提取。边缘检测在计算机视觉领域广泛应用于图像识别、目标追踪、图像分割和图像特征提取等方面。常见的边缘检测算法有Sobel算子、Canny算子、Laplacian算子等。
边缘检测的步骤为:
- (1) 图像预处理:灰度化、去噪等处理,使图像的边缘更加明显
- (2)计算图像梯度:通过计算图像的梯度,可以确定图像中亮度变化最大的地方,也就是边缘。sobel和prewitt算法是比较常见的梯度算法
- (3)非极大值抑制:对梯度方向上的像素进行非极大值抑制,使得只有亮度值最大的像素被保留,其他像素被抑制
- (4)双阈值处理:将梯度值划分为强边缘和弱边缘,并且将弱边缘中与强边缘相连的部分保留下来
- (5)边缘连接:将强边缘和弱边缘相连形成完成的边缘线
目前canny检测算法被认为是最优的算法,它具有准确性高、可靠性强、鲁棒性好等特点,是一种比较优秀的算法。
2、什么是二值化,如何实现?
二值化是将图像像素点的灰度值转换为黑白两色的过程。二值化后,图像中的像素只有黑色或白色;灰色的像素值被指定为黑或白。二值化的目的是简化图像信息,减少计算量和内存占用,以便于图像处理与分析。常见二值化方法包括阈值法、OTSU算法等。
下面是使用C++ 语言实现二值化的代码,图片需要本地。
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv) {
// 读入彩色图像
Mat image = imread("123.png", 1);
// 将彩色图像转换为灰度图像
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// 对灰度图像进行全局阈值二值化
Mat binaryImage;
threshold(grayImage, binaryImage, 128, 255, THRESH_BINARY);
// 显示二值图像
imshow("Binary Image", binaryImage);
waitKey(0);
return 0;
}
3、什么是直方图均衡化,如何实现?
直方图均衡化是一种用于调整图像亮度以增强对比度的图像处理方法。该方法可以使图像的亮度分布变得更加平坦,从而在视觉上增加图像的清晰度和对比度。
直方图均衡化的实现方法如下:
- 1、计算图像的直方图
将图像中的所有像素点的灰度值(0~255)进行统计,得到每个灰度级别下像素的数量。- 2、计算累计分布函数(CDF)
将直方图中每个灰度级别下的像素数除以总像素数,得到每个灰度级别的像素累计分布函数- 3、计算灰度级别映射值:
将CDF转换为灰度级别映射值,公式为:s=T®=L-1×∑j=0rPj,其中s
为映射后的灰度级别,r
为原始灰度级别,L
为图像亮度级别,Pj
为累计分布函数。- 4、将原始图像中每个像素的灰度级别映射到新的灰度级别值
- 5、输出均衡化后的图像
直方图均衡化的实现可以使用计算机程序,例如Python中的opencv库或者MATLAB等数学软件。
如果用底层代码实现直方图均衡化,是这样的,我已经把它封装成为了一个函数:
import cv2
import matplotlib.pyplot as plt
def histogram_equalization(image):
# 初始化长度为256的列表,存储每个像素值的数量
pixel_count = [0] * 256
# 计算像素值大小为i的像素数量,存在pixel_count[i]中
for row in image:
for pixel in row:
pixel_count[pixel] += 1
# 计算概率,每个像素值的数量除以总像素数量即为概率
probabilities = [count / (image.shape[0] * image.shape[1]) for count in pixel_count]
# 计算累计概率分布函数
cumulative_distribution = []
cumulative_sum = 0
for probability in probabilities:
# 累计概率分布函数:将每个概率累加,存储在累计概率分布函数列表中
cumulative_sum += probability
cumulative_distribution.append(cumulative_sum)
# 计算灰度级别映射值,灰度级别映射值等于累计概率分布函数值乘以最大灰度级别,取整后得到整数灰度级别
mapping = [round(value * 255) for value in cumulative_distribution]
# 将灰度级别映射值应用于原始图像,将图像中的每个像素值根据映射值进行替换
for i in range(image.shape[0]):
for j in range(image.shape[1]):
pixel = image[i][j]
image[i][j] = mapping[pixel]
# 返回均衡化后的图像
return image
if __name__ == '__main__':
if __name__ == '__main__':
# 加载图像
image = cv2.imread('./image/input/123.png', 0)
# 检查图像是否成功加载
if image is None:
print('Error: Could not open or find the image.')
else:
# 对图像进行直方图均衡化
equalized_image = histogram_equalization(image)
# 显示均衡化后的图像
plt.subplot(1, 2, 2)
plt.imshow(equalized_image, cmap='gray')
plt.title('Equalized Image')
# 显示图像
plt.show()
这是底层代码,其中的数学公式分别为:
像素计数:计算像素值大小为i的像素数量,存在pixel_count[i]中:
p i x e l c o u n t [ i ] = ∑ j = 0 h e i g h t ∑ k = 0 w i d t h I [ j , k ] = n i pixel_count[i] = \sum_{j=0}^{height}\sum_{k=0}^{width} I[j,k] = n_i pixelcount[i]=j=0∑heightk=0∑widthI[j,k]=ni
其中, I [ j , k ] I[j,k] I[j,k]表示原始图像中位于第 j j j行第 k k k列的像素值, h e i g h t height height、 w i d t h width width分别表示原始图像的高度和宽度, n i n_i ni表示像素值为 i i i的像素数量。
概率计算:每个像素值的数量除以总像素数量即为概率:
P i = n i N P_i = \frac{n_i}{N} Pi=Nni
其中, N N N为原始图像的像素总数。
累计概率分布函数:将每个概率累加,存储在累计概率分布函数列表中:
c i = ∑ j = 0 i P j c_i = \sum_{j=0}^{i} P_j ci=j=0∑iPj
其中, c i c_i ci表示像素值小于等于 i i i的像素的累计概率分布函数。
灰度级别映射值:
S i = T ( R i ) = L − 1 N ∑ j = 0 i n j S_i = T(R_i) = \frac{L-1}{N}\sum_{j=0}^{i} n_j Si=T(Ri)=NL−1j=0∑inj
其中, L L L表示灰度级别数, N N N为原始图像的像素总数, n j n_j nj表示像素值为 j j j的像素数量, R i R_i Ri表示原始图像中像素值为 i i i的像素, S i S_i Si表示i值的映射结果。
映射原始图像中的每个像素值:
I ′ ( i , j ) = T ( I ( i , j ) ) I'(i,j) = T(I(i,j)) I′(i,j)=T(I(i,j))
其中, I ′ I' I′为处理后的图像, I I I为原始图像。
4、什么是形态学操作,有哪些常见的形态学操作?
形态学操作是数字图像处理中的一种基本操作,它利用结构元素对图像进行像素点的灰度值变换、形态学膨胀、形态学腐蚀、开操作、闭操作等简单操作,来实现图像的去噪、分割、预处理等目的。
常见的形态学操作有:
(1)膨胀(Dilation)
该操作可以使对象区域向外面扩张,它将结构元素置于待处理的二值图像上,任何重叠的像素值设为1,。这个过程会使图像的面积增加,填充细小空洞与连接破碎的对象。
下面是使用C++实现膨胀的代码。
void Dilation()
{
// imread函数读取待处理的图像,IMREAD_GRAYSCALE表示以灰度图像的方式读入。
Mat img = imread("123.png", IMREAD_GRAYSCALE);
// 创建一个大小为(3,3)的正方体结构元素
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
// 进行膨胀操作
Mat img_dilate; // 表示膨胀处理后的图像
dilate(img, img_dilate, element);
// 显示原图像与膨胀后的图像
imshow("Input Image", img);
imshow("Dilated Image", img_dilate);
waitKey(0);
return;
}
如果用底层代码而不使用库函数的话,代码是这样的:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("test.png");
int kernel_size = 3; // 结构元素行数(或列数)
int anchor_point = kernel_size / 2; // 结构元素中心点位置
Mat result_img = Mat::zeros(img.rows, img.cols, CV_8UC1);
// 遍历每个像素
for (int row = 0; row < img.rows; row++) {
for (int col = 0; col