python - 除轮廓外如何去除骨架线?
问题描述
我想摆脱使用 python 的轮廓之外的骨架线。
并且,只想提取最大的轮廓。
(实际上,我尝试从分段蒙版中制作骨架线。并且,我得到了具有上图轮廓的主茎。在这些轮廓中,我只想提取面积最大的轮廓。)
我不知道该怎么做。如果您有任何想法,请帮助我。
提前致谢。
import os
import numpy as np
import cv2
from plantcv.plantcv import find_objects
from plantcv.plantcv import image_subtract
from plantcv.plantcv.morphology import segment_sort
from plantcv.plantcv.morphology import segment_skeleton
from plantcv.plantcv.morphology import _iterative_prune
from plantcv.plantcv import print_image
from plantcv.plantcv import plot_image
from plantcv.plantcv import params
from cv2.ximgproc import thinning
def find_large_contour(img, mask):
params.device += 1
mask1 = np.copy(mask)
ori_img = np.copy(img)
# If the reference image is grayscale convert it to color
if len(np.shape(ori_img)) == 2:
ori_img = cv2.cvtColor(ori_img, cv2.COLOR_GRAY2BGR)
objects, hierarchy = cv2.findContours(mask1, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:]
for i, cnt in enumerate(objects):
cv2.drawContours(ori_img, objects, i, (255, 102, 255), -1, lineType=8, hierarchy=hierarchy)
if params.debug == 'print':
print_image(ori_img, os.path.join(params.debug_outdir, str(params.device) + '_id_objects.png'))
elif params.debug == 'plot':
plot_image(ori_img)
return objects, hierarchy, ori_img
def prune(skel_img, size=2, mask=None):
# Store debug
debug = params.debug
params.debug = None
pruned_img = skel_img.copy()
# Check to see if the skeleton has multiple objects
skel_objects, _ = find_objects(skel_img, skel_img)
_, objects = segment_skeleton(skel_img)
kept_segments = []
removed_segments = []
if size > 0:
# If size>0 then check for segments that are smaller than size pixels long
# Sort through segments since we don't want to remove primary segments
secondary_objects, primary_objects = segment_sort(skel_img, objects)
# Keep segments longer than specified size
for i in range(0, len(secondary_objects)):
if len(secondary_objects[i]) > size:
kept_segments.append(secondary_objects[i])
else:
removed_segments.append(secondary_objects[i])
# Draw the contours that got removed
removed_barbs = np.zeros(skel_img.shape[:2], np.uint8)
cv2.drawContours(removed_barbs, removed_segments, -1, 255, 1,
lineType=8)
# Subtract all short segments from the skeleton image
pruned_img = image_subtract(pruned_img, removed_barbs)
pruned_contour_img = image_subtract(pruned_img, removed_barbs)
pruned_img = _iterative_prune(pruned_img, 1)
# Reset debug mode
params.debug = debug
# Make debugging image
if mask is None:
pruned_plot = np.zeros(skel_img.shape[:2], np.uint8)
else:
pruned_plot = mask.copy()
pruned_plot = cv2.cvtColor(pruned_plot, cv2.COLOR_GRAY2RGB)
pruned_obj, pruned_hierarchy, large_contour = find_large_contour(pruned_img, pruned_img)
cv2.drawContours(pruned_plot, removed_segments, -1, (0, 0, 255), params.line_thickness, lineType=8)
cv2.drawContours(pruned_plot, pruned_obj, -1, (150, 150, 150), params.line_thickness, lineType=8)
# Auto-increment device
params.device += 1
if params.debug == 'print':
print_image(pruned_img, os.path.join(params.debug_outdir, str(params.device) + '_pruned.png'))
print_image(pruned_plot, os.path.join(params.debug_outdir, str(params.device) + '_pruned_debug.png'))
elif params.debug == 'plot':
plot_image(pruned_img, cmap='gray')
plot_image(pruned_plot)
# Segment the pruned skeleton
segmented_img, segment_objects = segment_skeleton(pruned_img, mask)
return pruned_img, segmented_img, segment_objects, large_contour
vseg = cv2.imread("vseg.png", cv2.IMREAD_GRAYSCALE)
gray = thinning(vseg, thinningType=cv2.ximgproc.THINNING_GUOHALL)
pruned, seg_img, edge_objects, large_contour = prune(skel_img=gray, size=3, mask=vseg)
img_cont_gray = cv2.cvtColor(large_contour, cv2.COLOR_BGR2GRAY)
ret_cont, thresh_cont = cv2.threshold(img_cont_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imwrite("first_cont111.png", thresh_cont)
## then I want to extract the only contour with largest area
解决方案
使用形态作为第一步
ret,thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
rect=cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, rect)
然后找到最大面积的连通分量
max_component=np.full(opening.shape, 0, np.uint8)
nb_components,labels,stats,centroids= cv2.connectedComponentsWithStats(opening,8)
max_component[labels == np.argmax(stats[1:, -1])+1]=255
推荐阅读
- wordpress - 如何在 WAMP 服务器上运行的 Wordpress 中加载自定义模板文件?
- memory-leaks - 金丝雀泄漏 (scanf("%d", num)
- python - 如何将元素插入到python中的子列表中?
- java - @DateTimeFormat 仅适用于有限的模式。为什么会这样?
- google-apps-script - 禁用我从我拥有的模板创建的 Google 表格文件的自动订阅通知
- django - Django Oscar 仪表板链接无法访问
- r - 通过名称匹配两个不同大小列表的元素
- azure-api-management - Azure API 管理开发人员门户 - 自定义菜单和报告
- python - Tensorflow:如何获取张量的所有可能索引
- c# - 在 linq 查询中添加最大值和平均值