基于Linux系统的地理信息数字水印系统设计与实现

2023-12-01 03:43邹秀珍胡宇宸朱长青
软件导刊 2023年11期
关键词:栅格数据数字水印矢量

邹秀珍,胡宇宸,朱长青

(1.南京吉印信息科技有限公司,江苏 南京 210013;2.南京师范大学 虚拟地理环境教育部重点实验室,江苏 南京 210097)

0 引言

地理信息是国家基础设施建设与地理信息科学研究的基础数据,包含了大量的地理位置信息、空间分布特征和地理属性,被广泛应用于城市规划、环境保护、农业管理等领域[1-3]。然而,随着地理信息的快速增长和广泛流通,随之引起的复制、盗版等侵权问题屡禁不止[4-6],不仅无法保障数据提供者的权益,还阻碍了更多的数据共享和创新,无法推动地理信息领域的持续发展。因此,如何解决地理信息开放共享和版权保护之间的矛盾成为了地理信息领域面临的重要科学问题。

数字水印是一种将特定信息嵌入到数字数据中的技术,通过对数据进行隐蔽性修改,不影响数据的正常使用和感知,但可在需要时提取水印信息以实现版权保护[7-8]。数字水印技术的出现为地理信息的版权保护提供了新思路[9-11],在多年研究中,众多学者们针对不同格式的地理信息设计了多种数字水印算法[12-14]。现有地理信息数字水印算法可分为空间域和变换域算法两类。其中,空间域算法直接使用坐标、像素值、亮度值等作为水印信息载体[15];变换域算法将坐标、像素值等从空间域转换为变换域后,使用转换后的系数作为水印信息载体[16]。

基于设计的水印算法,学者们逐渐开发了地理信息版权保护系统。张海涛等[17]利用数字水印技术开发了名为GiSeal的软件,该软件以矢量数据的空间分布特征为基础,将水印信息嵌入搭配数据的冗余信息中。周芳妃[18]设计了基于离散傅里叶变换的自适应矢量地图数字水印算法,基于此开发了适用于矢量地图的数字水印系统。崔翰川等[19]基于ArcGIS Engine 开发了矢量地理数据数字水印系统,实现了对于矢量地理数据的版权保护。任娜等[20]开发了适用于4D 数据的数字水印系统,实现了对多种格式地理信息的版权保护。邓晓红等[21]介绍了数字水印在南京市规划和自然资源局中,实现数据安全保护中的应用。

虽然,上述开发地理信息数字水印系统现已在各领域得到了广泛应用,但只适用于Windows 操作系统,不适用基于Linux 内核开发的国产操作系统,因此无法完全满足科研、政府等机构在多个平台上实现地理信息版权保护的需求。

相较于Windows 操作系统,国产操作系统由本国技术团队开发,具有自主可控性[22]。其次,国产操作系统可根据国情、安全需求进行定制开发,以提供更强的安全保护和适应性。在实现GIS 软件国产化的背景下,虽然开发代码及内容逐渐实现了国产化,但开发平台的不安全性对GIS 软件造成了一定的威胁。因此,开发适用于国产操作系统的GIS 软件,可提供更好的数据安全、定制化功能、本地技术支持,跨部门合作优势更强,有助于满足国内用户需求,降低外部技术的依赖。地理信息数字水印系统作为保护地理信息版权的关键软件,确保其安全性是维护国家地理信息安全的关键所在。因此,开发基于Linux 操作系统的地理信息数字水印系统,真正实现GIS 软件的自主可控,是当前研究的关键问题。

为了解决上述问题,本文使用开源的地理空间数据抽象库(Geospatial Data Abstraction Library,GDAL),开发了适用于Linux 操作系统的地理信息数字水印系统,实现了地理信息在Linux 操作系统上的版权保护,为地理信息的安全共享和保护提供了新的思路。

1 系统设计

1.1 系统框架

