九、答案
第 1 章,构建图像查看器
- 我们使用消息框来告诉用户他们在尝试查看第一张图像之前的图像或最后一张图像之后的图像时已经在查看第一张或最后一张图像。 但是,还有另一种处理方法:当用户查看第一张图像时禁用
prevAction
,而当用户查看最后一张图像时禁用nextAction
。 我们该如何处理?
QAction
类具有bool enabled
属性,因此具有setEnabled(bool)
方法,我们称其为启用或禁用prevImage
和nextImage
方法中的相应动作。
- 我们的菜单项或工具按钮上只有文字。 我们如何向他们添加图标图像?
QAction
类具有QIcon icon
属性,因此具有setIcon
方法,您可以创建和设置操作图标。 要创建QIcon
对象,请参考这里上的相应文档。
- 我们使用
QGraphicsView.scale
放大或缩小图像视图。 图像视图如何旋转?
使用QGraphicsView.rotate
方法。
moc
有什么作用?SIGNAL
和SLOT
宏有什么作用?
moc
命令是 Qt 元对象系统编译器。 它主要从包含QOBJECT
宏的用户定义类中提取所有与元对象系统相关的信息,包括信号和时隙。 然后,它创建一个名称以moc_
开头的 C++ 源文件来管理此元信息(主要是信号和插槽)。 它还提供了该文件中信号的实现。 SIGNAL
和SLOT
宏将其参数转换为字符串,该字符串可用于在由moc
命令管理的元信息中找到相应的信号或时隙。
第 2 章,像专家一样编辑图像
- 我们如何知道 OpenCV 函数是否支持原地操作?
如本章所述,我们可以参考与该函数有关的正式文件。 如果文档规定它支持原地操作,则支持,否则,不支持。
- 如何将热键添加到我们作为插件添加的每个操作中?
我们可以向插件接口类添加一个新方法,该方法返回QList<QKeySequence>
实例并在具体的插件类中实现。 加载插件时,我们调用该方法以获取快捷键序列,并将其设置为该插件操作的热键。
- 如何添加新操作以丢弃应用中当前图像中的所有更改?
首先,将QPixmap
类型的类字段添加到MainWindow
类中。 在编辑当前图像之前,我们将图像的副本保存到该字段。 然后,我们添加一个新动作和一个连接到该动作的新插槽。 在插槽中,我们将保存的图像设置为图形场景。
- 如何使用 OpenCV 调整图像大小?
第 3 章,家庭安全应用
- 我们可以从视频文件而不是从摄像机检测运动吗? 如何实现的?
我们可以。 只需使用视频文件路径来构造VideoCapture
实例。 可以在这个页面上找到更多详细信息。
- 我们可以在不同于视频捕获线程的线程中执行运动检测工作吗? 如果是这样,这怎么可能?
是。 但是我们应该使用多种同步机制来确保数据安全。 另外,如果我们将帧分派到不同的线程,则必须确保将结果帧发送回并即将显示时,它们的顺序也正确。
- IFTTT 允许您在发送的通知中包括图像-当通过 IFTTT 的此功能向您的手机发送通知时,我们如何发送检测到的运动图像?
首先,在 IFTTT 上创建小程序时,选择从 IFTTT 应用发送丰富通知作为that
服务。 然后,当检测到运动时,我们将帧作为图像上传到诸如 imgur 之类的位置,并获取其 URL。 然后,将图像 URL 作为参数发布到 IFTTT Webhook,并使用该 URL 作为富格式通知中的图像 URL,该格式可以在其主体中包含图像 URL。
第 4 章,人脸上的乐趣
- LBP 级联分类器可以用来自己检测人脸吗?
是。 只需使用 OpenCV 内置的lbpcascades/lbpcascade_frontalface_improved.xml
分类器数据文件。
- 还有许多其他算法可用于检测 OpenCV 库中的人脸标志。 其中大多数可以在这个页面中找到。 自己尝试一下。
可以通过以下链接使用不同的函数,创建不同的算法实例。 所有这些算法都与本章中使用的 API 具有相同的 API,因此您只需更改它们的创建语句即可轻松尝试这些算法。
- 如何将彩色装饰物应用到脸上?
在我们的项目中,视频帧和装饰物均为BGR
格式,没有 alpha 通道。 考虑到装饰物有白色背景,我们可以使用cv::threshold
函数先生成一个遮罩。 遮罩是二进制图像,背景为白色,前景(装饰的一部分)为黑色。 然后,我们可以使用以下代码来应用装饰:
frame(rec) &= mask;
ornament &= ^mask;
frame(rec) |= ornament;
第 5 章,光学字符识别
- Tesseract 如何识别非英语语言的字符?
初始化TessBaseAPI
实例时,请指定相应的语言名称。
- 当我们使用 EAST 模型检测文本区域时,检测到的区域实际上是旋转的矩形,而我们只是使用其边界矩形。 这总是对的吗? 如果没有,该如何纠正?
是正确的,但这不是最佳方法。 我们可以将旋转矩形的边界框中的区域复制到新图像,然后旋转并裁剪它们以将旋转矩形转换为规则矩形。 之后,通常通过将生成的规则矩形发送到 Tesseract 来提取文本,通常将获得更好的输出。
- 尝试找出一种方法,允许用户在从屏幕捕获图像时拖动鼠标后调整所选区域。
通常的方法是在选定区域的边界矩形的顶点和侧面上插入八个手柄,然后用户可以拖动这些手柄以调整选定区域。 这可以通过扩展我们的ScreenCapturer
类的paintEvent
和mouse*Event
方法来完成。 在paintEvent
方法中,我们绘制选择矩形及其句柄。 在mouse*Event
方法中,我们检查是否在手柄上按下了鼠标,然后通过拖动鼠标重新绘制选择矩形。
第 6 章,实时对象检测
- 当我们针对波士顿公牛的脸部训练级联分类器时,我们会在每个图像上自行标注狗的脸部。 标注过程非常耗时。 网站上有该数据集的标注数据压缩包。 是否可以使用一段代码从此标注数据生成
info.txt
文件? 如何才能做到这一点?
该压缩文件中的标注数据与狗的身体有关,而不与狗的脸有关。 因此,我们不能使用它来训练狗脸的分类器。 但是,如果您想为狗的全身训练分类器,这会有所帮助。 该压缩文件中的数据以 XML 格式存储,标注矩形是具有//annotation/object/bndbox
路径的节点,我们可以轻松提取该路径。
- 尝试找到预训练的(快速/快速)R-CNN 模型和预训练的 SSD 模型,运行它们,然后将其性能与 YOLOv3 进行比较。
以下列表提供了一些 Faster R-CNN 和 SSD 模型。 如果您对它们之一感兴趣,请自己进行测试:
- 我们可以使用 YOLOv3 来检测某种对象,但不是全部 80 类对象吗?
是的,您可以根据特定的类 ID 过滤结果。 在第 7 章,“实时汽车检测和距离测量”中,我们采用了这种方法来检测汽车,请仅参考该章。
第 7 章,实时汽车检测和距离测量
- 测量汽车之间的距离时是否有更好的参考对象?
可可数据集中有许多类,其中对象通常具有固定位置; 例如,交通信号灯,消防栓和停车标志。 我们可以在相机视图中找到其中一些,选择其中任意两个,测量它们之间的距离,然后将所选对象及其距离用作参考。