Image Processing - Eliminate Arc-like Smears
I am dealing with this kind of image (upper is post-processed) (lower is raw) So, first I converted the grayscale image into pure black and white binary image. I am interested in
Solution 1:
You can just detect circle of the right size with skimage's methods hough_circle
and hough_circle_peaks
and cut it out.
Here I adapted my previous answer to your other question to do this:
# skimage version 0.14.0import math
import numpy as np
import matplotlib.pyplot as plt
from skimage import color
from skimage.io import imread
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle
from skimage.util import img_as_ubyte
INPUT_IMAGE = 'dish1.png'# input image name
BEST_COUNT = 1# how many circles to detect (one dish)
MIN_RADIUS = 100# min radius of the Petri dish
MAX_RADIUS = 122# max radius of the Petri dish (in pixels)
LARGER_THRESH = 1.2# circle is considered significantly larger than another one if its radius is at least so much bigger
OVERLAP_THRESH = 0.1# circles are considered overlapping if this part of the smaller circle is overlappingdefcircle_overlap_percent(centers_distance, radius1, radius2):
'''
Calculating the percentage area overlap between circles
See Gist for comments:
https://gist.github.com/amakukha/5019bfd4694304d85c617df0ca123854
'''
R, r = max(radius1, radius2), min(radius1, radius2)
if centers_distance >= R + r:
return0.0elif R >= centers_distance + r:
return1.0
R2, r2 = R**2, r**2
x1 = (centers_distance**2 - R2 + r2 )/(2*centers_distance)
x2 = abs(centers_distance - x1)
y = math.sqrt(R2 - x1**2)
a1 = R2 * math.atan2(y, x1) - x1*y
if x1 <= centers_distance:
a2 = r2 * math.atan2(y, x2) - x2*y
else:
a2 = math.pi * r2 - a2
overlap_area = a1 + a2
return overlap_area / (math.pi * r2)
defcircle_overlap(c1, c2):
d = math.sqrt((c1[0]-c2[0])**2 + (c1[1]-c2[1])**2)
return circle_overlap_percent(d, c1[2], c2[2])
definner_circle(cs, c, thresh):
'''Is circle `c` is "inside" one of the `cs` circles?'''for dc in cs:
# if new circle is larger than existing -> it's not insideif c[2] > dc[2]*LARGER_THRESH: continue# if new circle is smaller than existing one...if circle_overlap(dc, c)>thresh:
# ...and there is a significant overlap -> it's inner circlereturnTruereturnFalse# Load picture and detect edges
image = imread(INPUT_IMAGE, 1)
image = img_as_ubyte(image)
edges = canny(image, sigma=3, low_threshold=10, high_threshold=50)
# Detect circles of specific radii
hough_radii = np.arange(MIN_RADIUS, MAX_RADIUS, 2)
hough_res = hough_circle(edges, hough_radii)
# Select the most prominent circles (in order from best to worst)
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii)
# Determine BEST_COUNT circles to be drawn
drawn_circles = []
for crcl inzip(cy, cx, radii):
# Do not draw circles if they are mostly inside better fitting onesifnot inner_circle(drawn_circles, crcl, OVERLAP_THRESH):
# A good circle found: exclude smaller circles it covers
i = 0while i<len(drawn_circles):
if circle_overlap(crcl, drawn_circles[i]) > OVERLAP_THRESH:
t = drawn_circles.pop(i)
else:
i += 1# Remember the new circle
drawn_circles.append(crcl)
# Stop after have found more circles than needediflen(drawn_circles)>BEST_COUNT:
break
drawn_circles = drawn_circles[:BEST_COUNT]
# Draw circle and cut it out
colors = [(250, 0, 0), (0, 250, 0), (0, 0, 250)]
fig, ax = plt.subplots(ncols=1, nrows=3, figsize=(10, 4))
color_image = color.gray2rgb(image)
black_image = np.zeros_like(image)
for center_y, center_x, radius in drawn_circles[:1]:
circy, circx = circle(center_y, center_x, radius, image.shape)
color = colors.pop(0)
color_image[circy, circx] = color
black_image[circy, circx] = image[circy, circx]
colors.append(color)
# Output
ax[0].imshow(image, cmap=plt.cm.gray) # original image
ax[1].imshow(color_image) # detected circle
ax[2].imshow(black_image, cmap=plt.cm.gray) # cutout
plt.show()
Output:
Again, as in my previous answer, most of the code here is doing "hierarchy" computation to find the biggest best fitting circle.
Post a Comment for "Image Processing - Eliminate Arc-like Smears"