You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Skimage技术问询:阈值化图像加黑边及旋转防裁切方法

Skimage图像处理问题解决方案

刚好处理过类似的图像需求,给你两个问题的具体实现方案,都是基于Skimage的原生函数,不用额外依赖:

问题1:为阈值化图像的顶部、底部及两侧添加黑色像素区域

这个需求其实很常见,Skimage专门提供了skimage.util.pad工具来做这件事,不用自己手动拼接数组。下面是完整的代码示例:

首先导入需要的库:

from skimage import io, filters, util
import numpy as np

然后读取图像并完成阈值化处理:

# 读取灰度图像(如果是彩色图,记得先转灰度:img = rgb2gray(img))
img = io.imread('your_image_path.png', as_gray=True)
# 用Otsu自动阈值化(你也可以换成手动阈值,比如thresh = 0.5)
thresh = filters.threshold_otsu(img)
binary_img = img > thresh

接下来就是添加黑边了,你可以自定义各边的像素宽度:

# 设置各边的填充宽度:格式为 ((顶部填充像素, 底部填充像素), (左侧填充像素, 右侧填充像素))
pad_width = ((80, 80), (40, 40))  # 示例:上下各加80像素,左右各加40像素
# 填充黑色(灰度图中0代表黑色,彩色图的话constant_values改成(0,0,0))
padded_binary_img = util.pad(binary_img, pad_width=pad_width, mode='constant', constant_values=0)

运行这段代码后,你就能得到四边带有指定宽度黑边的阈值化图像了。

问题2:旋转至主轴垂直+避免裁切的补边方法

这里的核心思路是先补边再旋转——因为旋转后被裁切的内容是无法恢复的,所以我们得先算出需要提前添加多少黑边,确保旋转后所有内容都能完整保留,同时四边的黑边等量。

步骤1:计算需要旋转的角度

首先我们要找到图像中前景区域的主轴方向,用skimage.measure.regionprops就能轻松获取:

from skimage import measure, transform

# 给二值图打标签(获取前景区域的属性)
labeled_img = measure.label(binary_img)
# 获取第一个前景区域的属性(如果图像只有一个目标区域,直接取[0]即可)
region_props = measure.regionprops(labeled_img)[0]
# 将主轴方向的弧度值转成角度
orientation_deg = np.rad2deg(region_props.orientation)
# 计算旋转角度:让主轴垂直,需要旋转的角度 = 90° - 主轴方向角度(注意符号可能需要微调,根据你的图像实际情况调整)
rotate_angle = 90 - orientation_deg

步骤2:计算需要添加的黑边宽度

根据旋转角度,我们可以用三角函数算出旋转后的图像尺寸,然后计算需要给原图添加的padding,确保原图居中放置:

H, W = binary_img.shape
theta_rad = np.deg2rad(rotate_angle)

# 计算旋转后的理论尺寸(确保能装下所有内容)
new_height = int(W * abs(np.sin(theta_rad)) + H * abs(np.cos(theta_rad)))
new_width = int(W * abs(np.cos(theta_rad)) + H * abs(np.sin(theta_rad)))

# 计算上下、左右需要添加的padding,保证原图居中
pad_top = (new_height - H) // 2
pad_bottom = new_height - H - pad_top
pad_left = (new_width - W) // 2
pad_right = new_width - W - pad_left

# 给原图添加黑边padding
padded_for_rotate = util.pad(binary_img, pad_width=((pad_top, pad_bottom), (pad_left, pad_right)), mode='constant', constant_values=0)

步骤3:执行旋转

现在旋转图像就不会裁切内容了,用transform.rotate完成旋转:

# 旋转图像,保持尺寸不变(因为我们已经提前适配了合适的尺寸)
rotated_img = transform.rotate(padded_for_rotate, rotate_angle, resize=False, preserve_range=True)
# 转回二值图(rotate会把图像转成float类型,所以需要重新阈值化)
rotated_binary_img = rotated_img > 0.5

这样得到的图像不仅主轴垂直、副轴水平,所有内容都完整保留,而且四边的黑边也是等量的。

内容的提问来源于stack exchange,提问作者Dante Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:12:26