使用Hugin拼接扫描图像

使用Hugin拼接扫描图像

目录
为什么?
所用软件
测试图片
脚本
4.1 第一次尝试:一次性拼接所有图片
4.2 完善:一次拼接两张图片
附录
参考文献

  1. 为什么?
    我的目的是将一些地图数字化。首先通过扫描将它们转换为栅格图像,然后再将栅格图像转换为可缩放的图形。整个两步过程如下所示:

扫描 -> 矢量化

地图 -> 栅格图像 -> 可缩放图形

在上述第一步中,由于一些地图的面积大于我的扫描仪表面(A4大小),因此我必须多次扫描地图,每次扫描不同的区域(有重叠部分),然后将这些较小的图像拼接成最终图像。Hugin在这第一步中起到了关键作用。

本文的目的是记录如何使用Hugin的命令行工具自动化拼接过程,而不深入讨论每个工具及其相关的命令行选项。

  1. 所用软件
    在网上搜索时,发现有很多软件可以进行拼接,但到目前为止,Hugin似乎是最佳选择,尤其是因为它是免费且开源的。唯一的缺点是Hugin的学习曲线有点陡峭,尽管它有一个GUI界面。

除了Hugin之外,其他软件包(也是免费、开源和跨平台的)也有所帮助:

ImageMagick:用于栅格图像处理的“瑞士军刀”。
GIMP:用于基于GUI的栅格图像处理,是Adobe PhotoShop的替代品。
Inkscape:用于可缩放图形编辑,基于SVG格式。这主要用于栅格图像的矢量化。
在基于Debian的发行版上安装这些软件包的命令如下:

bash
$ sudo apt install hugin
$ sudo apt install imagemagick
$ sudo apt install gimp
$ sudo apt install inkscape
(注意:原文中的“gimp-plugin-registry”可能是一个错误或不再需要的包名,因此在此处省略。通常,安装GIMP时会自动包含所需的插件。)

  1. 测试图片
    测试图片是一张1600x1000像素的数字照片,它被当作杂志中要扫描的原始图片:
    在这里插入图片描述

为了测试拼接功能,将原始图片分成4张较小的(1000x600像素)图片,并带有重叠部分,以代表4张扫描的图片,顺序如下:
在这里插入图片描述

请注意,为了模拟图像扫描过程中的实际情况,在拼接之前,“扫描”的图片(除第一张外)会按小角度旋转:

2.jpg:顺时针旋转1°;
3.jpg:逆时针旋转1°;
4.jpg:顺时针旋转2°;
因此,任务是使用Hugin拼接这4张“扫描”的图片。

  1. 脚本
    4.1 第一次尝试:一次性拼接所有图片

为了自动化拼接过程,使用了一个shell脚本来按特定顺序调用各种Hugin命令行工具。以下脚本是从Hugin关于拼接扫描图像的教程中下载的。

请注意,我对原始脚本进行了小幅修改,用hugin_executor替换了pto2mk和make,如此处所述。输入图像文件名也已更改以适应我们的情况。
在这里插入图片描述

然而,尝试运行此脚本并一次性拼接所有图像可能不会产生理想的结果,因为Hugin可能在查找图像之间的共同部分时感到困惑。
4.2 改进:一次拼接两张图片

可能在一步中提供多张图片会使Hugin在寻找图片间的共同部分时感到困惑…如果我们逐步拼接图片,每次只拼接两张图片会怎么样呢?

让我们创建一个新的脚本来测试这个想法:

bash
$ cat stitch-two.sh
#! /bin/bash

±----------+

| 1 | 2 |

±----±----+

| 3 | 4 |

±----------+

分三步拼接上面的4张图片:

1. 1.jpg + 2.jpg => top.jpg

2. 3.jpg + 4.jpg => bot.jpg

3. top.jpg + bot.jpg => final.jpg

该函数按以下顺序接受参数:

$1: 第一个文件名

$2: 第二个文件名

$3: 输出前缀(输出格式为JPG)

$4: JPG质量,1-100

$5: hfov(以度为单位)

function stitch_two(){
pto_gen --projection=0 --fov=$5 -o project.pto $1 $2
pto_lensstack -o project1.pto --new-lens i1 project.pto
cpfind -o project1.pto --multirow project1.pto
cpclean -o project2.pto project1.pto
linefind -o project3.pto project2.pto
pto_var -o setoptim.pto --opt r,d,e,!r0,!d0,!e0 project3.pto
autooptimiser -n -o autoptim.pto setoptim.pto
pano_modify --projection=0 --fov=AUTO --center --canvas=AUTO --crop=AUTO \
–ldr-file=JPG --ldr-compression=$4 -o autoptim2.pto autoptim.pto
hugin_executor -s -p $3 autoptim2.pto
}