地理信息数字水印系统建设的总体目标是在类型多样、格式繁多的数据中嵌入可代表版权信息的水印,从而实现版权保护。系统要求快速速写不同类型的地理信息,且具备跨平台的能力。因此,数字水印系统基于Linux 操作系统,应用开源且跨平台的GDAL 库,采用Java 语言、Swing 框架进行开发,系统架构如图1 所示。由此可见,本文系统以不同数据类型的数字水印算法为基础,依据C/S三层架构将其划分为表示层、业务逻辑层、数据访问层,不同层级完成不同的业务需求。

Fig.1 System framework图1 系统框架

(1)表示层。该层是用户与系统之间的接口,用户通过该层与系统进行交互操作,可输入待处理文件的路径、水印信息,并选择嵌入的数据格式和方法等,将输入数据传递给业务逻辑层进行处理。

(2)业务逻辑层。该层实现了地理信息数字水印系统的应用功能,具体为版权信息加密方法、水印嵌入算法、水印检测算法、用户权限管理、水印日志记录等,版权信息加密方法可对水印信息进行加密以提升水印的安全性,然后水印嵌入算法将加密后的水印信息嵌入待处理数据中。其中,水印检测算法可从数字水印数据中提取水印信息,实现水印的检测和提取;用户权限管理负责管理系统中用户的权限,确保数据的安全性和访问控制;水印日志操作用于记录水印嵌入和提取过程的操作日志,便于追溯和审计。Linux 操作系统的稳定性和安全性使业务逻辑层在处理版权信息加密、水印嵌入算法和水印检测算法等关键功能时更可靠。同时,Linux 操作系统的良好网络性能和高并发处理能力可支持大规模数据嵌入和提取任务,满足业务逻辑层的性能需求。

(3)数据访问层。该层负责对处理的数据进行读写操作,可从存储介质中读取待处理数据,并将处理后的数据写回存储介质。数据访问层与业务逻辑层进行交互,将待处理数据传递给业务逻辑层进行处理,并存储处理后的数据。Linux 操作系统的高度兼容性和可扩展性使系统能与各种存储介质进行交互,包括硬盘、闪存等。此外,Linux还提供了强大的文件系统支持,可高效读取和写入数据,确保数据的完整性和安全性。

1.2 系统功能

地理信息数字水印系统采用模块化的设计,由水印信息生成模块、水印信息嵌入模块、水印信息提取与检测模块、用户权限管理模块、水印日志记录模块组成,如图2所示。

Fig.2 System function module图2 系统功能模块

1.2.1 水印信息生成模块

水印信息生成是地理信息数字水印系统的核心功能之一,该模块负责生成用于嵌入到待处理数据中的水印信息。在处理界面,用户可输入需要嵌入的水印信息,系统将根据用户输入的信息生成水印数据,再对水印信息进行加密以提高水印的安全性,生成的水印信息将传递至水印信息嵌入模块进行处理。

1.2.2 水印信息嵌入模块

水印信息嵌入模块负责将生成的水印信息嵌入待处理数据中。在处理界面中,用户可选择嵌入的数据格式和方法等参数。通过水印信息嵌入模块,系统将根据用户选择的嵌入算法将水印信息嵌入待处理的数据中。水印嵌入过程通过访问Linux 文件系统与数据访问层进行交互,从存储介质中读取待处理数据,并将处理后的数据写回存储介质。

1.2.3 水印信息提取与检测模块

水印信息提取与检测模块负责从处理后的数据中提取和检测水印信息。在该模块中,用户可选择进行水印检测的文件路径,系统将采用相应的水印检测算法从待处理数据中提取嵌入的水印信息,并进行验证和检测,以判断数据是否被侵权。

1.2.4 用户权限管理模块

用户权限管理模块负责管理系统中用户的权限,确保数据的安全性和访问控制权限。该模块与Linux 的用户管理和权限系统进行集成,确保系统的安全性和可控性,以控制用户对系统各功能模块的访问权限。系统管理员可设置不同用户的权限级别,限制其访问和操作系统功能,从而确保只有经过授权的用户才能进行水印信息生成、嵌入、提取和检测等操作,以增强系统的安全性。

1.2.5 水印日志记录模块

