【问题标题】:Is there a Linux tool to extract multiple cropped pieces from a single image?是否有 Linux 工具可以从单个图像中提取多个裁剪部分?
【发布时间】:2020-09-29 12:21:42
【问题描述】:

我看到了有关从多张图像中提取位置相似的裁剪区域的问题。这个问题正好相反,我还没有找到任何有用的工具。

我有多个区域的图像要提取到单独的图片文件中。提取区域的位置因图片、形状和大小以及区域数量而异,但通常为矩形。我已经尝试过 ImageMagick 和其他工具,但没有一个提供具有这种功能的交互模式,而且充其量都是痛苦的。

例如,想象一张书架的图片。大多数书是直立的,书的厚度和书的高度不同,少数书是倾斜的,可以支撑其他书。我正在寻找的是一种将每本书的书脊提取到单独图像的工具(具有名称模式(例如“spines-%%”),或者原件的后缀就可以了,例如“书.png 将给出“books-1.png”、“books-2.png”等。原始的“books.png”将被保留。重命名每个裁剪部分的能力会很好。)这个想法是绘制第一个裁剪框,当它的大小/形状正确时按“提取”按钮,然后再做一个裁剪框,再做一个,任意次数。

使用 ImageMagick、GIMP 等,目前必须: - 检查每张图像,并提前确定所需提取的数量 - 为每个所需的提取制作原始图像的副本,为每个图像稍微更改名称 - 编辑(使用magick,gimp等):放置一个裁剪框,裁剪到那个,保存每个裁剪的图像(ImageMagick和其他)或导出它(GIMP),用现在很多覆盖整个(例如书架图像副本)图像较小的裁剪框部分 - 关闭该文件并打开下一个文件(或在 ImageMagick 中使用 Next - 一个小而有用的东西) - 如果需要,删除原始的多图像文件,或将它们移动到安全的地方

然后,对数百个合成图像执行此操作。哎哟! multicrop 和 multicrop2 等脚本无法做到这一点,因为它们需要在书脊之间定义明确的间隙。 CLI 工具无法做到这一点,因为脊椎的位置及其大小在每张图片中都会发生变化。如前所述,GIMP、ImageMagick、gthumb 等可以一一完成,但它需要大量的中间步骤和文件,甚至可能出现小错误(比如错误计算书籍的数量)在架子上)只有一个数字需要重做。尝试根据书籍颜色、文本等进行自动化本身就是一项艰巨的任务,如果多重裁剪的下一个图像不同,比如从台球桌中提取每个台球的裁剪视图,该怎么办?基于书本的预处理器将无法工作(尽管 multicrop2 可能,如果球之间的距离足够远,可以将绿色毛毡用作分隔符)。

有什么想法吗?

【问题讨论】:

  • 这个社区很棒。我得到了两个很好的答案和几个有用的 cmets。我一直在尝试下面的 ImageMagick 脚本,并且在典型的书架上取得了不错的效果;该解决方案的最佳之处在于对正在做什么以及为什么出色的描述 - 即使您不必处理这样的图像,也请阅读它(我没有尝试过,但它可能适用于各种其他类型图片)。
  • 请考虑接受其中一个答案,如果它们是正确且有帮助的,则可能对这两个答案都投赞成票。这样一来,您和作者都将获得荣誉,未来的读者就会知道答案是有效的。单击计票旁边的空心对勾(复选标记)接受答案。谢谢。

标签: image imagemagick crop gimp


【解决方案1】:

nip2libvips GUI,让您只需单击一下即可拖动裁剪框并保存在每个位置。它是大多数 linux 的一部分,只需检查您的包管理器即可。它带有手册:按 F1 寻求帮助。

加载图像,双击打开视图窗口,按住 CTRL 并向下和向右拖动以创建一个区域并将其放置在其中一个对象上。返回主窗口,右键单击该区域并选择“另存为”。在文件对话框中,勾选“增加文件名”,输入类似“area0001.png”的名称,然后在文件保存对话框中按“确定”。

保存对话框将保持固定状态,文件名将递增。现在将区域重新定位到另一个对象上,然后再次按 OK。您可以继续这样做——每次保存只需单击一次。

您也可以进行旋转矩形选择:只需选择 Toolkits / Image / Transform / Rotate / Free 以制作旋转图像,然后在其上标记区域。您将能够每次拖动旋转滑块以使对象直立。

【讨论】:

  • 这是一个可用的解决方案,我会阅读手册(上面的说明似乎没有按相同的顺序工作)。它易于使用并且(幸运的是?)我只有大约 200 个需要提取的文件(这将导致大约 3000 个最终保存的区域)。因此,虽然对这么多人来说有点“罗嗦”,但它胜过我迄今为止找到的替代方案。
  • 应该说:“感谢您提供有关 nip2 的提示!”
  • 嗯,说明应该有效。请跟进说明什么对您有用,我会更新答案。很高兴它有用!
  • 我正在创建新区域 - 文件名增量在这些区域中不起作用(尽管多次尝试;-!)。我去了 git 站点,浏览了文档,但没有看到它是如何使用 multiple 区域的,就像我正在做的那样。然后我想起了你的评论。你说“重新定位”并且确实有效,而且非常好。所以秘诀是创建一个区域(CTRL-鼠标),它会得到一个像“A2”这样的名字。不要创造另一个!相反,将鼠标移到角上并调整框的大小/重新定位,然后再次按保存,然后使用鼠标再次移动 A2 的角,再次按保存,等等。
  • 我已经尽力让它更清楚了,谢谢!此外,在标签上拖动以移动区域而不调整大小,以防不明显。
