38、基于内容的图像搜索与高性能计算

基于内容的图像搜索与高性能计算

1. 基于内容的图像搜索

1.1 相关程序及其功能

在基于内容的图像搜索中,有一系列的程序发挥着不同的作用,以下是这些程序及其功能的详细介绍:
| 程序名 | 功能 |
| — | — |
| convert.c | 将主文本特征文件转换为二进制文件,二进制文件读取速度更快且更便捷 |
| display.c | 显示数据集目录中的图像 |
| listGreyFiles.c | 创建灰度图像名称的主文件 |
| makeCM.c | 生成颜色中心矩的文件 |
| makeMaster.c | 通过扫描目录创建图像的主文件 |
| makeMaster2.c | 使用主文件中的图像创建图像特征的主文本文件 |
| makeMasterGrey.c | 为灰度图像数据集创建主特征文件(仅二进制) |
| quadtree.c | 构建并显示基于颜色的四叉树 |
| search1.c | 搜索图像,从控制台读取图像文件名,并在数据集中搜索相似图像 |
| search2.c | 使用数据集中已收集的特征测试提取的特征,进行搜索并收集统计信息 |
| searchCM.c | 在一组彩色图像上测试一组颜色特征 |
| searchGrey.c | 通过使用预计算的特征进行 654 次搜索并收集统计信息,测试一组灰度特征 |
| searchGreyMoments.c | 使用灰度矩进行搜索,进行 600 多次搜索并收集统计信息 |
| searchGreyQuad.c | 使用灰度直方图(包括四叉树)进行搜索,进行 654 次搜索并收集统计信息 |

1.2 图像搜索系统示例

以下是一些图像搜索系统的示例:
- Efficient and Effective Querying by Image Content :能够高效且有效地通过图像内容进行查询。
- Multimedia Analysis and Retrieval System (MARS) Project :多媒体分析和检索系统项目。
- NetRa, A Toolbox for Navigating Large Image Databases :用于导航大型图像数据库的工具包。
- Supporting Similarity Queries in MARS :支持 MARS 中的相似性查询。
- VisualSEEK: A Fully Automated Content-based Image Query System :一个完全自动化的基于内容的图像查询系统。

2. 高性能计算在视觉和图像处理中的应用

2.1 计算能力的发展

英特尔创始人戈登·E·摩尔曾指出,集成电路上可放置的晶体管数量每 20 个月翻一番。这意味着在固定价格下可购买的计算能力也以相同速度翻倍。多年来,这主要通过使 CPU 更小、更快来实现。但自 2007 年左右以来,速度提升不仅得益于更快的单核 CPU,还得益于并行计算(使用多个处理器)。到 2010 年,很少能找到运行速度超过 3.5 GHz 的单核 PC,而拥有 3 或 4 个处理器、每个处理器速度超过 3 GHz 的 PC 则相对常见。这些多核系统比 2005 年的单核系统更便宜,且能完成更多工作。

2.2 并行计算的适用场景

在问题本身和数据都能分割的情况下,多核 CPU 系统比单核系统在单位时间内可完成更多计算。例如,二维傅里叶变换就属于这类问题,其每一行可独立变换,可由不同处理器处理,之后再处理列。然而,排序问题则不适合并行计算,使用多个处理器对一组数字进行排序很难获得计算优势。大多数图像处理任务可应用于图像的部分,之后再合并成完整图像,因此并行计算可用于提升性能。考虑到过去十年典型图像尺寸的增加以及许多图像处理方法的算法复杂性,并行计算是一个值得考虑的选择。

2.3 并行计算的开销

将问题分割成多个部分会带来一定的开销,这会影响速度提升,实际上也限制了可实现的增益。此外,还存在编程成本,以及设备和软件方面的成本。接下来将探讨一些相对简单且经济的实现并行性的方法。

2.4 多处理器计算的范式

2.4.1 向量计算机

