7

次の画像があります。

輪郭が欠けている画像

その輪郭を塗りつぶしたいと思います(つまり、この画像の線をギャップフィルしたいと思います)。

モルフォロジー クロージングを試みましたが、サイズの長方形のカーネル3x310反復で使用すると、境界全体が塗りつぶされません。21x21また、反復でカーネルを試しました1が、運もありませんでした。

アップデート:

以下を使用してOpenCV(Python)でこれを試しました:

cv2.morphologyEx(img, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (21,21)))

cv2.morphologyEx(img, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)), iterations=10)

およびscikit-image :

closing(img, square(21))

私の最終目標は、カバーされた領域を歪ませることなく、その画像全体の塗りつぶしバージョンを作成することです。

4

2 に答える 2

7

次のスニペットでは、反転画像の距離マップを計算しています。しきい値を設定して現在のオブジェクトの大きなアウトラインを取得し、それをスケルトン化して中心線を取得します。あなたの目的には、これで十分かもしれません。ただし、指定された線の太さと一致させるために、スケルトンを拡張して元のスケルトンに追加し、ギャップを埋めます。また、境界に接している残りの 1 つのオブジェクトも削除します。

隙間に気をつけて

from skimage import io, morphology, img_as_bool, segmentation
from scipy import ndimage as ndi
import matplotlib.pyplot as plt

image = img_as_bool(io.imread('/tmp/gaps.png'))
out = ndi.distance_transform_edt(~image)
out = out < 0.05 * out.max()
out = morphology.skeletonize(out)
out = morphology.binary_dilation(out, morphology.selem.disk(1))
out = segmentation.clear_border(out)
out = out | image

plt.imshow(out, cmap='gray')
plt.imsave('/tmp/gaps_filled.png', out, cmap='gray')
plt.show()
于 2015-01-22T01:02:30.410 に答える
2

2番目のステップで、これらの輪郭を輪郭検出に使用したいと仮定すると、より簡単な解決策があります。膨張を使用すると、白い領域が拡大され、ギャップが閉じます。

ここに画像の説明を入力

import cv2
import numpy as np

image = cv2.imread('lineswithgaps.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# apply dilation on src image
kernel = np.ones((3,3),np.uint8)
dilated_img = cv2.dilate(gray, kernel, iterations = 2)

cv2.imshow("filled gaps for contour detection", dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

欠点として、エッジが厚くなりますが、高精度を必要としない場合、これは問題にならない可能性があります...輪郭を今すぐ検出したい場合は、切り取った最初のコードに次の行を追加するだけです:

ここに画像の説明を入力

canvas = dilated_img.copy() # Canvas for plotting contours on
canvas = cv2.cvtColor(canvas, cv2.COLOR_GRAY2RGB) # create 3 channel image so we can plot contours in color

contours, hierarchy = cv2.findContours(dilated_img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)

# loop through the contours and check through their hierarchy, if they are inner contours
# more here: https://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html
for i,cont in enumerate(contours):
    # look for hierarchy[i][3]!=-1, ie hole boundaries
    if ( hierarchy[0][i][3] != -1 ):
        #cv2.drawContours(canvas, cont, -1, (0, 180, 0), 1) # plot inner contours GREEN
        cv2.fillPoly(canvas, pts =[cont], color=(0, 180, 0)) # fill inner contours GREEN
    else:
        cv2.drawContours(canvas, cont, -1, (255, 0, 0), 1) # plot all others BLUE, for completeness

cv2.imshow("Contours detected", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
于 2021-01-01T16:55:25.113 に答える