How to remove blob extension caused by morphology

I have an image that I blur and expand like this:

kernel = np.ones((5,5),np.float32)/1 eroded_img = cv2.erode(self.inpainted_adjusted_image, kernel, iterations=10) dilated_img = cv2.dilate(eroded_img, kernel, iterations=10) 

Here is the result of erosion and dilatation:

enter image description here

and then I take his threshold like this:

 self.thresh = cv2.threshold(dilated_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] 

But the threshold gives me an undesirable extension, which I noted in the image below (the area above the red line is the undesirable area):

enter image description here

How do I get rid of this unwanted region? Is there a better way to do what I do?

+8
python scipy image-processing opencv
source share
3 answers

Working with another type of threshold (an adaptive threshold that takes into account local proximity) will save you from your problem: an adaptive threshold result is what you are looking for.

enter image description here

[EDIT: I took the liberty of adding code to Hough circles. I admit that I played with the parameters for this single image to get a nice result, although I donโ€™t know what type of accuracy you need for this type of problem]

 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('image.png',0) thresh = cv2.threshold(img, 210, 255, cv2.ADAPTIVE_THRESH_MEAN_C)[1] canny = cv2.Canny(thresh,50,150) cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) circles = cv2.HoughCircles(canny,cv2.HOUGH_GRADIENT,1,20, param1=50,param2=23,minRadius=0,maxRadius=0) circles = np.uint16(np.around(circles)) for i in circles[0,:]: # draw the outer circle cv2.circle(cimg,(i[0],i[1]),i[2],(255,0,0),3) # draw the center of the circle cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) titles = ['Original Image', 'Adaptive Thresholding', "Canny", "Hough Circle"] images = [img, thresh, canny, cimg] for i in xrange(4): plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() 

Let us know if this is not enough.

+8
source share

From a binary image, it would be pretty easy to set up a circle using the How transform. As soon as you have the outer border of the circle, I propose to bleed the border and cut out the part that is outside the border.

Another approach is to set a threshold value. It looks like you could handle it. You may need morphological operations to get a clean line. Using a kernel disk will help maintain shape to a large extent.

+4
source share

Since your question was returned to its original version, I attached a solution using a fill fill that works on your images.

 import numpy as np import cv2 import sys import matplotlib.pyplot as plt img = cv2.imread('image.png', 0) h, w = img.shape[:2] mask = np.zeros((h+2, w+2), np.uint8) gray = cv2.blur(img,(5,5)) (minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(gray) print maxLoc fixed_range = True connectivity = 4 flooded = img.copy() mask[:] = 0 connectivity = 4 #8 flags = connectivity flags |= cv2.FLOODFILL_FIXED_RANGE cv2.floodFill(flooded, mask, maxLoc, (255, 255, 255), (60,)*3, (60,)*3, flags) thresh = cv2.threshold(flooded, 250, 255, cv2.THRESH_BINARY)[1] titles = ['Original Image', 'Blurred', "Floodfill", "Threshold"] images = [img, gray, flooded, thresh] for i in xrange(4): plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() 

enter image description here

0
source share

All Articles