向量计算机使用特殊硬件对多个数据元素进行多次计算。例如,它能在乘法两个数字所需的时间内,将向量的每个元素与另一个数字相乘,从而将计算时间加快 N 倍(N 为向量的大小)。但向量计算机是专用机器,价格昂贵。而且,N 倍的加速依赖于设置(需要时间),因此只有在进行大量计算时才能获得增益。

2.4.2 分布式计算

分布式计算涉及将问题的部分发送到各个处理器(或网络上的计算机)。每个处理器完成其计算份额,并将结果发送回某个中央存储库。这种计算方式几乎不需要特殊硬件,但需要时间将数据发送到每个处理器,然后等待处理器返回答案。输入/输出所需的实际时间比计算或内存访问多得多。因此,只有当将数据发送到另一个处理器所需的时间短于进行计算并接收结果所需的时间时,分布式计算才比简单计算更快。

2.5 共享内存

共享内存多处理器拥有一组物理上彼此靠近的 CPU,它们可以使用相同的内存。这种物理上的接近提高了速度,但通常意味着硬件是专用的,且难以扩展。PC 上的多核 CPU 本质上就是共享内存多处理器,许多向量机也是如此。

共享内存多处理器在编程方面存在一些困难。虽然多个处理器可以同时读取相同的内存位置,但写入内存需要某种保护机制。否则,计算结果可能不可预测。例如,考虑一个在两台计算机上同时执行的程序,像素 (i,j) 的值为 RGB = (128, 84, 200):

Processor 1         Processor 2
get pixel p at i,j
p=(128, 84, 200)
g = green value at p
. . .
g = 84
r = red value at p
get pixel p at i,j
r=128; p=(128, 84, 200)
b = blue value at p
g = green value at p
b=200,
g=84
k = (r+b+g)/3
r = red value at p
k=137;
r=128
p = (k, 0, 0)
b = blue value at p
p=(137,0,0) b = 0
. . .
k = (r+b+g)/3
k = 137/3 = 46
p = (k, 0, 0)
p = (46,0,0)
. . .

当两个相同的程序使用相同的数据但稍微不同步运行时,会得到两个不同的结果。在一个处理器上,上述代码对像素 p 的颜色值进行平均,得到灰度值 (137,0,0)。而当两个进程同时使用相同的内存位置时,结果会大不相同,因为进程同时修改内存。在上述情况中,结果是 (46,0,0),但结果会根据交互方式的不同而变化。

使用共享内存时,一次只允许一个进程访问共享内存。这可以通过暂时停止一个进程,然后在安全时允许其继续来实现。修改一组共享内存位置的代码称为临界区,可以使用锁或信号量进行保护。重要的是,并行编程软件应提供此类保护,并且程序员应了解不当访问共享数据的后果。

2.6 消息传递

在分布式处理的这种范式中,程序被编写为一组独立的进程,它们通过在彼此之间发送数据包进行通信。数据包或消息可以有不同的类型,进程可以相互发送整数或浮点数作为数据。发送消息有多种方式,每种方式适用于不同类型的处理。一个进程可以向一组其他进程发送带有不同数据的消息,例如将矩阵的一行发送到傅里叶变换程序。同样,一个进程可以向大量进程发送消息,例如向代表图像部分的进程发送阈值。进程甚至可以组织成“循环”,其中 A 向 B 发送数据,B 向 C 发送数据,C 再向 A 发送数据。

进程可以在一台计算机、多核 CPU 或网络上的多台计算机上执行。消息传递系统具有很大的灵活性。一个程序可以利用大量处理器,也可以仅在一个处理器上运行完成。并且有许多工具可用于使用消息传递编写分布式程序,如 Message-Passing Interface (MPI) 系统。

2.7 执行时间测量

由于并行计算的目标是在更短的时间内产生结果,因此了解如何测量程序的执行时间非常重要。当然,结果的准确性是最重要的,如果一个更快的程序产生的答案错误或不准确,那么这个更快的程序就毫无用处,应该使用较慢但正确的程序。然而,在所有结果相同的情况下,更快的程序更受青睐。那么,如何测量执行时间并量化加速比呢?

2.7.1 使用 clock() 测量时间

