当前位置: 首页 > news >正文

基于碎纸片的拼接复原算法及MATLAB实现

一、问题描述

破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。传统上,拼接复原工作需由人工完成,准确率较高,但效率很低。特别是当碎片数量巨大,人工拼接很难在短时间内完成任务。随着计算机技术的发展,人们试图开发碎纸片的自动拼接技术,以提高拼接复原效率。请讨论以下问题:

(1)对于给定的来自同一页印刷文字文件的碎纸机破碎纸片(仅纵切),建立碎纸片拼接复原模型和算法,并针对附件1、附件2给出的中、英文各一页文件的碎片数据进行拼接复原。如果复原过程需要人工干预,请写出干预方式及干预的时间节点。复原结果以图片形式及表格形式表达。

(2)对于碎纸机既纵切又横切的情形,请设计碎纸片拼接复原模型和算法,并针对附件3、附件4给出的中、英文各一页文件的碎片数据进行拼接复原。如果复原过程需要人工干预,请写出干预方式及干预的时间节点。复原结果表达要求同上。

(3)上述所给碎片数据均为单面打印文件,从现实情形出发,还可能有双面打印文件的碎纸片拼接复原问题需要解决。附件5给出的是一页英文印刷文字双面打印文件的碎片数据。请尝试设计相应的碎纸片拼接复原模型与算法,并就附件5的碎片数据给出拼接复原结果,结果表达要求同上。

二、拼接中存在的几个主要问题及解决方案

为了将碎片拼接成一幅完整的图片,需要解决的问题有以下几个方面:

  1. 如何判断两个碎片是否为相邻碎片?
  2. 如何控制两两拼接的循环执行直至拼接完成?
  3. 如何判断碎片是否为边界碎片?
  4. 如果碎片的某个边界刚好完全是空白,则将其判断为原图的边界还是相邻文字的空隙?

(5) 对于既有纵切又有横切的单面图片,如何拼接?

(6) 对于对于既有纵切又有横切的双面图片,如何拼接?

 针对上述问题,我们给出以下解决方案:

1.问题(1)的解决方案

为了减少计算量和便于处理,我们将原灰度图像转换成二值图像,此转换不影响文字类图片的质量,也不会影响拼接效果。

一般而言,相邻碎片的边缘都具有很强的相似性,我们通过判断碎片矩阵的对应边界列的相似程度来确定两矩阵存储的碎片是否为相邻碎片。为了确定两列向量的相似程度,我们利用其信噪比值psnr来衡量,psnr的值越大,说明两者的相似程度越高。在拼接过程中可能会存在这种现象:也许存在多幅待拼碎片与已拼图片的信噪比相同,为了从中选择一幅正确的碎片作为当前碎片的邻接碎片,我们可以人为介入从语义上进行判断。也有可能待拼碎片与已拼图片的信噪比大,但是并不是已拼图片的邻接图片,反而次小信噪比的碎片是邻接碎片。这是因为用信噪比去衡量邻接碎片边缘的相似度也存在概率性误差。对于以上两种情况,我们都需要在程序运行期间进行人工干预,即程序在拼接时需要与用户进行交互。思想如下:拼接函数f2()和f3()拼接时都会将当前已拼图片与所有待拼碎片的信噪比进行求解,并将所得信噪比序列存入一维数组中,然后通过排序函数paixu2()进行自小而大的排序,然后通过循环控制,从已排序数组的最后一个元素逐个向前尝试,每尝试一次都要与用户交互,用户根据图片语义判断拼接正确与否,如果正确,则给出‘YES’的输入,程序终止拼接;如果否,则给出‘NO’的输入,程序继续尝试剩余碎片,直到找到正确邻接碎片为止。实验证明,用该种方法对单纯纵切碎片的情况非常有效。

2.问题(2)的解决方案

在拼接的过程中,需要考虑如下几种情况:

① 如果选取的第一幅碎片刚好是原图的左侧边缘碎片,则只需要在其右侧进行拼接,直到完毕。

② 如果选取的第一幅碎片刚好是原图的右侧边缘碎片,则只需要在其左侧进行拼接,直到拼接完毕。

③ 如果选取的第一幅碎片刚好是原图的内部某一碎片,则既要进行右侧拼接,又要进行左侧拼接。

针对以上三种情况,我们编写了两个拼接函数,其中函数f2()实现两碎片的右侧拼接,函数f3()实现两碎片的左侧拼接。通过反复调用两函数实现整幅图的拼接。为了确定是选择函数f2()还是函数f3(),依照以下思路进行:

从所有碎片中首先选择一个碎片,判断其是否为右侧边缘碎片,如果否,则对其进行右侧拼接,则反复调用右拼函数f2(),直到右边缘,然后再调用左拼函数f3()进行左拼,直到左边缘;如果是,则直接调用左拼函数f3()进行左拼,直到左边缘。

3.问题(3)的解决方案