水印日志记录模块用于记录水印嵌入和提取过程的操作并生成日志,以便追溯和审计。该模块在Linux 环境下运行,利用Linux 的特性和功能来实现日志记录的安全性和可靠性,并记录用户的操作行为、嵌入和提取文件信息、操作时间等关键信息以及用户身份、权限验证等与Linux 系统相关的额外信息。通过记录水印操作的日志可用于后续审计、追溯和分析,有助于保障水印操作安全,提供证据支持,当发生问题或纠纷时可进行调查和解决。

2 关键技术

2.1 水印信息生成

针对不同的嵌入水印信息,将其分为文本版权信息和图像版权信息分别进行处理。对于文本版权信息,首先使用快速反应(Quick Response,QR)码进行编码,使其转为具有版权信息的图像[23];然后将图像版权信息使用Logistic 混沌映射进行加密。Logistic 混沌映射模型是一种常见的水印信息加密算法[24-25],其特点是对初始值及参数极为敏感,初始值只要有微小的差异就能导致完全不同的结果。应用于图像置乱的Logistic 混沌系统的公式如式(1)所示。图3 为使用Logistic 混沌系统加密前后的版权图像信息。

Fig.3 Copyright image information before and after encryption图3 加密前后的版权图像信息

式中:Dn∈(0,1);0 ≤μ≤4;n=0,1,2,…

2.2 水印信息嵌入

2.2.1 矢量数据数字

本文采用的数字水印算法需同时适用于点、线、面数据,且具备较好的不可感知性和鲁棒性。基于该设计思想,本文使用基于空间域的数字水印算法为系统核心,算法具体步骤如下:

步骤1:将线和面数据转为点集合,以点要素为操作对象。

步骤2:计算点集合的最小凸包,并获得最小凸包的最远点对。

步骤3:分别计算点集合中其他点距离最远点对的两个点的最短距离,这两个点分别记为Pf(xf,yf)、Pl(xl,yl)。

步骤4:计算点集合内的其他点到点Pf、Pl构成直线的距离D,点(xt,yt)到直线距离的计算公式为:

步骤5:计算点集合内的其他点与点Pf构成的线段距离,并计算该距离与点Pf、Pl构成线段距离的比值r。

步骤6:取距离比值r,根据哈希函数将其量化为水印索引index。

步骤7:获取加密后的版权图像,并将其转为一维序列Bit,然后根据水印索引index获取该点需要嵌入的水印比特bit。

步骤8:使用量化索引调制(Quantization Index Modulation,QIM)技术[26-27]将待嵌入的水印比特bit嵌入到距离D的小数后第δ位q中,计算公式如下:

式中:q′为距离D小数后第δ位被嵌入后的数值;S为量化步长;在D中使用q′替换q即可得到新的距离D′。

步骤9:重复上述操作,对点Pf、Pl外的其他点依次嵌入水印信息。

2.2.2 栅格数据数字水印嵌入

本文采用的栅格数据水印算法使用基于密钥矩阵的栅格数据水印算法[28],该算法将水印信息嵌入栅格像元值的最高和次低位平面,通过生成密钥矩阵进行模板匹配,从而实现水印信息的嵌入和提取。算法具体步骤如下:

步骤1:读取待嵌入的栅格数据R,R的大小为M×N。

步骤2:读取原始栅格数据大小,将加密后的水印信息按照栅格数据的大小进行扩频处理,以得到新的水印信息。

步骤3:首先,遍历栅格数据的每个像元,将水印信息的对应位与当前像元的最高位进行比较。如果水印信息与最高位相同则记录该像元的位置,并生成一个密钥矩阵Key。然后,在密钥矩阵Key的相应位置处将值设置为1,从而实现了将水印信息嵌入到栅格数据的最高位中,并保持原始像元的最高位值不变。如果水印信息与最高位不相同,则在密钥矩阵Key的相应位置处将值设置为0,表示该像元未嵌入水印信息。然后,转至步骤4 进行水印嵌入操作,将产生的密钥矩阵按照二进制格式进行存储。

步骤4:采取基于特征修改的嵌入规则将水印信息嵌入栅格数据的次低位,计算公式如下:

式中:Il表示像素值次低位的值。

2.3 水印信息提取

2.3.1 矢量数据数字水印提取

矢量数据数字水印检测流程是水印嵌入的逆过程,具体步骤如下:

