web-dev-qa-db-ja.com

OpenCVによる水平線の検出

「ドキュメント」からの画像から水平線と垂直線を見つけようとしています。ドキュメントは契約からスキャンされたページであるため、行は表または契約ブロックに表示されるもののように見えます。

私は仕事のためにOpenCVを試しています。 OpenCVのHough変換の実装は、この仕事には便利に思えましたが、垂直線と水平線をきれいに見つけることができるパラメーターの組み合わせは見つかりませんでした。エッジ検出ありとなしで試しました。運がありません。誰かが似たようなことをしたことがあるなら、私はその方法を知りたいと思っています。

ここに、OpenCVでのHoughPの実験前後の私の画像を見てください。私ができる最善の方法です http://dl.dropbox.com/u/3787481/Untitled%201.png

それで、水平線と垂直線(できれば破線も)を確実に見つけることができる別の種類の変換を使用できるかどうか疑問に思っています。

NuanceとABBYY OCRツールを使用して、水平線と垂直線を確実に抽出し、線の境界ボックスを返すことができるため、この問題が解決可能であることを知っています。

ありがとう!パトリック。

22
Patrick Collins

HoughLinesP 関数ドキュメントのコードサンプルを見ましたか?

アルゴリズムの出発点として使用できると思います。水平線と垂直線を選択するには、線の角度で他の線を除外するだけです。

UPDATE:

私が見るように、あなたは線ではなく、ページの水平方向と垂直方向の端を見つける必要があります。このタスクでは、いくつかの処理ステップを組み合わせて良好な結果を得る必要があります。

画像については、Canny Edgeの検出とHoughLinesPを組み合わせることで、良い結果を得ることができます。ここに私のコードがあります(私はpythonを使用しましたが、あなたはアイデアを見ると思います):

img = cv2.imread("C:/temp/1.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 80, 120)
lines = cv2.HoughLinesP(edges, 1, math.pi/2, 2, None, 30, 1);
for line in lines[0]:
    pt1 = (line[0],line[1])
    pt2 = (line[2],line[3])
    cv2.line(img, pt1, pt2, (0,0,255), 3)
cv2.imwrite("C:/temp/2.png", img)

結果は次のようになります。

30
Andrey Kamaev

「ラインセグメント」ではなく「ライン」だけが必要な場合は、コードの速度を上げたい場合に備えて、Canny、Hough、FindContoursなどの関数を使用しないでください。画像が回転せず、検索する対象が常に垂直または水平である場合、cv :: Sobel(垂直用と水平用)を使用して、列と行の累積配列を作成します。次に、たとえばしきい値を設定することにより、そのような累積またはプロファイルの最大値を検索できます。また、垂直または水平のエッジラインがある行または列がわかります。

9
marcos.nieto

RGBをグレースケールに変換しないでください。場合によっては、RGBの異なる色を同じグレースケール値にマージできるため、一部の輪郭が失われる可能性があります。各RGBチャンネルを個別に分析する必要があります。

6
fzec

この方法は、必ずしも線分ではなく「グローバル」な線を探すため、ハフ線の検出を終了することを検討してください。私は最近、「平行四辺形」を特定するアプリケーションを実装しました。これは、基本的に、視野角のために回転し、遠近感が短くなる可能性のある正方形です。同様のことを検討するかもしれません。私のパイプラインは:

  1. RGBからグレースケールに変換(cvCvtColor)
  2. スムーズ(cvSmooth)
  3. しきい値(cvThreshold)
  4. エッジの検出(cvCanny)
  5. 輪郭を見つける(cvFindContours)
  6. 線形特徴を持つ近似輪郭(cvApproxPoly)

アプリケーションでは、結果の輪郭リストが大きくなる可能性があります(平滑化の「攻撃性」とCanny Edge検出器の機能強化に依存します。このリストは、さまざまなパラメーターで整理できます。輪郭ファインダーから返されるポイントの数私の経験から、アプリケーションの「有効な」線には、明確に定義された領域と頂点の数のプロパティがあると思います。さらに、終点間の距離に基づいて輪郭をフィルタリングすることもできます。ポイント、エンドポイントを結ぶ線で定義される角度など。

CPUの「時間」に応じて、常にハフアルゴリズムと上記のようなアルゴリズムを組み合わせて、水平線と垂直線をしっかりと識別することができます。

5
Throwback1986