简体   繁体   中英

To get the center mask from an image of masks using Python3 and opencv

Suppose I have these sets of images:

在此处输入图像描述

I want to take the center coordinate mask, ie, the circular one which has the cell:

在此处输入图像描述

To finally isolate the cell

在此处输入图像描述

How to achieve these using Python3 and opencv?

The Concept

  1. Detect the contours of the objects.

  2. Loop through the contours and find the one that encloses the center of the image.

  3. Using that contours, create a mask for the image and mask the image.

The Code

import cv2
import numpy as np

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_canny = cv2.Canny(img_gray, 0, 50)
    img_dilate = cv2.dilate(img_canny, None, iterations=1)
    img_erode = cv2.erode(img_dilate, None, iterations=1)
    return img_erode

def get_masked(img):
    h, w, _ = img.shape
    center = h // 2, w // 2
    contours, _ = cv2.findContours(process(img), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    for cnt in contours:
        if cv2.contourArea(cnt) > 100:
            if cv2.pointPolygonTest(cnt, center, False) > 0:
                mask = np.zeros((h, w), 'uint8')
                cv2.drawContours(mask, [cnt], -1, 255, -1) 
                return cv2.bitwise_and(img, img, mask=mask)

img = cv2.imread("blobs.png")
cv2.imshow("img_processed", get_masked(img))
cv2.waitKey(0)

The Output

在此处输入图像描述

The Explanation

  1. Import the necessary libraries:
import cv2
import numpy as np
  1. Define a function to process the image into a binary image that will allow optimal results when detecting the contours of the image:
def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_canny = cv2.Canny(img_gray, 0, 50)
    img_dilate = cv2.dilate(img_canny, None, iterations=1)
    img_erode = cv2.erode(img_dilate, None, iterations=1)
    return img_erode
  1. Define a function that will loop though the contours of the image (using the process function defined before to process the image) , and for every contour with contour area greater than 100 (to filter out noise) , check if the center of the image is inside the contour (done by checking if the result from calling the cv2.pointPolygonTest returns a positive number) , create the mask, mask the image and return the masked image:
def get_masked(img):
    h, w, _ = img.shape
    center = h // 2, w // 2
    contours, _ = cv2.findContours(process(img), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    for cnt in contours:
        if cv2.contourArea(cnt) > 100:
            if cv2.pointPolygonTest(cnt, center, False) > 0:
                mask = np.zeros((h, w), 'uint8')
                cv2.drawContours(mask, [cnt], -1, 255, -1) 
                return cv2.bitwise_and(img, img, mask=mask)
  1. Finally, read in your image, apply the get_masked function define before and show the image:
img = cv2.imread("blobs.png")
cv2.imshow("img_processed", get_masked(img))
cv2.waitKey(0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM