web-dev-qa-db-ja.com

Python画像内の「X」記号を検出するOpenCVライン検出

行内のX記号を検出する必要がある画像があります。

画像:

enter image description here

上の画像を見るとわかるように、線の中にX記号があります。シンボルのX座標とY座標を知りたい。この絵の中でこのシンボルを見つける方法はありますか、それとも小さいですか?

import cv2
import numpy as np


def calculateCenterSpot(results):
    startX, endX = results[0][0], results[0][2]
    startY, endY = results[0][1], results[0][3]
    centerSpotX = (endX - startX) / 2 + startX
    centerSpotY = (endY - startY) / 2 + startY
    return [centerSpotX, centerSpotY]

img = cv2.imread('crop_1.png')
res2 = img.copy()

cords = [[1278, 704, 1760, 1090]]
center = calculateCenterSpot(cords)
cv2.circle(img, (int(center[0]), int(center[1])), 1, (0,0,255), 30)
cv2.line(img, (int(center[0]), 0), (int(center[0]), img.shape[0]), (0,255,0), 10)
cv2.line(img, (0, int(center[1])), (img.shape[1], int(center[1])), (255,0,0), 10)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# You can either use threshold or Canny Edge for HoughLines().
_, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# Perform HoughLines tranform.
lines = cv2.HoughLines(thresh,0.5,np.pi/180,1000)
for line in lines:
    for rho,theta in line:
            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a*rho
            y0 = b*rho
            x1 = int(x0 + 5000*(-b))
            y1 = int(y0 + 5000*(a))
            x2 = int(x0 - 5000*(-b))
            y2 = int(y0 - 5000*(a))
            if x2 == int(center[0]):
                cv2.circle(img, (x2,y1), 100, (0,0,255), 30)

            if y2 == int(center[1]):
                print('hell2o')
                # cv2.line(res2,(x1,y1),(x2,y2),(0,0,255),2)

#Display the result.
cv2.imwrite('h_res1.png', img)
cv2.imwrite('h_res3.png', res2)

cv2.imwrite('image.png', img)

私はすでにHoughLinesでそれをやってみましたが、それは成功しませんでした。

5
mHvNG

複数のテンプレート画像の場合、forループを使用してさまざまなテンプレート画像の量を指定し、しきい値を使用して複数のテンプレートの一致を見つけることができます。

for i in range(templateAmount):
    template = cv2.imread('template{}.png'.format(i),0)
    w, h = template.shape[::-1]
    res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
    threshold = 0.8
    loc = np.where( res >= threshold)
    for pt in Zip(*loc[::-1]):
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
1
NielsNL4

このXシンボルを検出する必要がある複数の画像があり、このXシンボルが常に同じであり、同じ次元である場合、2次元 convolution 各画像について、畳み込みを行う kernel は、検出しようとしている分離されたX記号です。次に、この2次元コンボリューションの出力を最大強度のピクセルで確認します。その正規化座標(x/w,y/h)は、高い確率で入力画像のXシンボルの正規化座標に対応します。 2次元の畳み込みの数式は次のとおりです。

enter image description here opencvで 独自のカーネル を定義して(バックグラウンドに十字以外は何も残さないようにしてください)、それをイメージに適用できます。

0
Victor Deleau