开始拼接,Hugin!

stitch_two 1.jpg 2.jpg top 90 10
stitch_two 3.jpg 4.jpg bot 90 10
stitch_two top.jpg bot.jpg final 90 10
像以前一样准备一个新文件夹,并调用新脚本(./stitch-two.sh),我们得到了以下结果,看起来相当不错:
在这里插入图片描述

经过测试,这4张图片也可以以不同的顺序成功拼接(首先拼接左右部分,然后拼接整体)。实际上,多步方法不仅限于拼接2x2图片数组,理论上它适用于任何维度的图片数组,并且该数组可以首先逐行或逐列进行拼接。

使用多步拼接过程的另一个好处是,它还保留了中间步骤的拼接结果,如果最终结果有误,我们可以检查中间步骤以查看哪两张图片导致了问题,并尝试相应地调整输入图片。

基于之前的bash函数stitch_two(),以下是可用于拼接多于两张图片(在一行或一列中)的函数stitch_multi():

bash

$1: 输入文件名的数组

$2: 输出前缀

$3: JPG质量,1-100

$4: hfov(以度为单位)

function stitch_multi(){
tmp=tmp.jpg
inputs= 1 f i r s t = 1 first= 1first={inputs[0]}
inputs=( “${inputs[@]:1}” )

cp $first $tmp  

while (( ${#inputs[@]} )); do  
    next=( "${inputs[0]}" )  
    inputs=( "${inputs[@]:1}" )  

    echo "stitch_two $tmp $next $2 $3 $4"  
    stitch_two $tmp $next $2 $3 $4  
    cp $2.jpg $tmp  
done  

mv $tmp $2.jpg  

} #

示例:拼接一个2x3的图片数组

inputs=( 1.jpg 2.jpg 3.jpg )
stitch_multi $inputs left 90 10

inputs=( 4.jpg 5.jpg 6.jpg )
stitch_multi $inputs right 90 10

inputs=( left.jpg right.jpg )
stitch_multi $inputs final 90 10
5 附录

5.1 屏幕截图提示

要从网站(如google、baidu等)获取高分辨率数字地图,我们可以从浏览器中截取许多屏幕截图:

每个屏幕截图覆盖一个小区域;
相邻的屏幕截图具有足够的重叠;
将所有屏幕截图拼接成一张大图片。
显然,每个屏幕截图的尺寸越大越好。购买更大的显示器是一种选择,但大型显示器也有分辨率限制。我们能否获得尺寸大于显示器分辨率的屏幕截图呢?是的!本节将介绍如何实现这一点。请注意,专家可能有更复杂的方法从专业网站获取高分辨率地图。下面描述的简单方法仅适用于临时使用。

根据维基百科,响应式网页设计(RWD)是一种网页设计方法,旨在使网页在各种设备和窗口或屏幕尺寸上都能良好地呈现,从最小到最大显示尺寸,以确保可用性和满意度。为了满足这一要求,浏览器供应商提供了一些功能。例如,Firefox提供了响应式设计模式(RDM),其中网页开发人员可以定义要在其上呈现网页的设备的屏幕尺寸。定义的设备尺寸与用于网页开发的显示器的分辨率无关,而是用于模拟目标设备(如Pad或Mobile)。利用RDM功能的技巧概述如下:

进入浏览器的开发者模式;
打开RDM模式;
定义具有最大可能分辨率的自定义设备;
使用自定义设备访问所需的地图网站(在开发者模式下);
使用内置的屏幕截图工具或扩展程序捕获全页内容作为图像;
我遇到了Firefox(Windows版107.0 64位)的RDM模式的一些问题,如果设备尺寸大于3800x3750,截图就会失败且没有任何提示。然后我尝试了Google Chrome,效果更好。以下是在Windows 10上使用Google Chrome(107.0.5304.107 64位)捕获9999x9999截图的简要说明:

• 打开一个标签页并转到所需的网站(例如earthol.com);
• 从菜单–>更多工具–>DevTools,打开DevTools窗口:
∘ DevTools窗口可能会停靠在当前网页的一侧,或者它是未停靠的(在一个单独的窗口中);如果DevTools窗口停靠在当前网页内,请点击自定义–>停靠大小–>将窗口停靠到单独的窗口中,以将其取消停靠。这为当前网页提供了更大的可见区域。
∘ 在DevTools窗口旁边,注意到当前页面的顶部添加了一个工具栏。尺寸(Dimensions)项是我们想要放大的。从尺寸的下拉列表中选择编辑…,这将转到模拟设备设置页面。我们也可以通过点击DevTools窗口右侧菜单栏中的设置图标进入相同的设置页面(这将打开设置窗口;在左侧栏中点击设备以进入设置类别,右侧将显示模拟设备列表);
• 点击右侧栏顶部的添加自定义设备…按钮,将出现一个设备表单;
• 在设备表单中填写适当的信息,然后点击添加按钮添加刚刚定义的设备,最后关闭设置页面。以下是我定义的自定义设备:
∘ 名称:biggest
∘ 分辨率:9999x9999
∘ 设备像素比:1
∘ 设备类型:选择桌面
∘ 与用户代理相关的项:无需触碰
• 现在我们返回到当前网页(确保DevTools窗口仍然打开);选择biggest作为设备,尺寸将自动更改为定义的值(即9999x9999)。
• 导航到当前页面的所需位置(对于地图网站使用适当的缩放比例),等待一会儿,这是为了确保当前页面的所有内容(可见和不可见的)都已下载并呈现。
• 从当前页面顶部工具栏的最右侧菜单图标中点击捕获全尺寸截图。
• 如果一切顺利,将出现一个文件保存对话框,用于指定文件名以保存截图。
就是这样。很简单,不是吗?
是否有可能使截图尺寸大于9999x9999?我想是可能的,如果我们能够修改浏览器的源代码(Mozilla Firefox是完全免费和开源的)并重新编译它。如果我们不想弄脏源代码…Hugin来拯救。
以下是从earthol.com捕获圆明园卫星地图的示例:
• 为了获得最多的细节,我将地图放大到最大,因此区域的大小略大于9999x9999。
• 根据大致估算,整个区域可以被4张截图覆盖(即2x2截图)。
• 在每个earthol.com页面的顶部,都有一个工具按钮,可以将当前窗口以经度和纬度指定的位置为中心。
• 使用此工具,可以测量出圆明园的区域位于经度范围[116.28, 116.315]和纬度范围[39.995, 40.02]内,并有足够的边距;
• 现在很容易确定4张截图中每一张的中心位置(经度,纬度):
∘ 左上:(116.289, 40.014)
∘ 右上:(116.306, 40.014)
∘ 左下:(116.289, 40.001)
∘ 右下:(116.306, 40.001)

以下是按这种方式拍摄的4张截图的缩略图:
在这里插入图片描述

另请注意,从earthol.com上截取的屏幕截图在每侧都包含一些图标/文本/空白,我们需要在拼接之前将其裁剪掉,因为这些内容不是地图的一部分,更糟糕的是,它们会在拼接过程中误导Hugin。

以下是使用ImageMagick裁剪图像四边的示例脚本:

#!/bin/bash
#https://imagemagick.org/Usage/crop/#chop

每边要裁剪的像素
上=200
下=100
左=100
右=100

$1 输入文件
$2 输出文件
function chop_one_img(){
convert 1−chop0x上 top.jpg
convert top.jpg -gravity South -chop 0x下bot.jpgconvertbot.jpg−chop{左}x0 left.jpg
convert left.jpg -gravity East -chop 右x02
rm top.jpg bot.jpg left.jpg
}
for f in *.png; do
chop_one_img f{f%.png}.jpg
done

最终拼接的图像尺寸为16000x16000,中心部分是圆明园的区域(已突出显示)。 如果我们减小圆明园周围的边距大小,则图像尺寸可以减小到12000x10000。
在这里插入图片描述

注:这段翻译中存在一些问题,比如变量名称“上”、“下”、“左”、“右”在bash脚本中并不适用,因为bash脚本不支持非英文字符作为变量名。这里为了保留原文的直观性,仍然按照原文进行翻译。在实际应用中,应将这些变量名替换为英文,如"top", “bottom”, “left”, “right”。另外,“function chop_one_img(){” 这一行中的括号也存在错误,应该是 “function chop_one_img() {”。此外,“convert” 命令现在已被 “magick” 命令替代,因为在新版本的 ImageMagick 中,推荐使用 “magick” 命令。但是,为了保持与原文的一致性,这里仍然使用 “convert”。在实际应用中,应根据安装的 ImageMagick 版本选择正确的命令。

5.2 ImageMagick 小抄

• 检查资源策略:convert -list resource
• 更改资源策略:vi /etc/ImageMagick-6/policy.xml
• 获取图像信息:identify -verbose <输入>
• 去除exif元数据:convert <输入> -strip <输出>
• 从彩色转换为灰度:convert <输入> -colorspace Gray <输出>
• 更改jpg/png文件的质量:convert <输入> -quality <1到100的值> <输出>
• 下采样:convert <输入> -resize 50% <输出>
• 更改图像大小:convert <输入> -size 800x600 <输出>
• 旋转:convert <输入> -rotate <角度> <输出>; 可能使用GIMP GUI对此任务更直观。
• 转换颜色深度:convert <输入> -colors <颜色数> <输出>

6 参考文献

• Panorama 脚本简述
• Hugin的教程
• ImageMagick 在线文档

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值