求助:如何用ImageMagick计算图像旋转后的边界框?
我明白你卡在这里的痛苦——找了半天没找到现成的函数,确实让人头疼。其实解决这个问题有两个思路:手动通过数学计算旋转后的坐标(最可靠,不受工具限制),或者用ImageMagick的命令行参数辅助验证。下面我一步步给你讲清楚:
一、先搞懂基础:ImageMagick的旋转规则
ImageMagick默认围绕图像中心旋转,旋转后会自动扩展画布以容纳整个图像。对于90°/180°/270°这种直角旋转,我们不需要复杂的三角函数,直接用坐标变换公式就能算出结果。
首先你需要获取原图像的宽高,用这条命令:
identify -format "%w %h" 你的图像文件名.jpg
假设输出是1000 800(即宽W=1000,高H=800),你的原边界框是[685,601,832,743](对应左上角(x1,y1)=(685,601),右下角(x2,y2)=(832,743))。
二、针对不同旋转角度的坐标计算
1. 90°顺时针旋转(对应convert input.jpg -rotate 90 output.jpg)
直角旋转的坐标变换公式(基于图像左上角为原点):
每个原坐标(x,y) → 新坐标(y, W - x - 1)
把你的四个边界点代入计算:
- (685,601) → (601, 1000-685-1) = (601, 314)
- (832,601) → (601, 1000-832-1) = (601, 167)
- (832,743) → (743, 1000-832-1) = (743, 167)
- (685,743) → (743, 1000-685-1) = (743, 314)
取所有点的最小/最大x、y值,得到新边界框:[601, 167, 743, 314]
2. 180°旋转(对应convert input.jpg -rotate 180 output.jpg)
坐标变换公式:
每个原坐标(x,y) → 新坐标(W - x - 1, H - y - 1)
代入计算后,四个点的新坐标分别是(314,198)、(167,198)、(167,56)、(314,56),最终边界框:[167, 56, 314, 198]
3. 270°顺时针旋转(即90°逆时针,对应convert input.jpg -rotate 270 output.jpg)
坐标变换公式:
每个原坐标(x,y) → 新坐标(H - y - 1, x)
代入计算后,四个点的新坐标分别是(198,685)、(198,832)、(56,832)、(56,685),最终边界框:[56, 685, 198, 832]
三、自动计算的脚本(一键搞定)
如果你不想手动算,可以写个简单的bash脚本,把参数填进去就能直接输出结果:
# 替换成你的图像文件名 IMAGE="input.jpg" # 替换成你的原边界框 x1=685 y1=601 x2=832 y2=743 # 获取图像宽高 read W H <<< $(identify -format "%w %h" "$IMAGE") # 计算90°旋转后的边界框 new_90_x_min=$y1 new_90_x_max=$y2 new_90_y_min=$((W - x2 - 1)) new_90_y_max=$((W - x1 - 1)) echo "90°顺时针旋转后的边界框: [$new_90_x_min, $new_90_y_min, $new_90_x_max, $new_90_y_max]" # 计算180°旋转后的边界框 new_180_x_min=$((W - x2 - 1)) new_180_x_max=$((W - x1 - 1)) new_180_y_min=$((H - y2 - 1)) new_180_y_max=$((H - y1 - 1)) echo "180°旋转后的边界框: [$new_180_x_min, $new_180_y_min, $new_180_x_max, $new_180_y_max]" # 计算270°旋转后的边界框 new_270_x_min=$((H - y2 - 1)) new_270_x_max=$((H - y1 - 1)) new_270_y_min=$x1 new_270_y_max=$x2 echo "270°顺时针旋转后的边界框: [$new_270_x_min, $new_270_y_min, $new_270_x_max, $new_270_y_max]"
四、验证方法
如果你想确认计算是否正确,可以用ImageMagick给原图像的边界框画个红色矩形,然后旋转图像,对比旋转后的矩形位置和你计算的边界框是否一致:
# 原图像画边界框 convert input.jpg -stroke red -strokewidth 2 -draw "rectangle 685,601 832,743" marked_input.jpg # 旋转后查看 convert marked_input.jpg -rotate 90 rotated_marked.jpg
打开rotated_marked.jpg,用图像查看工具的坐标拾取功能,就能验证你计算的边界框是否准确。
内容的提问来源于stack exchange,提问作者Ryan