步骤1:重复水印嵌入的步骤1—步骤6,获取水印索引index′、距离D′′。

步骤2:对距离D′′再次采用QIM 技术,从其小数后δ位的数值q′′中提取嵌入的水印比特bit′。

式中:S为量化步长。

步骤3:为了增加水印的鲁棒性,在嵌入时同一水印比特会被多次嵌入到不同的点中。因此,根据水印索引index′和提取出的水印比特bit′,使用多数投票法完成水印信息组合。

步骤4:通常通过计算原始水印信息W与提取出的水印信息W′之间的相似度,来评价水印算法鲁棒性。本文采用归一化相关(Normalized Correlation,NC)值来表征相似度[29],NC值越大表示数据之间的相似度越高。

式中:O*P表示水印图像的大小;W(i,j)、W′(i,j)分别表示原始水印信息与提出水印信息在(i,j)位置的水印比特;XNOR表示异或非运算。

2.3.2 栅格数据数字水印提取

在对栅格数据进行水印检测与嵌入时,使用的基于密钥矩阵的栅格数据水印算法相互对应。本文使用了基于模板匹配的水印提取算法进行水印提取。具体步骤如下:

步骤1:读取待检测的栅格数据I′。

步骤2:读取密钥矩阵,如果对应位置处的密钥值为1则根据步骤3 进行水印提取,否则根据步骤4 进行水印提取。

步骤3:在含水印信息的栅格数据像元值的最高位二进制位中提取水印信息,提取规则为:如果该位置最高位为1,则对应的扩频水印位的值为1;否则,对应的扩频水印位的值为0。计算公式为:

步骤4:在含水印信息的栅格数据像元值的次低位二进制位提取水印信息,提取规则为:如果该位的二进制最高位为1,则对应的扩频水印位的值位1;否则,对应的扩频水印位的值为0。计算公式为:

步骤5:将得到的扩频水印进行Logistic 逆变换,得到解密后的扩频水印。

步骤6:将原始水印信息作为待匹配的模板,在提取的扩频水印信息中搜寻目标。如果栅格数据未经过任何攻击,可在扩频水印信息的第一个位置处获得最佳匹配结果;一旦栅格数据遭受攻击后,为了得到最佳匹配结果,此时扫描扩频水印并与原始水印进行匹配,以计算两者间的相关系数NC。

步骤7:计算所有的相关系数,以提取出具有最大相关系数的块,并将其作为提取的水印信息。

2.4 Linux系统下矢量数据读写

由于水印嵌入和检测需要对矢量数据的坐标及其他参数进行修改和读取,因此在Linux 系统中实现矢量数据读写是系统的关键技术之一。矢量数据数字水印的实现过程中,为了减少水印嵌入对数据精度的影响,需要通过原始数据的容差和分辨率来计算嵌入的位置。

