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

如何基于定位的像素裁剪图片以去除白色背景?

解决图片白色背景裁剪问题

你已经通过K-Means完成了背景与目标的分割,接下来只需要计算目标区域的最小外接矩形(Bounding Box),就能精准裁剪掉周围空白。

核心问题修正

你当前获取的「首尾非白色像素」无法代表目标的真实边界——np.where返回的像素是按遍历顺序排列的,首尾像素可能只是目标区域内的某两个点,并非最边缘的边界。正确的做法是提取所有非白色像素的行、列极值,得到目标的上下左右边界。

修改后的完整代码

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取并转换颜色空间
image = cv2.imread('1.jpg')
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# K-Means聚类分割
pixel_values = image_rgb.reshape((-1, 3)).astype(np.float32)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)
k = 2
_, labels, centers = cv2.kmeans(pixel_values, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

# 生成分割后的图像
centers = np.uint8(centers)
segmented_image = centers[labels.flatten()].reshape(image_rgb.shape)

# 计算目标区域的边界
# 获取所有非白色像素的坐标(注意:np.where返回的是(行索引, 列索引),对应(y, x))
non_white_coords = np.where((segmented_image != 255).all(axis=2))
min_y, max_y = non_white_coords[0].min(), non_white_coords[0].max()
min_x, max_x = non_white_coords[1].min(), non_white_coords[1].max()

# 裁剪原图(如果要裁剪分割后的图,替换成segmented_image即可)
cropped_image = image_rgb[min_y:max_y+1, min_x:max_x+1]

# 显示结果
plt.figure(figsize=(10, 5))
plt.subplot(121), plt.imshow(segmented_image), plt.title('分割后图像')
plt.subplot(122), plt.imshow(cropped_image), plt.title('裁剪后图像')
plt.show()

# 保存裁剪后的图像
cv2.imwrite('cropped_result.jpg', cv2.cvtColor(cropped_image, cv2.COLOR_RGB2BGR))

关键细节说明

  • 边界计算:(segmented_image != 255).all(axis=2)确保筛选的是RGB三个通道都不为255的像素,避免误判单通道非白的情况。
  • 切片范围:Python切片是左闭右开,所以max_y+1和max_x+1能保证包含最边缘的目标像素。
  • 灵活选择:可以选择裁剪原图或分割后的图像,根据需求替换cropped_image的赋值对象。

内容的提问来源于stack exchange,提问作者00zahra000

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:33:09