图像算法工程师知识题(三)——究极无敌大总结

文章目录



OpenCV面试问题

1、OpenCV中cv::Mat的深拷贝与浅拷贝问题

深拷贝:分配新内存的同时拷贝数据,当被赋值的容器被修改时,原始容器数据不会改变。
浅拷贝:仅拷贝数据,当被赋值的容器修改时,原始容器数据也会总同样改变。
OpenCV的Mat有几种赋值方式:
深拷贝是 b = a.clone()a.copyTo(b)
浅拷贝是b=ab(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=0heightk=0widthI[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=0iPj
其中, 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)=NL1j=0inj
其中, 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 
RCNN(Region-based Convolutional Neural Networks)算法是一种用于目标检测的深度学习算法。其思想是将输入图像分割成不同的区域,然后对每个区域进行卷积神经网络的特征提取,最后通过分类模块判断每个区域是否包含感兴趣的目标。 RCNN算法的主要步骤包括: 1. 输入图像经过Selective Search算法对图像进行区域提取,生成多个候选区域。 2. 将每个候选区域调整为同样的尺寸,以适应卷积神经网络的输入要求。 3. 使用预训练的卷积神经网络(如AlexNet或VGGNet)对每个候选区域进行前向计算,提取该区域的特征表示。 4. 将每个候选区域的特征表示输入到一个全连接层中进行分类,判断该区域是否包含目标物体,并输出预测结果。 5. 对于输出的预测结果,使用非值抑制(Non-Maximum Suppression,NMS)算法进行处理,去除重叠的检测结果。 RCNN算法的核心思想就是利用卷积神经网络来提取图像的特征表示,然后通过分类模块对每个候选区域进行分类预测。相比于传统的滑动窗口方法,RCNN算法只对候选区域进行处理,减少了计算量。 然而,RCNN算法存在的一个问是速度较慢,因为需要对每个候选区域分别进行卷积神经网络的计算。为了提高速度,后续的改进算法如Fast R-CNN和Faster R-CNN应运而生。 总的来说,RCNN算法通过将图像分割为候选区域,并利用卷积神经网络提取区域特征,实现了目标检测的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智刃纪元

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值