【解决方案2】:

这是使用 ImageMagick 的一种方法。 ImageMagick 安装在 Linux 上,可用于 Windows 和 Mac OSX。这只是一个演示。它一次只能在一个书架上使用。

这个想法是修剪图像以去除大部分白色边框。然后获取 Canny 边缘并使用连接组件过滤掉较短的边缘。然后得到霍夫线并过滤到那些描绘书籍垂直边的线。在白色背景上将霍夫线绘制为黑色。然后再次使用连接组件来识别应该对应于书籍的较大白色区域的边界框,并丢弃较小的边界框。最后,遍历边界框以将图像裁剪到每本书中。

输入:

这部分代码修剪图像以去除多余的白色。然后提取 Canny 边缘。然后过滤边缘以使用连接组件删除小的边缘。然后,它计算霍夫线并使用 AWK 过滤那些线,以获得完全垂直或偏离垂直 1 度的线的线端点。端点存储在一个数组中。

lineArr=(`convert bookshelf.jpg \
-trim +repage +write bookshelf_trim.png \
-canny 0x1+20%+50% +write bookshelf_edges.png \
-define connected-components:exclude-header=true \
-define connected-components:area-threshold=300 \
-define connected-components:mean-color=true \
-connected-components 8 +write bookshelf_edges_filtered.png \
-stroke black -strokewidth 2 \
-hough-lines 9x9+70 +write bookshelf_lines.png MVG:- | \
awk '{ if( $6 == 0 || $6 == 1) {print $2","$3}}'`)

num=${#lineArr[*]}
echo $num
echo "${lineArr[*]}"


这部分代码设置了要在其上绘制线条的修剪图像和白色图像。

convert bookshelf_trim.png bookshelf_lines_filtered.png
convert bookshelf_trim.png -fill white -colorize 100 bookshelf_lines_filtered2.png


这部分代码循环遍历每一行并将其绘制在上面的两个图像上。

for((i=0; i<num; i++)); do
line="${lineArr[$i]}"
x1=`echo $line | cut -d, -f1`
y1=`echo $line | cut -d, -f2`
x2=`echo $line | cut -d, -f3`
y2=`echo $line | cut -d, -f4`
echo "$x1,$y1 $x2,$y2"
convert bookshelf_lines_filtered.png -fill black -stroke black -strokewidth 2 -draw "line $x1,$y1 $x2,$y2" -alpha off bookshelf_lines_filtered.png
convert bookshelf_lines_filtered2.png -fill black -stroke black -strokewidth 2 -draw "line $x1,$y1 $x2,$y2" -alpha off bookshelf_lines_filtered2.png
done


这部分代码使用白色图像上的连接组件,黑色线条绘制来提取白色部分的边界框。

bboxArr=(`convert bookshelf_lines_filtered2.png \
-type bilevel \
-define connected-components:exclude-header=true \
-define connected-components:area-threshold=0 \
-define connected-components:mean-color=true \
-define connected-components:verbose=true \
-connected-components 8 \
+write bookshelf_regions.png null: | grep "gray(255)" | awk '{print $2}'`)

num=${#bboxArr[*]}
echo "${bboxArr[*]}"


代码的最后部分循环遍历每个边界框并裁剪修剪后的输入图像以获取每本书。

for((i=0; i<num; i++)); do
bbox="${bboxArr[$i]}"
convert bookshelf_trim.png -crop $bbox +repage bookshelf_$i.jpg
done


精明的边缘:

过滤边缘:

霍夫线:

过滤的输入行:

白色背景上的过滤线:

19 本书中的一些:

【讨论】:

  • 哇!这是一个非常令人印象深刻的结果,关于如何组装它的说明非常宝贵。谢谢!
【解决方案3】:

ofn-extract-objects 是一个脚本,它可以一次性提取和导出图层上所有非连续不透明区域的文件,并根据需要将其导出到尽可能多的文件中。因此,如果您可以擦除不需要的部分并隔离每个书脊,它就可以完成其余的工作。

【讨论】:

  • 我一直试图让它工作,但似乎遇到了一个常见的 GIMP 问题 - python 版本。
  • 你的操作系统是什么?
  • @JD53 从您上面的回答看来,您似乎没有正确使用该插件...从命令行调用它不是主要的,而是在加载图像后在 Gimp 菜单中访问在编辑器中。
  • 操作系统是 Linux 20.04。在第二篇文章中,我试图从 GIMP (v 2.10) 内部运行,但由于 Python 版本/库,GIMP 不会加载插件。系统默认 Python 为 2.7.18。在 GIMP 启动期间,它会吐出插件无法导入模块的错误消息。尝试安装该模块(使用 pip)显示没有这样的库;用它搜索可安装的paclage(即使在ofn代码站点)也没有帮助。使用pyenv我切换到Python 3.7.6,尝试了同样的插件,未能包含模块并且出现“打印”语句()问题。
  • 哦,追查这个问题导致许多网站描述 GIMP 使用较旧的 Python 版本,以及版本敏感问题。
猜你喜欢
  • 2019-01-19
  • 1970-01-01
  • 2021-08-10
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
相关资源
最近更新 更多