测量时间的一种常见方法是使用 clock() 函数。它相对通用,可在 Unix、Linux(至少在 GNU 库中)和 Windows 系统(需要包含 windows.h 文件)上找到,并且易于使用。

clock() 函数不接受任何参数,返回一个 clock_t 类型的值,根据系统的不同,它可以是无符号整数或无符号长整数。在任何情况下,计时代码都很简单。 clock() 返回自重启(或类似操作)以来的时间,因此记录计算前后的时钟时间,然后相减。该函数返回的时间是以任意单位(时钟滴答)表示的,因此要将其转换为秒,需将测量时间乘以系统相关的常量 CLOCKS_PER_SEC ,即每秒的滴答数。现在就知道了执行时间。通常将这个时间转换为毫秒更有用,因此除以 1000 即可。

以下是一个使用 clock() 函数对简单计算进行计时的示例程序:

/* example of the use of clock() to time code */
#include "mpi.h"
#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <time.h>
#define BUFSIZE 1024
#define ITERS 1000
int main(int argc, char *argv[])
{
    int i, j, niter=0;
    double xtime, dat[BUFSIZE], y, z;
    clock_t cstart, cstop;
    for (niter=ITERS; niter < ITERS*1000; niter *= 2)
    {
        cstart = clock();
        for (j=0; j<niter; j++)
        {
            for (i=0; i<BUFSIZE; i++)
            {
                dat[i] = sin (3.1415926535 * i/1024.0);
            }
        }
        xtime = (double)(clock() - cstart)*CLK_TCK/1000.0;
        printf ("Iterations %d Clock time is %lf = %lf\n",
                niter, xtime, xtime/niter);
    }
    printf ("Returning.\n");
    return 0;
}

每次测量的时间值理论上应该是前一次测量值的两倍,但实际情况并非如此。以下是一个示例输出:

Iterations 1000 Clock time is 46.000000 = 0.046000
Iterations 2000 Clock time is 94.000000 = 0.047000
Iterations 4000 Clock time is 188.000000 = 0.047000
Iterations 8000 Clock time is 359.000000 = 0.044875
Iterations 16000 Clock time is 750.000000 = 0.046875
Iterations 32000 Clock time is 1531.000000 = 0.047844
Iterations 64000 Clock time is 2938.000000 = 0.045906
Iterations 128000 Clock time is 5875.000000 = 0.045898
Iterations 256000 Clock time is 11781.000000 = 0.046020
Iterations 512000 Clock time is 23531.000000 = 0.045959
Returning.

注意,小迭代次数的测量似乎不如大迭代次数的测量准确,这可以从每次迭代的连续计时差异中看出。实际上,时间是关键因素;程序运行的时间越长,使用 clock() 函数进行计时就越准确。

综上所述,基于内容的图像搜索和高性能计算在视觉和图像处理领域都有着重要的应用。通过合理选择和使用相关的程序和计算范式,可以提高图像搜索的效率和计算性能。同时,准确测量执行时间对于评估和优化程序性能至关重要。

2.8 不同测量结果分析

从上述使用 clock() 函数测量程序执行时间的示例输出可以看出,每次测量的时间值并非严格按照理论上的两倍关系增长。这是因为在实际的计算机系统中,存在多种因素会影响程序的执行时间。

2.8.1 系统开销

计算机系统在运行程序时,除了执行程序本身的代码外,还需要处理各种系统开销,如进程调度、内存管理、中断处理等。这些系统开销在每次测量中所占的比例可能不同,尤其是在小迭代次数的情况下,系统开销对总执行时间的影响更为显著,导致测量结果的准确性降低。

2.8.2 缓存效应

现代计算机系统通常具有多级缓存,当程序重复执行相同或相似的操作时,数据可能会被缓存到高速缓存中,从而减少了内存访问时间,提高了程序的执行速度。在大迭代次数的情况下,缓存效应更加明显,使得程序的执行时间相对稳定,测量结果也更加准确。

2.9 并行计算的性能评估指标

除了执行时间外,还有一些其他的指标可以用于评估并行计算的性能。

2.9.1 加速比

