Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Thuật toán bạn trực tuyến là một phần sai, ít nhất là cho mục đích của bạn. Nếu chúng ta có hình ảnh sau, chúng ta muốn nó che dấu như vậy:

Hướng dẫn create circular mask python - tạo mặt nạ tròn python
Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Cách dễ nhất để tạo mặt nạ như thế này là cách thuật toán của bạn đi về nó, nhưng nó không được trình bày theo cách bạn muốn, cũng không cho bạn khả năng sửa đổi nó một cách dễ dàng. Những gì chúng ta cần làm là nhìn vào các tọa độ cho mỗi pixel trong hình ảnh và nhận được một giá trị đúng/sai cho việc pixel đó có nằm trong bán kính hay không. Ví dụ: đây là một hình ảnh được phóng to hiển thị bán kính vòng tròn và các pixel hoàn toàn nằm trong bán kính đó:

Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Bây giờ, để tìm ra những pixel nằm bên trong vòng tròn, chúng ta sẽ cần các chỉ số của từng pixel trong hình ảnh. Hàm np.ogrid() cung cấp hai vectơ, mỗi vectơ chứa các vị trí pixel (hoặc chỉ số): Có một vectơ cột cho các chỉ số cột và một vectơ hàng cho các chỉ số hàng:

>>> np.ogrid[:4,:5]
[array([[0],
       [1],
       [2],
       [3]]), array([[0, 1, 2, 3, 4]])]

Định dạng này rất hữu ích để phát sóng để nếu chúng ta sử dụng chúng trong một số chức năng nhất định, nó thực sự sẽ tạo ra một lưới của tất cả các chỉ số thay vì chỉ hai vectơ đó. Do đó, chúng ta có thể sử dụng np.ogrid() để tạo các chỉ số (hoặc tọa độ pixel) của hình ảnh, sau đó kiểm tra từng tọa độ pixel để xem nó ở bên trong hay bên ngoài vòng tròn. Để cho biết liệu nó có ở bên trong trung tâm hay không, chúng ta chỉ có thể tìm khoảng cách Euclide từ trung tâm đến mọi vị trí pixel, và sau đó nếu khoảng cách đó nhỏ hơn bán kính vòng tròn, chúng ta sẽ đánh dấu đó là bao gồm trong mặt nạ, và nếu Nó lớn hơn thế, chúng tôi sẽ loại trừ nó khỏi mặt nạ.

Bây giờ chúng tôi đã có mọi thứ chúng tôi cần để tạo ra một chức năng tạo ra mặt nạ này. Hơn nữa, chúng tôi sẽ thêm một chút chức năng tốt đẹp cho nó; Chúng tôi có thể gửi ở trung tâm và bán kính, hoặc tự động tính toán chúng.

def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask

Trong trường hợp này, dist_from_center là một ma trận cùng chiều cao và chiều rộng được chỉ định. Nó phát các vectơ chỉ mục cột và hàng vào một ma trận, trong đó giá trị tại mỗi vị trí là khoảng cách từ trung tâm. Nếu chúng ta trực quan hóa ma trận này như một hình ảnh (chia tỷ lệ nó thành phạm vi thích hợp), thì đó sẽ là một độ dốc tỏa ra từ trung tâm mà chúng ta chỉ định:

Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Vì vậy, khi chúng ta so sánh nó với

def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
0, nó giống hệt với ngưỡng hình ảnh độ dốc này.

Lưu ý rằng mặt nạ cuối cùng là một ma trận Booleans;

def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
1 Nếu vị trí đó nằm trong bán kính từ trung tâm được chỉ định,
def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
2 khác. Vì vậy, sau đó chúng tôi có thể sử dụng mặt nạ này như một chỉ số cho một vùng pixel mà chúng tôi quan tâm, hoặc chúng tôi có thể đối lập với boolean đó (
def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
3 trong
def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
4) để chọn các pixel bên ngoài khu vực đó. Vì vậy, sử dụng chức năng này để tô màu các pixel bên ngoài vòng tròn màu đen, giống như tôi đã làm ở đầu bài đăng này, cũng đơn giản như:

h, w = img.shape[:2]
mask = create_circular_mask(h, w)
masked_img = img.copy()
masked_img[~mask] = 0

Nhưng nếu chúng tôi muốn tạo một mặt nạ tròn ở một điểm khác so với trung tâm, chúng tôi có thể chỉ định nó (lưu ý rằng hàm đang mong đợi tọa độ trung tâm theo thứ tự

def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
5, chứ không phải chỉ mục
def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
6):

center = (int(w/4), int(h/4))
mask = create_circular_mask(h, w, center=center)

Mà, vì chúng tôi không đưa ra bán kính, sẽ cho chúng tôi bán kính lớn nhất để vòng tròn vẫn phù hợp với giới hạn hình ảnh:

Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Hoặc chúng ta có thể để nó tính toán trung tâm nhưng sử dụng bán kính được chỉ định:

radius = h/4
mask = create_circular_mask(h, w, radius=radius)

Cung cấp cho chúng tôi một vòng tròn tập trung với bán kính không mở rộng chính xác đến kích thước nhỏ nhất:

Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Và cuối cùng, chúng tôi có thể chỉ định bất kỳ bán kính và trung tâm nào chúng tôi muốn, bao gồm cả bán kính mở rộng bên ngoài giới hạn hình ảnh (và trung tâm thậm chí có thể nằm ngoài giới hạn hình ảnh!):

center = (int(w/4), int(h/4))
radius = h/2
mask = create_circular_mask(h, w, center=center, radius=radius)

Hướng dẫn create circular mask python - tạo mặt nạ tròn python

Những gì thuật toán bạn tìm thấy trực tuyến làm tương đương với việc đặt trung tâm thành

def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
7 và đặt bán kính thành
def create_circular_mask(h, w, center=None, radius=None):

    if center is None: # use the middle of the image
        center = (int(w/2), int(h/2))
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask
8:

mask = create_circular_mask(h, w, center=(0, 0), radius=h)

Hướng dẫn create circular mask python - tạo mặt nạ tròn python