エッジ検出の問題が以前に投稿されたことは知っていますが(Javaの場合: 画像内のオブジェクトの数を数える 、言語に依存しません: 画像のエッジ検出 )、知りたいですPythonでそれを実装する方法。
いくつかの単純な形状(ノイズのあるバイナリ形状)で、エッジ検出とエッジ周辺の曲率計算を行っています。 OpenCVのラッパーがあることは知っていますが、どちらが優れているかわかりません:pyopencv、pycv、pycvf?
私は基本的にこの2つのタスクのみを実行しているため、ライブラリを使用するよりも自分で実装する方が速いかどうかもわかりません。
活発に開発されているscikit-image
には、セグメンテーションとエッジ検出のアルゴリズムがあります。
Pythonのscipyでエッジ検出を簡単に実現できます。
from scipy import ndimage
Edge_horizont = ndimage.sobel(greyscale, 0)
Edge_vertical = ndimage.sobel(greyscale, 1)
magnitude = np.hypot(Edge_horizont, Edge_vertical)
Scikit-imageには、エッジ検出の方法の 説明付きの特別ページ があります。
python scikit imageを使用して、輪郭を見つける非常に簡単な方法があります。これは、実際には次のような数行のコードです。
from skimage import measure
contours = measure.find_contours(gimg, 0.8)
これにより、等高線のベクトル表現が返されます。行ごとに別々の配列。また、近似値を計算することで、線のポイント数を減らすことも簡単です。ソースコードを使用したもう少し長い説明を次に示します。 Pythonによる画像のベクトル化
使用できるさまざまなエッジ検出器があります:Canny、Sobel、Laplacian、Scharr、Prewitt、Roberts。あなたはそれを行うことができます OpenCV :
import cv2
import numpy as np
img = cv2.imread('your_image.jpg', 0)
# Canny
edges_canny = cv2.Canny(img, 100, 100)
# Sobel
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)
edges_sobel = np.hypot(sobel_x, sobel_y)
edges_sobel *= 255.0 / np.max(edges_sobel)
# Laplacian
edges_laplacian = cv2.Laplacian(img, cv2.CV_64F)
# Scharr
schar_x = cv2.Scharr(img, cv2.CV_64F, 1, 0)
schar_y = cv2.Scharr(img, cv2.CV_64F, 0, 1)
edges_scharr = np.hypot(schar_x, schar_y)
edges_scharr *= 255.0 / np.max(edges_scharr)
または scikit-image :
import cv2
from skimage import feature, filters
img = cv2.imread('your_image.jpg', 0)
edges_canny = feature.canny(img) # Canny
edges_sobel = filters.sobel(img) # Sobel
edges_laplace = filters.laplace(img) # Laplacian
edges_scharr = filters.scharr(img) # Scharr
edges_prewitt = filters.prewitt(img) # Prewitt
edges_roberts = filters.roberts(img) # Roberts
Canny Edge検出器は、おそらく最も一般的に使用され、最も効果的な方法ですが、最も複雑でもあります。上記の方法の違いの詳細については、 このブログ投稿 を確認してください。