目前,多采用ESRI FileGeoDatabase(FileGDB)存储矢量数据。不同于Windows 系统,在Linux 系统中GDAL 并不支持读取FileGDB 内矢量数据容差和分辨率。为了解决该问题,本文首先将ESRI 提供的File Geodatabase API 在Linux 系统中进行编译,从而实现GDAL 对FileGDB 的写入操作;然后将其与jfgdb 库(https://github.com/frett27/jfgdb)编译后生成的.so 文件用于系统开发软件的配置中,从而读取FileGDB 中矢量数据定义和容差。读取容差的具体操作如下:

首先,创建一个地理数据库对象,并打开一个地理数据库;然后,调用getDatasetDefinition()方法获取指定数据集的定义信息;接下来,对定义信息中的“<XYTolerance> … </XYTolerance>”及“<XYScale>" … </XYScale>”标签内容进行解析,分别获得容差和分辨率。

3 系统实现

3.1 主要功能

系统的主要功能由水印嵌入、水印检测、日志管理、权限管理部分组成,系统界面如图4所示。

Fig.4 System interface图4 系统界面

3.1.1 地理信息读写

本文使用GDAL 读写地理信息,提供了一组功能强大的工具和API,用于读取、写入和处理各种地理空间数据格式。GDAL 支持GeoTIFF、ArcGIS Grid 等栅格数据,Shapefile、GeoJSON 等矢量数据及其他常见的地理信息格式[30],相较于ArcGIS Engine 而言具有一些显著的优点。首先,GDAL 是一个开源库,免费提供给开发者使用,而ArcGIS Engine 是商业软件,需要购买许可证;其次,GDAL 具有跨平台性,可在多个操作系统上使用,包括Windows、Linux 和MacOS 等,开发者可在Linux 环境下开发和运行地理信息读写功能,无需进行系统平台的迁移和调整。

3.1.2 水印信息生成

ZXing 是谷歌开源的支持二维码、条形码等图形的生成类库,可实现对QR 码的生成和解码[31]。因此,本文使用ZXing 库将文本版权信息转为QR 码。首先,将文本版权信息编码为字符串的形式作为QR 码的内容;然后,设置大小、纠错级别、边距等QR 码参数;最后,使用ZXing 库提供的API,将QR 码内容和参数作为输入,生成包含版权信息的QR 码图像对象,生成的QR 码图像对象不做本地存储和加密操作。

在使用Logistic 混沌系统进行加密时,首先需要初始化逻辑映射的初始值,创建一个长度为图像像素数量的逻辑映射数组;然后,通过迭代生成逻辑映射数组,按行优先的顺序遍历图像的每个像素,获取像素的RGB 值;接下来,将逻辑映射数组中的当前值乘以255,将结果转换为整数;最后,将图像像素的RGB 值与逻辑映射数组的当前值进行异或运算,并用改值更新像素的RGB 值。重复上述操作直至遍历完所有像素。

3.1.3 水印信息嵌入

在实现地理信息的读写中,首先使用gdal.AllRegister()方法来初始化GDAL,确保它能正确加载支持的数据格式驱动程序;然后,使用gdal.Open()方法打开地理信息数据集。该方法首先将数据集路径作为参数,并返回一个gdal.Dataset 对象,表示打开的数据集;然后使用gdal.Get-DriverByName()方法获取适当的数据驱动程序;最后使用driver.Create()方法创建新的数据集,为存储嵌入后的数据作准备。

矢量和栅格数据读写操作的方法并不相同,需要进行区分。对于栅格数据,通过gdal.Dataset 对象可获取数据集的相关信息,例如数据集宽度(width)、高度(height)、波段数量(bandCount)等,然后使用gdal.Dataset 对象的GetRasterBand()方法获取波段对象,并使用ReadAsArray()方法读取栅格数据的像素值。在使用水印嵌入阶段,使用算法对像素值进行修改后,通过gdal.Dataset 对象的WriteArray()方法将处理后的栅格数据写入数据集。

对于矢量数据集,使用gdal.Dataset 对象的GetLayer()方法获取图层对象,并使用遍历等方法读取矢量数据的要素和属性信息。在水印嵌入阶段,使用Geometry 类的set-Point()方法对点坐标进行修改。在完成对数据集的读写操作后,使用gdal.Dataset 对象的delete()方法关闭数据集,释放资源,并使用gdal.GDALDestroyDriverManager()方法关闭GDAL 的使用。

对于水印信息是否有效嵌入,本文采用数据是否被改动来进行判断,即比较嵌入前后的坐标或像元值是否一致,若不一致则认为水印信息有效嵌入。图5、图6 分别展示了系统中矢量数据水印嵌入的参数选择及嵌入进度界面。

Fig.5 Watermark embedding parameter selection interface图5 水印嵌入参数选择界面

Fig.6 Watermark embedding progress interface图6 水印嵌入进度界面

3.1.4 水印信息检测

水印信息检测是水印信息嵌入步骤的逆过程,首先需要使用与水印信息嵌入部分相同的步骤打开读取的数据集。对于栅格数据集,首先使用gdal.Dataset 对象的GetRasterBand()方法获取波段对象,然后使用ReadAsArray()方法读取栅格数据的像素值,最后使用水印检测阶段的步骤实现提取水印。

对于矢量数据集,首先使用gdal.Dataset 对象的Get-Layer()方法获取图层对象,然后获取到图层对象的Geometry 类,最后通过Geometry.GetX()、Geometry.GetX()分别获取点的X、Y 坐标。基于读取的像元值和坐标值,首先采用QIM 技术从其中提取出嵌入的水印比特,然后获取水印索引,最后根据水印索引将水印比特组成完整的水印信息。

在水印信息检测部分,若提取出的水印信息能正常识别出版权所有,则认为水印信息检测有效。图7 为系统的水印检测结果界面。

Fig.7 Watermark detection result interface图7 水印检测结果界面

3.2 实验与分析

3.2.1 实验数据

为验证本文设计系统算法的不可感知性和鲁棒性,选取了3 种不同的矢量地理数据和栅格数据用于实验,相关信息如表1所示。

Table 1 Experimental data information表1 实验数据信息

3.2.2 不可感知性分析

不可感知性是指经过系统处理后的数据与原始的数据在视觉和精度上是否存在误差。本文通过计算水印嵌入前后数据坐标与像元值之间均方根误差(Root Mean Square Error,RMSE)来定量评价算法的不可感知性。

式中:n为顶点或像元数量;x、x′分别表示对应顶点的坐标或像元的像元值;RMSE 值越小,表示两个数据之间的误差越小,不可感知性越好。

表2 展示了不同数据不可感知性实验的结果。由结果可知,6 种数据的顶点坐标或像元值均发生了改变,但改变量非常小,仍属于可容忍的范围内。因此,本文系统具有良好的不可感知性。

3.2.3 鲁棒性分析

旋转、缩放、平移(Rotation、Scaling and Translation,RST)是矢量地理数据最常见的操作,也是水印算法面对的最常见的攻击之一。为了验证本文设计系统的鲁棒性,分别对矢量数据进行不同强度的RST 攻击,以计算攻击后水印信息与原始水印信息的NC值。

由表3 实验结果可知,RST 攻击后的NC 值均为1.00,这是由于矢量数据水印算法将水印嵌入由点要素最小凸包构建的几何特征中,在提取水印时不受RST 影响。

Table 3 Experimental results of RST attack表3 RST攻击实验结果

高斯随机噪声攻击是栅格数据常见攻击之一,设定高斯噪声攻击均值为0,方差从0.1 依次递增到0.5,栅格数据攻击后提出的水印信息与原始水印信息的NC 值如表4 所示。由此可知,3 种栅格数据在各种强度的攻击下NC 值均大于0.9,表明本文系统对高斯随机噪声攻击具有极强的鲁棒性。

Table 4 Experimental results of Gaussian random noise attack表4 高斯随机噪声攻击实验结果

综上,本文系统对矢量数据或栅格数据常见的攻击均具有较好的鲁棒性。

4 结语

本文基于GIS 软件国产化的背景及开发适用于Linux操作系统的地理信息数字水印系统的需求,设计并实现了基于Linux 系统的地理信息数字水印系统。该系统基于开源的GDAL 地理信息处理库开发而成,系统内部分别封装了处理矢量和栅格数据的数字水印算法,可满足不同类型地理信息版权保护的需求。

该系统还是满足了现阶段在Linux 操作系统上使用数字水印系统的迫切需求,可被科研单位、政府机构等在国产操作系统中进行地理数据的版权保护,具有极强的使用价值与现实意义。实验表明,该系统虽然具有优良的不可感知性,对常见的数据攻击具有较强的鲁棒性强,但对栅格数据数字水印算法的设计过于复杂,无形中增加了栅格数据的处理时间。未来,可采取多线程处理、优化算法设计等措施提升栅格数据的处理效率。

此外,水印嵌入操作仍不可避免地修改了数据,后续可将无损水印和区块链技术相结合,并将其应用于地理信息数据水印系统中。

猜你喜欢
栅格数据数字水印矢量
基于网屏编码的数字水印技术
基于GDAL的标准图幅生成及数据批量裁剪方法*1
基于矢量最优估计的稳健测向方法
基于ArcGISEngine的南水北调工程基础栅格数据管理
基于数字水印的人脸与声纹融合识别算法
基于矩阵分解和混沌置乱的数字水印算法
色料减色混合色矢量计算
基于ArcGIS Engine的栅格数据转换矢量数据