python - OpenCV remove background -


i trying remove background of images, tweaking values , using methods morphologyex gives me aceptable result holes still remaining, in last case, holes doesn't fill iterating on every contour , drawing -1. can see threshold image good, making whole shape lines, don't know how continue...

update i've changed code better results i'm still getting holes... if fill theese holes, script perfect.

def get_contrasted(image, type="dark", level=3):     maxintensity = 255.0 # depends on dtype of image data     phi = 1     theta = 1      if type == "light":         newimage0 = (maxintensity/phi)*(image/(maxintensity/theta))**0.5         newimage0 = array(newimage0,dtype=uint8)         return newimage0     elif type == "dark":         newimage1 = (maxintensity/phi)*(image/(maxintensity/theta))**level         newimage1 = array(newimage1,dtype=uint8)          return newimage1  def sharp(image, level=3):     f = cv2.gaussianblur(image, (level,level), level)     f = cv2.addweighted(image, 1.5, f, -0.5, 0)     return f  original_image = imread('imagen.jpg') # 1 convert gray & normalize gray_img = cv2.cvtcolor(original_image, cv2.color_bgr2gray) gray_img = sharp(get_contrasted(gray_img)) gray_img = normalize(gray_img, none, 0, 255, norm_minmax, cv_8uc1) imshow("gray", gray_img)  # 2 find threshold gray_blur = cv2.gaussianblur(gray_img, (7, 7), 0) adapt_thresh_im = cv2.adaptivethreshold(gray_blur, 255, cv2.adaptive_thresh_gaussian_c, cv2.thresh_binary_inv, 11, 1) max_thresh, thresh_im = cv2.threshold(gray_img, 0, 255, cv2.thresh_binary_inv | cv2.thresh_otsu) thresh = cv2.bitwise_or(adapt_thresh_im, thresh_im)  # 3 dilate gray = cv2.canny(thresh, 88, 400, aperturesize=3) gray = cv2.dilate(gray, none, iterations=8) gray = cv2.erode(gray, none, iterations=8) imshow("trheshold", gray)  # 4 flood contours, _ = cv2.findcontours(gray, cv2.retr_tree, cv2.chain_approx_simple) contour_info = [] c in contours:     contour_info.append((         c,         cv2.iscontourconvex(c),         cv2.contourarea(c),     )) contour_info = sorted(contour_info, key=lambda c: c[2], reverse=true) max_contour = contour_info[0] holes = np.zeros(gray_img.shape, np.uint8) drawcontours(holes, max_contour, 0, 255, -1) imshow("holes", holes)  mask = cv2.gaussianblur(holes, (15, 15), 0) mask = np.dstack([mask] * 3)  # create 3-channel alpha mask  mask = mask.astype('float32') / 255.0  # use float matrices, img = original_image.astype('float32') / 255.0  # easy blending masked = (mask * img) + ((1 - mask) * (0,0,1))  # blend masked = (masked * 255).astype('uint8')  imshow("maked", masked) waitkey() 

0 original

enter image description here

1 threshold

enter image description here

2 holes

enter image description here

3 final image

enter image description here

iteratively perform morphological closing of holes image using kernel of increasing size. but, before doing suggest resize holes image (using nearest-neighbor interpolation) don't have use huge kernels. in following code (c++), resized holes image 25% of original dimensions.

to reduce effects on borders add constant border of zeros using copymakeborder before apply iterative closing. using 15 iterations here, make border around image larger 15.

so steps are

  • resize holes image
  • add 0 border
  • iteratively close image kernel of increasing size
  • remove border
  • now have small mask. resize mask original image size

the code in c++. i'm not familiar python.

    // read image , holes     mat im = imread("koal2.jpg");     mat holes = imread("guicx.jpg", 0);     // resize     mat small, bordered;     resize(holes, small, size(), .25, .25);     // add 0 border     int b = 20;     copymakeborder(small, bordered, b, b, b, b, border_constant, scalar(0));     // close     (int = 1; < 15; i++)     {         mat kernel = getstructuringelement(morph_ellipse, cv::size(2*i+1, 2*i+1));         morphologyex(bordered, bordered, morph_close, kernel, point(-1, -1), 1);     }     // remove border     mat mask = bordered(rect(b, b, small.cols, small.rows));     // resize mask     mat largemask;     resize(mask, largemask, size(im.cols, im.rows));     // foreground     mat fg;     im.copyto(fg, largemask); 

the output (not original scale) looks fine except takes background region @ bottom foreground.

enter image description here


Comments

Popular posts from this blog

OpenCV OpenCL: Convert Mat to Bitmap in JNI Layer for Android -

android - org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope -

python - How to remove the Xframe Options header in django? -