在拼接过程中需要判断是否已经拼接到原图的边缘,为了解决该问题,我们在设计函数f2()和f3()时,分别用它们的返回值的一个分量来标志是否调用成功。如果函数按psnr的逆序试了所有剩余碎片都未能找到合适的碎片,说明当前待拼图片是边界图片, 此时返回值分量flag的值为0,否则返回1。

4.问题(4)的解决方案

对于此种情况可以不做特殊处理,只需要调用拼接函数f2()或f3()进行拼接。如果刚好是边界,而剩余碎片个数为n,则人机交互n次才能判断该图片为边界碎片,而且人为根据语义做出判断时,也浪费了很多精力。为了避免该情况发生,我们将边界完全为空白的情况处理为边界。也可以在程序中直接把该处理对应的代码去掉,其余代码不需做任何改动,不足是增加了人工干预次数。当然,我们假定,在纵切时没有刚好完全切在空白处的情况,否则程序会给出错误的结果。程序实现时,具体处理方法如下:以f2()为例,首先测试碎片矩阵的大小,如果该碎片矩阵的右侧边界分量各元素值的和与碎片的行数之差小于一个阀值,我们就认为该碎片为边缘碎片,停止拼接。因为碎片已被处理为二值图像,在二值图像中,白色像素值为1,黑色像素值为0,而边缘通常是纯白的,在考虑有极少杂色的情况下,我们给了一个阀值。左侧边缘判定方法一样。

5.问题(5)的解决方案

对于既有纵切又有横切的图片,我们按如下思想进行拼接:利用纵切图片的拼接思想首先将碎片拼接成多个横条图片,然后将每个横条图片的矩阵进行转置,最后再次利用纵切拼接思想对横条图片进行拼接,拼接完毕后,将得到的最终矩阵进行转置,最终得到整幅图片。在实现过程中,存在以下细节需要处理:

整个过程中需要多次调用纵切拼接函数将碎片拼接成多个横条图片,所以,需要在每次成功拼接一个横条图片时将当前已参与拼接的碎片从剩余碎片中分离出来,这就需要用到分离函数ff()。

6.问题(6)的解决方案

   单面纵横切的算法和思想完全可以拓展到双面纵横切的情形,区别在于:在将所有碎片拼接成横条形图片后,再进行横条拼接时要产生两幅图像。为了能生成两幅图像,需要在单面纵横切拼接算法的基础上做以下处理:在拼接过程中要将参与拼接的图片与剩余图片分离出来;从一个图片开始拼起,如果遇到两个边界都已经找到了,说明第一个图片已经拼接完毕,然后再将剩余碎片拼接成另一面图像。因时间关系,我们未能编程实现。

相关文章:

基于碎纸片的拼接复原算法及MATLAB实现

一、问题描述 破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。传统上,拼接复原工作需由人工完成,准确率较高,但效率很低。特别是当碎片数量巨大,人工拼接很难在短时间内完成任务。随着计算…...

苍穹外卖 软件开发流程

软件开发的流程: 1.需求分析 完成需求规格说明书、产品原型。 需求规格说明书:一般而言是word文档描述当前项目的各个组成部分,如:系统定义、应用环境、功能规格、性能需求等,都会在文档中描述。 …...

mysqldump导出表结构和表数据和存储过程和函数

0、查看表结构信息 (1) 只查看表结构的注释信息 select table_name,table_comment from information_schema.tables where table_schema 表所在的库 and table_name 表名 ; mysql> select table_name,table_comment from information_schema.tables where tabl…...

常见的排序算法及分类对比

虽然在竞赛和编程语言中用到的排序算法主要是时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的高效算法,但作为算法学习,我们要从简单到复杂,认识常见的排序算法,并理解其算法思想。本文列出几乎所有的排序算法并进行分类对比。 排序算法总表 以下是一个对比表格…...

多窗口切换——selenium

