从对开页扫描裁剪页面

Crop page from facing-page scan

假设我只想从螺旋形笔记本的对开页扫描中裁剪左侧页面,如下例(来自 Paolini.net)。

有没有比简单地将图像宽度除以一半更可靠的方法?例如,更智能的算法会检测螺旋装订并将其作为右边界,甚至排除页面左侧的黑色区域。

如果使用 OpenCV 或 ImageMagick 有相对简单的方法,我很乐意学习。

在 ImageMagick 6 中使用 Unix 脚本的一种可能方法是执行以下操作:

Trim the image to remove most of the black on the sides

Scale the image down to 1 row, then scale up to 50 rows just for visualization

Threshold the scaled image so that you get the black region down the spine as the largest black region

Do connected components process to find the x coordinate of the largest black region

Crop the image according to the results from the connected components


输入:

convert img.jpg -fuzz 25% -trim +repage img_trim.png


convert img_trim.png -scale x1! -scale x50! -threshold 80% img_trim_x1.png


centx=$(convert img_trim_x1.png -type bilevel \
-define connected-components:mean-color=true \
-define connected-components:verbose=true \
-connected-components 4 null: | \
grep "gray(0)" | head -n 1 | awk '{print }' | cut -d, -f1)

convert img_trim.png -crop ${centx}x+0+0 img_result.jpg


来自连接组件的数据具有以下 header 和结构:

Objects (id: bounding-box centroid area mean-color):

所以 head -n 1 得到第一个黑色,即最大的灰色(0)区域(从大到小排序)。 awk 打印第 3 个条目,centroid,cut 得到 x 分量。


如果使用 ImageMagick 7,则将 convert 更改为 magick

如果要排除中间的绑定器,则使用连接组件列表中的边界框的x-offset:

convert img_trim.png -scale x1! -scale x50! -threshold 80% img_trim_x1.png
leftcenterx=$(convert img_trim_x1.png -type bilevel \
-define connected-components:mean-color=true \
-define connected-components:verbose=true \
-connected-components 4 null: | \
grep "gray(0)" | head -n 1 | awk '{print }' | cut -d+ -f2 | cut -d+ -f1)
convert img_trim.png -crop ${leftcenterx}x+0+0 img_result2.jpg


如果您只需要两个页面,那么我们可以找到白色区域,即灰色 (255) 并根据边界框的宽度和 x 偏移量裁剪它们。

convert img.jpg -fuzz 25% -trim +repage img_trim.png
convert img_trim.png -scale x1! -scale x50! -threshold 80% img_trim_x1.png
OLDIFS=$IFS
IFS=$'\n'
bboxArr=(`convert img_trim_x1.png -type bilevel \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=100 \
-define connected-components:verbose=true \
-connected-components 4 null: | \
grep "gray(255)" | awk '{print }'`)
IFS=$OLDIFS
num=${#bboxArr[*]}
for ((i=0; i<num; i++)); do
WW=`echo ${bboxArr[$i]} | cut -dx -f1`
Xoff=`echo ${bboxArr[$i]} | cut -d+ -f2`
convert img_trim.png -crop ${WW}x+${Xoff}+0 img_result3_$i.jpg
done