def _detect_streaks(self):
# Find contours.
# Returned contours is the list of [row, columns] (i.e. [y, x])
contours = measure.find_contours(
self.image, self._std * self.contour_threshold, fully_connected='high'
)
# Quantify shapes of the contours and save them as 'edges'.
edge = EDGE(contours, min_points=self.min_points,
shape_cut=self.shape_cut, area_cut=self.area_cut,
radius_dev_cut=self.radius_dev_cut,
connectivity_angle=self.connectivity_angle)
edge.quantify()
self.raw_borders = edge.get_edges()
# Filter the edges, so only streak remains.
edge.filter_edges()
edge.connect_edges()
# Set streaks variable.
self.streaks = edge.get_edges()
python类find_contours()的实例源码
def getContours(img,kernel=(10,10)):
#Define kernel
kernel = np.ones(kernel, np.uint8)
#Open to erode small patches
thresh = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#Close little holes
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE,kernel, iterations=4)
#Find contours
#contours=skimsr.find_contours(thresh,0)
thresh=thresh.astype('uint8')
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
areas=[]
for c in contours:
areas.append(cv2.contourArea(c))
return contours,thresh,areas
def level_curves(fname, npoints = 200, smoothing = 10, level = 0.5) :
"Loads regularly sampled curves from a .PNG image."
# Find the contour lines
img = misc.imread(fname, flatten = True) # Grayscale
img = (img.T[:, ::-1]) / 255.
img = gaussian_filter(img, smoothing, mode='nearest')
lines = find_contours(img, level)
# Compute the sampling ratio for every contour line
lengths = np.array( [arclength(line) for line in lines] )
points_per_line = np.ceil( npoints * lengths / np.sum(lengths) )
# Interpolate accordingly
points = [] ; connec = [] ; index_offset = 0
for ppl, line in zip(points_per_line, lines) :
(p, c) = resample(line, ppl)
points.append(p)
connec.append(c + index_offset)
index_offset += len(p)
size = np.maximum(img.shape[0], img.shape[1])
points = np.vstack(points) / size
connec = np.vstack(connec)
return Curve(points, connec)
# Pyplot Output =================================================================================
def level_curves(fname, npoints = 200, smoothing = 10, level = 0.5) :
"Loads regularly sampled curves from a .PNG image."
# Find the contour lines
img = misc.imread(fname, flatten = True) # Grayscale
img = (img.T[:, ::-1]) / 255.
img = gaussian_filter(img, smoothing, mode='nearest')
lines = find_contours(img, level)
# Compute the sampling ratio for every contour line
lengths = np.array( [arclength(line) for line in lines] )
points_per_line = np.ceil( npoints * lengths / np.sum(lengths) )
# Interpolate accordingly
points = [] ; connec = [] ; index_offset = 0
for ppl, line in zip(points_per_line, lines) :
(p, c) = resample(line, ppl)
points.append(p)
connec.append(c + index_offset)
index_offset += len(p)
size = np.maximum(img.shape[0], img.shape[1])
points = np.vstack(points) / size
connec = np.vstack(connec)
return Curve(points, connec)
# Pyplot Output =================================================================================
def __call__(self, img_binary):
cs = measure.find_contours(img_binary, 0.5)
# Collect contours into RotatedBoxes
results = []
for c in cs:
# Now examine the bounding box. If it is too small, we ignore the contour
ll, ur = np.min(c, 0), np.max(c, 0)
wh = ur - ll
if wh[0]*wh[1] < self.min_area: continue
# Finally, construct the rotatedbox. If its aspect ratio is too small, we ignore it
rb = RotatedBox.from_points(c, self.box_type)
if rb.height == 0 or rb.width/rb.height < self.min_box_aspect: continue
# All tests fine, add to the list
results.append(rb)
# Next sort and leave only max_boxes largest boxes by area
results.sort(key = lambda x: -x.area)
return self._merge_boxes(results[0:self.max_boxes])
def extract_chars(pixels):
# use sci-kit image to find the contours of the image
contours = measure.find_contours(pixels, CONTOUR_LEVEL)
# calls an algorithm on the contours to remove unwanted overlapping contours like the holes in 6's, 8's, and 9's
contours = __remove_overlap_contours(contours)
# populate a dictionary with key of the left most x coordinate of the contour and value of the resized contour
resized_char_dict = dict()
for n, contour in enumerate(contours):
min, max = __get_min_max(contour)
resized_contour = transform.resize(pixels[int(min[0]):int(max[0]), int(min[1]):int(max[1])], (32, 32))
resized_char_dict[min[1]] = resized_contour
# sort the map by key (left most x coordinate of the contour)
sorted_dict = sorted(resized_char_dict.items(), key=operator.itemgetter(0))
# extract the contours from the sorted dictionary into a list
extracted_chars = np.asarray([i[1] for i in sorted_dict])
# normalize the contours by subtracting 0.5 to each pixel value
np.subtract(extracted_chars, 0.5, out=extracted_chars)
return extracted_chars
utils.py 文件源码
项目:kaggle-dstl-satellite-imagery-feature-detection
作者: u1234x1234
项目源码
文件源码
阅读 19
收藏 0
点赞 0
评论 0
def polygonize_sk(mask, level):
contours = measure.find_contours(mask, level)
polys = []
for contour in contours:
if contour.shape[0] < 4:
continue
poly = Polygon(shell=contour[:, [1, 0]])
polys.append(poly)
polys = MultiPolygon(polys)
return polys
def get_contours(img, contour_param=0.8):
# Find contours
contours = find_contours(img, contour_param)
# Sort with largest first.
contours.sort(key=attrgetter('size'), reverse=True)
return contours
def level_curves(fname, npoints, smoothing = 10, level = 0.5) :
# Find the contour lines
img = misc.imread(fname, flatten = True) # Grayscale
img = img.T[:, ::-1]
img = img / 255.
img = gaussian_filter(img, smoothing, mode='nearest')
lines = find_contours(img, level)
# Compute the sampling ratio
lengths = []
for line in lines :
lengths.append( arclength(line) )
lengths = array(lengths)
points_per_line = ceil( npoints * lengths / sum(lengths) )
# Interpolate accordingly
points = []
connec = []
index_offset = 0
for ppl, line in zip(points_per_line, lines) :
(p, c) = resample(line, ppl)
points.append(p)
connec.append(c + index_offset)
index_offset += len(p)
points = vstack(points)
connec = vstack(connec)
return Curve(points.ravel(), connec, 2) # Dimension 2 !
def main():
cmd_kwargs = parse_command_line()
image_path = cmd_kwargs.get("image", False)
name = os.path.splitext(os.path.basename(image_path))[0]
print name
if not image_path or not os.path.exists(image_path):
info_on_red("Image does not exist.")
exit()
image = misc.imread(image_path)
image = np.array(np.array(np.mean(image[:, :, :3], 2), dtype=int)/255, dtype=float)
contours = measure.find_contours(image, 0.5)
nodes = contours[0][::10, 1::-1]
nodes /= np.max(nodes)
nodes[:, 1] = -nodes[:, 1]
nodes_max = np.max(nodes, 0)
nodes_min = np.min(nodes, 0)
nodes[:, 1] -= nodes_min[1]
nodes[:, 0] -= nodes_min[0]
edges = round_trip_connect(0, len(nodes)-1)
savefile_prefix = os.path.join(MESHES_DIR, name)
np.savetxt(savefile_prefix + ".nodes", nodes)
np.savetxt(savefile_prefix + ".edges", edges, fmt='%i')
plot_edges(nodes, edges)
def mouse_down(self, ips, x, y, btn, **key):
lim = 5.0/key['canvas'].get_scale()
if btn==1 or btn==3:
if ips.roi!= None:
self.curobj = ips.roi.pick(x, y, lim)
if not self.curobj in (None,True):return
if ips.roi == None:
msk = floodfill(ips.img, x, y,
self.para['tor'], self.para['con']=='8-connect')
conts = find_contours(msk, 0, 'high')
ips.roi = shape2roi(polygonize(conts, btn==3))
elif hasattr(ips.roi, 'topolygon'):
shp = roi2shape(ips.roi.topolygon())
oper = ''
if key['shift']: oper = '+'
elif key['ctrl']: oper = '-'
elif self.curobj: return
else: ips.roi=None
msk = floodfill(ips.img, x, y,
self.para['tor'], self.para['con']=='8-connect')
conts = find_contours(msk, 0, 'high')
cur = polygonize(conts, btn==3)
if oper == '+':
ips.roi = shape2roi(shp.union(cur))
elif oper == '-':
ips.roi = shape2roi(shp.difference(cur))
else: ips.roi = shape2roi(cur)
else: ips.roi = None
ips.update = True
def mouse_down(self, ips, x, y, btn, **key):
lim = 5.0/key['canvas'].get_scale()
if btn==1 or btn==3:
if ips.roi!= None:
self.curobj = ips.roi.pick(x, y, lim)
ips.roi.info(ips, self.curobj)
if not self.curobj in (None,True):return
if ips.roi == None:
msk = floodfill(ips.img, x, y,
self.para['tor'], self.para['con']=='8-connect')
conts = find_contours(msk, 0, 'high')
ips.roi = shape2roi(polygonize(conts, btn==3))
elif hasattr(ips.roi, 'topolygon'):
shp = roi2shape(ips.roi.topolygon())
oper = ''
if key['shift']: oper = '+'
elif key['ctrl']: oper = '-'
elif self.curobj: return
else: ips.roi=None
msk = floodfill(ips.img, x, y,
self.para['tor'], self.para['con']=='8-connect')
conts = find_contours(msk, 0, 'high')
cur = polygonize(conts, btn==3)
if oper == '+':
ips.roi = shape2roi(shp.union(cur))
elif oper == '-':
ips.roi = shape2roi(shp.difference(cur))
else: ips.roi = shape2roi(cur)
else: ips.roi = None
ips.update = True
def show_fig2():
contours = measure.find_contours(phi, 0)
ax2 = fig2.add_subplot(111)
ax2.imshow(img, interpolation='nearest', cmap=plt.cm.gray)
for n, contour in enumerate(contours):
ax2.plot(contour[:, 1], contour[:, 0], linewidth=2)
def find_ellipse(image, mode='ellipse_aligned', min_length=24):
""" Find bright ellipse contours on a black background.
This routine thresholds the image (using the Otsu threshold), finds the
longest contour and fits an ellipse to this contour.
Parameters
----------
image : ndarray, 2d
mode : {'ellipse', 'ellipse_aligned', 'circle'}
'ellipse' or None finds an arbitrary ellipse (default)
'circle' finds a circle
'ellipse_aligned' finds an ellipse with its axes aligned along [x y] axes
min_length : number, optional
minimum length of the ellipse contour, in pixels. Default 24.
Returns
-------
yr, xr, yc, xc when dimension order was y, x (most common)
xr, yr, xc, yc when dimension order was x, y
"""
assert image.ndim == 2
# Threshold the image
thresh = threshold_otsu(image)
binary = image > thresh
# Find the contours of 0.5 value. For a thresholded ellipse contour, this
# likely finds 2 contours: the inner and the outer.
contours = find_contours(binary, 0.5, fully_connected='high')
if len(contours) == 0:
raise ValueError('No contours found')
# Eliminate short contours
contours = [c for c in contours if len(c) >= min_length]
# fit circles to the rest, keep the one with lowest residual deviation
result = [np.nan] * 4
residual = None
for c in contours:
try:
(xr, yr), (xc, yc), _ = fit_ellipse(c.T, mode=mode)
if np.any(np.isnan([xr, yr, xc, yc])):
continue
x, y = c.T
r = np.sum((((xc - x)/xr)**2 + ((yc - y)/yr)**2 - 1)**2)/len(c)
if residual is None or r < residual:
result = xr, yr, xc, yc
residual = r
except np.linalg.LinAlgError:
pass
return result