web-dev-qa-db-ja.com

PythonでEdgeを検出して画像をトリミングする方法

私はPythonで画像処理をするのは初めてです。一般的な問題を解決しようとしています。人物のサインがある画像があります。エッジを見つけて切り取りたい署名を画像に合わせます。

入力画像

enter image description here

期待される出力

enter image description here

Canny Edge Detectionを試し、PIL、CV2を使用して既存のソリューション(記事と回答)のリストを使用して画像をトリミングしましたが、動作しないようです。実用的なソリューションを探しています。

私が試したいくつかの解決策:

  1. https://www.quora.com/How-can-I-detect-an-object-from-static-image-and-crop-it-from-the-image-using-openCV

  2. エッジ検出後にすべての側面から画像を切り取る

  3. 画像から最大の長方形を切り取る方法

その他多数...どれも機能しませんでしたが、非常にシンプルに見えます。既存のソリューションのいずれかを使用してエラーまたは予期しない出力が発生しました。

9
Kartik Rokde

必要なのはしきい値処理です。 OpenCVでは、 cv2.threshold() を使用してこれを実現できます。

私はそれを撃ちました。私のアプローチは次のとおりです。

  1. グレースケールに変換
  2. 画像をしきい値処理して、署名のみを取得します。
  3. しきい値処理された画像でそれらのピクセルが現れる場所を見つける
  4. 元のグレースケールでその領域の周りを切り抜きます
  5. 表示がそれほど厳密ではない作物から新しいしきい値の画像を作成します

ここに私の試みがありました、私はそれがかなりうまくいったと思います。

import cv2
import numpy as np

# load image
img = cv2.imread('image.jpg') 
rsz_img = cv2.resize(img, None, fx=0.25, fy=0.25) # resize since image is huge
gray = cv2.cvtColor(rsz_img, cv2.COLOR_BGR2GRAY) # convert to grayscale

# threshold to get just the signature
retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, type=cv2.THRESH_BINARY)

# find where the signature is and make a cropped region
points = np.argwhere(thresh_gray==0) # find where the black pixels are
points = np.fliplr(points) # store them in x,y coordinates instead of row,col indices
x, y, w, h = cv2.boundingRect(points) # create a rectangle around those points
x, y, w, h = x-10, y-10, w+20, h+20 # make the box a little bigger
crop = gray[y:y+h, x:x+w] # create a cropped region of the gray image

# get the thresholded crop
retval, thresh_crop = cv2.threshold(crop, thresh=200, maxval=255, type=cv2.THRESH_BINARY)

# display
cv2.imshow("Cropped and thresholded image", thresh_crop) 
cv2.waitKey(0)

結果は次のとおりです。 Cropped signature with thresholding

22
alkasm