2

I would like to get the mask from images with boundaries or boundaries from images of masks.

Here are two images:

Mask Image Boundary Image

I went through the followings, I did not understand the logic there: link1, link2, link3, link4

thanks, ilyas

Community
  • 1
  • 1
m.i.cosacak
  • 708
  • 7
  • 21
  • 1
    MASK->CONTOUR: use findContours with RETR_EXTERNAL. CONTOUR->MASK: use findContours with RETR_TREE, use internal contours only (use contourArea [see here](https://stackoverflow.com/a/42293993/5008845) ), then use drawContours. Try it out and come back if you have a specific programming problem and some code – Miki Apr 23 '20 at 10:51
  • @Miki I am not sure about the c++ code in the link you provided. Could you try with python3 and provide the code? I tried with watershed etc, but I could not. What I want to do: I would like to draw boundaries by hand for any the shapes (cell, nucleus, etc). Then, create a mask from these boundaries. Or instead of drawing boundaries, first I create mask by hand, then draw boundaries. – m.i.cosacak Apr 23 '20 at 17:01
  • I found this: [link](https://stackoverflow.com/questions/40441910/fast-method-to-retrieve-contour-mask-from-a-binary-mask-in-python). `im = cv.imread('mask.png')` `im = cv.cvtColor(im,cv.COLOR_BGR2GRAY)` `idx = cv2.findContours(im,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[1][0]` `out = np.zeros_like(im)` `out[idx[:,0],idx[:,1]] = 255` – m.i.cosacak Apr 23 '20 at 22:20
  • But still cannot create boundaries (second image), but if using gradient function, it gives some boundaries but not correct! – m.i.cosacak Apr 23 '20 at 22:23
  • Now this [link] (https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html) helped a lot: – m.i.cosacak Apr 23 '20 at 22:47

2 Answers2

0

from this link one can use the following;

to get boundary from mask:

im = cv2.imread('mask.png')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
tmp = np.zeros_like(im)
boundary = cv2.drawContours(tmp, contours, -1, (255,255,255), 1)
boundary[boundary > 0] = 255
plt.imsave("mask_boundary.png", boundary, cmap = "gray")

enter image description here

m.i.cosacak
  • 708
  • 7
  • 21
0

I still do not understand the logic, however, one can create boundary from mask and mask from boundary.

import os
import numpy as np
import cv2
from matplotlib import pyplot as plt

out = "mask_boundary.png"
inp = "mask.png"
im = cv2.imread(inp)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
tmp = np.zeros_like(im)
boundary = cv2.drawContours(tmp, contours, -1, (255,255,255), 1)
plt.imsave(out, boundary, cmap = "gray")


out = "boundary_mask.png"
inp = "mask_boundary.png"
im = cv2.imread(inp)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,0,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
tmp = np.zeros_like(im)
boundary = cv2.drawContours(tmp, contours, 0,(255,255,255), -1)
for i in range(1,len(contours)):
    boundary = cv2.drawContours(boundary, contours, i,(255,255,255), -1)

plt.imsave(out, boundary, cmap = "gray")



out = "boun_mask.png"
inp = "boundary.png"
im = cv2.imread(inp)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,0,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
tmp = np.zeros_like(im)
boundary = cv2.drawContours(tmp, contours, 0,(255,255,255), -1)
for i in range(1,len(contours)):
    boundary = cv2.drawContours(boundary, contours, i,(255,255,255), -1)

plt.imsave(out, boundary, cmap = "gray")

Note: using the mask image above, I first created boundary and then from this boundary I created mask. However, I could not convert all boundary above to mask, especially the one at the image edges/border. It looks like there must be boundary at the border as well! Any help on that will be appreciated!

convert the above mask to boundary:

mask2boundary

now convert the new boundary to mask:

newboundary2mask

now convert the above boundary to mask:

enter image description here

m.i.cosacak
  • 708
  • 7
  • 21