I have an image that I'm eroding and dilating like so:
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's the result of the erosion and dilation:
and then I'm taking a threshold of it like so:
self.thresh = cv2.threshold(dilated_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
But the threshold gives me an unwanted extension that I've marked in the image below (The region above the red line is the unwanted region):
How do I get rid of this unwanted region? Is there a better way to do what I'm doing?
3 Answers
Answers 1
Working with a different type of threshold (adaptive threshold, which takes local brigthness into account) will already get rid of your problem: The adaptive threshold result is what you are looking for.
[EDIT: I have taken the liberty of adding some code on Hough circles. I admit that I have played with the parameters for this single image to get a nice looking result, though I do not know what type of accuracy you are needing for such a 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 yet sufficient.
Answers 2
From the binary Image it would be fairly easy to fit a circle using a Hough transform. Once you have the outer boundary of the circle i would suggest bleeding the boundary and cropping out the portion that outside the boundary.
Another approach is to adjust your threshold value. It looks like you could get away with that. You might need some morphological operations to get a clean edge. Using a disk kernel will help retain the shape to a good extent.
Answers 3
Since your question has been rolled back to its original version, I have attached a solution using flood fill which 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()
0 comments:
Post a Comment