opencv 检测裁剪图像是否在遮罩内

qpgpyjmq  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(226)

假设我有一个图像如下,我想裁剪一些子图像的视网膜只。

所以我采取的第一步是找到一个面具

# Find Mask
img = imread(folder + 'test.jpg')
blur = cv2.GaussianBlur(img, (3, 3), cv2.BORDER_DEFAULT)
edged = cv2.Canny(blur, 10, 250) 

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

# apply close morphology
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# get bounding box coordinates from the one filled external contour
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)

# crop filled contour image
mask = filled.copy()

cv2_imshow(mask)

下面是找到的掩码:

然后,我希望在遮罩的内部区域裁剪50 * 50的子图像
下面是我在网上找到的一些代码:

# This gives the retina only
new_image = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
new_image[:,:,3] = mask[:,:]
imshow(new_image)

下面是接近我想要的。有两个子图像是在遮罩。但我真正想要的是裁剪也许5个子图像随机在遮罩内。有没有办法,我可以做到这一点?或者我如何检查裁剪的图像是在遮罩内?

def img_to_grid(img):
    # ww = [[i.min(), i.max()] for i in np.array_split(range(img.shape[0]),row)]
    # hh = [[i.min(), i.max()] for i in np.array_split(range(img.shape[1]),col)]
    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)

ruarlubt

ruarlubt1#

如果你想提取不需要内接在圆中的真正随机的子图像,你可以只在非零遮罩边界框中获得一些坐标,检查它是否只包含一个坐标,如果是的话,保存它们。

sub_imgs = []

# Define minimum width and height for the cropped region
min_width = 32
min_height = 32

# Define the number of sub-images
sub_img_count = 5

while len(sub_imgs) < sub_img_count:
    x1 = np.random.randint(x, x + w)
    y1 = np.random.randint(y, y + h)

    maxw = w - (x1 - x)
    maxh = h - (y1 - y)

    # Skip if maximum possible sizes don't meet the requirement
    if not (maxw > min_width and maxh > min_height):
        continue

    width = np.random.randint(min_width, maxw)
    height = np.random.randint(min_height, maxh)

    # Extract the region only if it is within the mask
    if np.all(mask[y1: y1 + height, x1: x1 + width]):
        sub_img = img[y1: y1 + height, x1: x1 + width, :]
        sub_imgs.append(sub_img)

# Save the cropped regions
for i, sub_img in enumerate(sub_imgs):
    cv2.imwrite(f'{i + 1}.jpg', sub_img)

The cropped sub-image example

相关问题