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

如何在视网膜图像掩码内随机裁剪50×50子图并验证有效性

视网膜图像掩码内随机裁剪50×50子图方案

问题背景

现有一张视网膜图像,目标是仅裁剪视网膜区域的子图。已完成以下前置步骤:

  1. 通过代码生成了视网膜区域的掩码
  2. 得到了仅保留视网膜的图像
  3. 尝试网格裁剪仅得到2个符合要求的子图,需求是随机裁剪5个完全位于掩码内的50×50子图,同时需要验证裁剪的子图是否在掩码内。

已实现的前置代码

生成掩码的代码

# 生成掩码
img = imread(folder + 'test.jpg')
blur = cv2.GaussianBlur(img, (3, 3), cv2.BORDER_DEFAULT)
edged = cv2.Canny(blur, 10, 250) 

# 二值化
thresh = cv2.threshold(edged, 128, 255, cv2.THRESH_BINARY)[1]

# 形态学闭运算
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# 获取外接轮廓的 bounding box 并填充轮廓
filled = np.zeros_like(thresh)
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
max_cnt = max(cnts, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(max_cnt)
cv2.drawContours(filled, [max_cnt], 0, 255, -1)

# 得到掩码
mask = filled.copy()

cv2_imshow(mask)

生成仅保留视网膜图像的代码

# 生成仅保留视网膜的图像
new_image = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
new_image[:,:,3] = mask[:,:]
imshow(new_image)

尝试的网格裁剪代码

def img_to_grid(img):
    print(img.shape[0], img.shape[1])
    ww = [[i, i+100-1] for i in range(0, img.shape[0],100)]
    print(ww)
    hh = [[i, i+100-1] for i in range(0, img.shape[1],100)]
    print(hh)
    grid = [img[j:jj,i:ii,:] for j,jj in ww for i,ii in hh]
    print((j, jj, i, ii) for j,jj in ww for i,ii in hh)
    return grid, len(ww), len(hh)

def plot_grid(grid,row,col,h=5,w=5):
    fig, ax = plt.subplots(nrows=row, ncols=col)
    [axi.set_axis_off() for axi in ax.ravel()]

    fig.set_figheight(h)
    fig.set_figwidth(w)
    c = 0
    for row in ax:
        for col in row:
            col.imshow(np.flip(grid[c],axis=-1))
            c+=1
    plt.show()

grid , r,c = img_to_grid(img)
plot_grid(grid,r,c)

解决方案:随机裁剪5个掩码内的50×50子图

实现思路

  1. 筛选所有可放置50×50子图的左上角坐标:坐标需满足子图不超出图像边界,且对应区域的掩码全部为255(完全在视网膜区域内)。
  2. 从有效坐标中随机挑选5个不同的位置,裁剪对应子图。
  3. 通过检查子图对应掩码区域是否全为255,验证子图是否符合要求。

完整代码

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

# 假设已存在img(原始视网膜图像)和mask(生成的掩码)变量
sub_size = 50  # 子图尺寸
num_subimgs = 5  # 需要的子图数量

# 1. 筛选所有有效的左上角坐标
valid_coords = []
img_h, img_w = img.shape[:2]

for y in range(img_h - sub_size + 1):
    for x in range(img_w - sub_size + 1):
        # 检查该区域内的掩码是否全为255
        mask_region = mask[y:y+sub_size, x:x+sub_size]
        if np.all(mask_region == 255):
            valid_coords.append((x, y))

# 2. 随机挑选指定数量的坐标(如果有效坐标不足则取全部)
selected_coords = random.sample(valid_coords, min(num_subimgs, len(valid_coords)))

# 3. 裁剪子图
subimgs = []
for x, y in selected_coords:
    subimg = img[y:y+sub_size, x:x+sub_size]
    subimgs.append(subimg)

# 4. 验证子图是否完全在掩码内
def validate_subimg(coord, mask, sub_size):
    x, y = coord
    mask_region = mask[y:y+sub_size, x:x+sub_size]
    return np.all(mask_region == 255)

# 输出验证结果
for idx, coord in enumerate(selected_coords):
    is_valid = validate_subimg(coord, mask, sub_size)
    print(f"第{idx+1}个子图是否有效:{is_valid}")

# 显示裁剪得到的子图
fig, axes = plt.subplots(1, len(subimgs), figsize=(15, 5))
for ax, subimg in zip(axes, subimgs):
    ax.imshow(cv2.cvtColor(subimg, cv2.COLOR_BGR2RGB))
    ax.axis('off')
plt.show()

代码说明

  • 有效坐标筛选:遍历所有可能的左上角位置,确保对应子图区域完全覆盖视网膜(掩码全为255)。
  • 随机采样:使用random.sample避免重复选取同一位置,同时处理有效坐标不足的情况。
  • 验证逻辑:通过检查掩码区域的像素值,确保子图没有超出视网膜范围。
  • 结果展示:用matplotlib批量展示裁剪后的子图,直观确认效果。

注意事项

  • 如果有效坐标数量不足5个,代码会自动取所有有效坐标,避免报错。
  • 可通过修改sub_size和num_subimgs参数,适配不同尺寸的子图和数量需求。

内容的提问来源于stack exchange,提问作者test tes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:43:12