获取窗口句柄(以Python Selenium为例) current_window_handle方法 用于获取当前窗口的句柄。句柄是一个标识符,用于唯一标识一个窗口。示例代码: from selenium import webdriverdriver webdriver.Chrome() driver.get("…...

LFD STM32编程规范20241111

1. 源文件和头文件放同一目录bsp文件夹顺序文件注释防重复设置#include#defineenum类型声明、定义 包括struct union typedef全局变量声明文件级变量声明全局或文件级函数声明函数实现。按函数声明顺序文件尾注释。/**************END FILE**************/引用头文件不用绝对路…...

Python学习------第八天

函数 函数的传入参数 掌握函数返回值的作用 掌握函数返回值的定义语法 函数的嵌套调用: 函数的局部变量和全局变量 局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。 money 5000000 n…...

【扩散——BFS】

题目 代码 #include <bits/stdc.h> using namespace std; const int t 2020, off 2020; #define x first #define y second typedef pair<int, int> PII; int dx[] {0, 0, 1, -1}, dy[] {-1, 1, 0, 0}; int dist[6080][6080]; // 0映射到2020&#xff0c;2020…...

C++ 编程基础(5)类与对象 | 5.5、多态

文章目录 一、多态1、概念2、多态实现方式3、动态绑定与静态绑定4、虚函数4.1、声明与定义4.2、虚函数的工作原理4.3、虚函数的优点与注意事项 5、不能声明为虚函数的函数6、纯虚函数7、抽象类8、总结 前言&#xff1a; 在C编程语言中&#xff0c;多态性&#xff08;Polymorphi…...

客户端发送http请求进行流量控制

客户端发送http请求进行流量控制 实现方式 1&#xff1a;使用 Semaphore (信号量) 控制流量 asyncio.Semaphore 是一种简单的流控方法&#xff0c;可以用来限制并发请求数量。 import asyncio import aiohttp import timeclass HttpClientWithSemaphore:def __init__(self, …...

STM32 低功耗模式详解

目录 一、什么是低功耗 二、低功耗的核心思想 三、STM32的3种低功耗模式 1、睡眠模式 (Sleep Mode) 2、停止模式 (Stop Mode) 3、 待机模式 (Standby Mode) 四、相关电源管理寄存器 1、PWR_CR (Power Control Register, 电源控制寄存器) 2、PWR_CSR (Power Control/St…...

我的第一个PyQt5程序

PyQt5的开发环境配置完成之后&#xff0c;开始编写第一个PyQt5的程序。 方法一&#xff1a;使用将.ui转换成.py文件的方法 import sys from FirstPyQt import Ui_MainWindow from PyQt5.QtWidgets import *#QtCore,QtGui,QtWidgets # from QtTest import Ui_MainWindow#导入Q…...

Unity调用Python

代码如下&#xff1a; if (useAI){/** 通过PaddlePaddle进行合成处理* */// 创建线程参数对象ThreadParameters parameters new ThreadParameters(){pythonPath "python", // 如果 Python 在系统路径中&#xff0c;可以直接使用 "python"pythonScript U…...

前端,location.reload刷新页面

location.reload() 是 JavaScript 中的一个方法&#xff0c;它用于重新加载当前页面。当你调用这个方法时&#xff0c;浏览器会重新加载当前页面的资源&#xff0c;就像用户点击了浏览器的刷新按钮一样。 基本用法 // 刷新当前页面 location.reload();带参数的用法 location…...

5G的发展演进

5G发展的驱动力 什么是5G [远程会议&#xff0c;2020年7月10日] 在来自世界各地的政府主管部门、电信制造及运营企业、研究机构约200多名会议代表和专家们的共同见证下&#xff0c;ITU-R WP 5D#35e远程会议宣布3GPP 5G技术&#xff08;含NB-IoT&#xff09;满足IMT-2020 5G技…...

数据库参数备份

MySQL #!/bin/bash # 获取当前日期和时间的时间戳 TIMESTAMP$(date "%Y%m%d-%H%M%S")# 0、创建目录 mkdir /tmp/parameter_$TIMESTAMP/# 1、获取所有命名空间 echo "1、获取所有命名空间" NAMESPACES$(kubectl get ns | grep qfusion- | grep -v qfusion-…...

PG数据库 数据库时间字段 开始时间和结束时间,判断和查询条件的开始和截止时间存在交集,SQL如何编写

PG 数据库时间字段 开始时间和结束时间&#xff0c;判断和查询条件的开始和截止时间存在交集&#xff0c;SQL如何编写&#xff1f; 在 PostgreSQL 中&#xff0c;如果你想要查询那些时间段&#xff08;由 开始时间 和 结束时间 定义&#xff09;与给定的时间段有交集的记录&am…...

k8s服务内容滚动升级以及常用命令介绍

查看K8S集群所有的节点信息 kubectl get nodes 删除K8S集群中某个特定节点 kubectl delete nodes/10.0.0.123 获取K8S集群命名空间 kubectl get namespace 获取K8S所有命名空间的那些部署 kubectl get deployment --all-namespaces 创建命名空间 web界面上看到的效果,但是…...

机器学习: LightGBM模型(优化版)——高效且强大的树形模型

LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一种基于梯度提升决策树&#xff08;GBDT&#xff09;的框架&#xff0c;由微软提出。它具有高效的训练速度、低内存占用、支持并行和GPU加速等特点&#xff0c;非常适合大规模数据的训练任务&#xff0c;尤…...

Wordpress常用配置,包括看板娘跨域等

一个Wordpress的博客已经搭建完成了&#xff0c;那么为了让它看起来更有人间烟火气一点&#xff0c;有一些常用的初始配置&#xff0c;这里整理一下。 修改页脚 页脚这里默认会显示Powered by Wordpress&#xff0c;还有一个原因是这里要加上备案信息。在主题里找到页脚&…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...