6

私がやろうとしているのは、下の出席シートを処理して、誰がそこにいて誰がいないかを教えることです 出席シート

私は現在、すべての塗りつぶされたドットを見つける単一の黒いドットを使用して matchTemplate を使用しています(画像は最初にグレースケールに変換されます)。下の画像

一致したドット

次に、matchPattern 配列を操作して、それぞれの y 方向のほぼ中心を取得します。欠落している生徒に対応するギャップがある場所を確認できます。

私が抱えている問題は、このようなものが完璧な入力のために機能することを確認していますが、私の目標は、物理的な紙の写真を撮ってこれを処理できるようにすることですか? 注: 出席シートは私が作成したものなので、必要に応じて変更/修正できます。

以下に示す一致するサンプル画像を添付しました。 テストマッチ 私の現在の方法を使用することは、単なる災害です(以下を参照)。ここからどこに行けばよいかわかりません。しきい値を変更しようとしましたが、.65 を超えると画像が見つかりません。 不合格

import cv2
import numpy as np
from matplotlib import pyplot as plt

values = []
img_rgb = cv2.imread('/home/user/Downloads/input.png')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('/home/user/Downloads/input_2.png',0)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.6
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)
  values.append(pt[1]+h/2)

cv2.imwrite('output.png',img_rgb)
values.sort()
pivot = values[0]
count = 1
total = values[0]
cleaned = []

for x in range(1,len(values)):
  if(values[x] < pivot+20):
    pivot = values[x]
    count = count + 1
    total = total + values[x]
  else:
    print values[x]
    cleaned.append(int(total/count))
    pivot = values[x]
    count = 1
    total = values[x]

  if x == len(values)-1:
    cleaned.append(int(total/count))
print values
print cleaned

別のテスト画像を次に示します。 ここに画像の説明を入力

4

2 に答える 2

3

かなり単純化されたアプローチでドットを識別する方法の例を次に示します。

from skimage import io, color, filter, morphology, feature, img_as_float
from skimage.morphology import disk

image = io.imread('dots.jpg')

# Remove blue channel
bw = image.copy()
bw[..., 2] = 0

bw = 1 - img_as_float(color.rgb2gray(image))

big_mask = 150
small_mask = 10
min_dist = 50

bw = filter.rank.threshold_percentile(bw, disk(big_mask), p0=0.95)
bw = morphology.erosion(bw, disk(small_mask))

peaks = feature.corner_peaks(bw, min_distance=min_dist, indices=True)

import matplotlib.pyplot as plt
f, (ax0, ax1) = plt.subplots(1, 2)

ax0.imshow(image, cmap=plt.cm.gray)
ax1.imshow(bw, cmap=plt.cm.gray)
ax0.scatter(peaks[:, 1], peaks[:, 0], c='red', s=30)

plt.show()

検出されたドット

于 2013-09-18T21:03:14.930 に答える
3

通常、紙のフォームを分析する場合、余白とフォームの角にある特別なマークを使用して、重要な部分の縮尺と方向を識別します。たとえば、フォームの境界にいくつかの小さな黒い四角形を印刷し、それらを同じもので見つけて、cv2.matchTemplate関心領域を定義することができます。

ほとんどの場合、フォームは完全にはキャプチャされません (たとえば、拡大縮小、回転、遠近法で表示されるなど) ため、入力も正規化する必要があります。これには、透視変換またはアフィン変換を使用できます。

ヒストグラムの均等化ノイズ除去、およびその他の手法を使用して、画像を強調することもできます。

この時点で、「完全な入力」にはるかに近い、完全に正規化された画像が得られます。この入力でアルゴリズムを試すことができますが、もっと簡単な方法もあります (私の知る限り、このようなものは自動フォーム分析の実際のアプリケーションで使用されています)。

フォームのレイアウトは固定されており、そのコーナーは既にわかっています。それでは、フォームのそれぞれの興味深い部分の位置を計算してみませんか? たとえば、下の図では、フォームの角に 4 つの黒いランドマークを配置しました。破線領域の正規化された画像位置は、これらのランドマークに対して常に同じになります。

ここに画像の説明を入力

学生が講義に参加したかどうかを確認するには、破線の領域を固定された正方形の領域 (学生ごとに 1 つ) に分割し、この領域のピクセル値を合計して、この値を事前定義されたしきい値と比較するだけです。値が低い領域は白よりも黒くなる傾向があり (学生は講義に出席)、値が高い領域は白である可能性が高くなります (学生は欠席)。

要約すると、次のようになります。

  1. ランドマークを使用して、用紙の角を定義します。
  2. これらのランドマークに関してイメージを正規化します。
  3. 必要に応じて画像を強調します。
  4. 関心領域の位置を計算します。
  5. 領域が白または黒である可能性が高いかどうかを判断します。
于 2013-09-10T15:44:00.527 に答える