加速比是指并行计算相对于串行计算的速度提升倍数,计算公式为:
[S = \frac{T_{serial}}{T_{parallel}}]
其中,(T_{serial}) 是串行计算的执行时间,(T_{parallel}) 是并行计算的执行时间。加速比越大,说明并行计算的性能提升越明显。

2.9.2 效率

效率是指加速比与处理器数量的比值,计算公式为:
[E = \frac{S}{P}]
其中,(S) 是加速比,(P) 是处理器数量。效率反映了并行计算中处理器的利用率,效率越高,说明处理器的利用率越高。

2.10 并行计算的优化策略

为了提高并行计算的性能,可以采用以下优化策略:

2.10.1 负载均衡

负载均衡是指将任务均匀地分配到各个处理器上,避免出现某些处理器负载过重,而其他处理器闲置的情况。可以通过合理划分任务、动态调整任务分配等方式实现负载均衡。

2.10.2 减少通信开销

在分布式计算中,数据的通信开销是影响性能的重要因素之一。可以通过减少数据传输量、优化通信协议等方式减少通信开销。

2.10.3 优化算法

选择合适的并行算法可以显著提高并行计算的性能。例如,对于某些问题,可以采用分治法、动态规划等算法进行并行化处理。

2.11 并行计算在图像处理中的应用案例

以下是并行计算在图像处理中的一些应用案例:

2.11.1 图像滤波

图像滤波是图像处理中常用的操作之一,如高斯滤波、中值滤波等。可以将图像分成多个小块,每个小块由一个处理器进行滤波处理,最后将处理结果合并,从而提高滤波的速度。

2.11.2 图像分割

图像分割是将图像分成不同的区域,以便进行后续的分析和处理。可以采用并行算法对图像进行分割,如基于区域生长、阈值分割等方法。

2.11.3 特征提取

特征提取是从图像中提取有用信息的过程,如边缘检测、角点检测等。可以将图像分成多个部分,每个部分由一个处理器进行特征提取,最后将提取的特征合并,提高特征提取的效率。

2.12 总结与展望

在视觉和图像处理领域,基于内容的图像搜索和高性能计算都具有重要的意义。基于内容的图像搜索可以帮助用户快速找到所需的图像,而高性能计算则可以提高图像处理的速度和效率。

通过合理选择和使用相关的程序和计算范式,如共享内存、消息传递等,可以充分发挥多核处理器的优势,提高计算性能。同时,准确测量执行时间和评估性能指标,如加速比和效率,可以帮助我们优化程序,进一步提高性能。

未来,随着计算机技术的不断发展,如量子计算、人工智能等技术的应用,基于内容的图像搜索和高性能计算将迎来更广阔的发展前景。例如,量子计算可以提供更强大的计算能力,人工智能可以提高图像搜索的准确性和智能化程度。我们可以期待这些技术的融合将为视觉和图像处理领域带来更多的创新和突破。

以下是一个简单的 mermaid 流程图,展示了并行计算的基本流程:

graph LR
    A[开始] --> B[问题分割]
    B --> C[任务分配]
    C --> D[并行计算]
    D --> E[结果收集]
    E --> F[结果合并]
    F --> G[结束]

以下是一个表格,总结了并行计算的不同范式及其特点:
| 计算范式 | 特点 | 优点 | 缺点 |
| — | — | — | — |
| 向量计算机 | 使用特殊硬件对多个数据元素进行多次计算 | 计算速度快 | 价格昂贵,专用机器 |
| 分布式计算 | 将问题部分发送到各个处理器,处理器完成计算后返回结果 | 无需特殊硬件,灵活性高 | 通信开销大 |
| 共享内存 | 多个 CPU 共享同一内存 | 速度快 | 硬件专用,编程困难 |
| 消息传递 | 程序由独立进程组成,通过消息通信 | 灵活性高,可利用多处理器 | 编程复杂 |

总之,基于内容的图像搜索和高性能计算在视觉和图像处理领域的应用前景广阔,我们需要不断探索和创新,以充分发挥它们的潜力,为相关领域的发展做出更大的贡献。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值