質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

opencvで検出した直線と描画した直線の交点を求めたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 196

tukim

score 5

前提・実現したいこと

opencvで検出した直線と描画した直線の交点を求めようと二つの直線のポインタを配列に入れて、それらを使って交点を計算し、表示したいのですが交点がない場合をうまく区別できていないため描画するときにエラーが起こってしまいます。交点のみをうまくとるにはどうしたらよいでしょうか。
お願いいたします。

該当のソースコード

      //認識した直線の描画   
          Mat bmpmat2 = new Mat();
          Utils.bitmapToMat(bmp, bmpmat2);
          double[] data2;
          Point pt12 = new Point();
          Point pt22 = new Point();
          int rows2 = dst.rows();
          double[][] lineData = new double[4][rows2];
           for (int i = 0; i < rows2; i++) {

                data2 = dst.get(i, 0);
                pt12.x = data2[0];
                pt12.y = data2[1];
                pt22.x = data2[2];
                pt22.y = data2[3];
                Imgproc.line(bmpmat2, pt12, pt22, new Scalar(255, 0, 0), 1);
                  lineData[0][i] = pt12.x;
                  lineData[1][i] = pt12.y;
                  lineData[2][i] = pt22.x;
                  lineData[3][i] = pt22.y;
                                }
                  //垂線の描画
                  int rows =bmpmat.rows();
                  int  cols = bmpmat.cols();
                  double[][] lineData2 = new double[4][rows2];
                  for(int i=1 ; i<8 ; i++) {

  Imgproc.line(bmpmat2, new Point(cols*i/8, 0), new Point(cols*i/8, rows), new Scalar(255, 0, 0), 1);
                           lineData[0][i-1] = cols*i/8;
                           lineData[1][i-1] = 0;
                           lineData[2][i-1] = cols*i/8;
                           lineData[3][i-1] = rows;
                                }

                 //交点の座標を求める
             Point[] xpoint = new Point[8*rows2];
             int pcon=0;
             double a1,a2,x1,x2,x3,x4,y1,y2,y3,y4,x,y;

             for(int i=0 ; i<rows2 ; i++) {
                x1=lineData[0][i];
                x2=lineData[2][i];
                y1=lineData[1][i];
                y2=lineData[3][i];

                    for(int j=0 ; j<8 ; j++){

                     x3=lineData2[0][j];
                     x4=lineData2[2][j];
                     y3=lineData2[1][j];
                     y4=lineData2[3][j];
                     a1 = (y2-y1)/(x2-x1);
                     a2 = (y4-y3)/(x4-x3);

                     x = (a1*x1-y1-a2*x3+y3)/(a1-a2);
                     y = (y2-y1)/(x2-x1)*(x-x1)+y1;


                     xpoint[pcon]=new Point(x,y);
           }
        }


                         Imgproc.circle(bmpmat2, xpoint[50],2,new Scalar(0,255,0),-1);

 

実行画面

![実行画面]
赤の横線と縦線の交点を求め五線譜の座標を求めようと思っています。
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • asahina1979

    2020/07/13 11:30

    一応
    歌詞の掲載利用にも JASRAC 等の関係団体の許諾が必要になります。
    著作権の失効している曲、もともとない曲等に差し替えましょう。

    キャンセル

  • tukim

    2020/07/13 14:30

    ご指摘ありがとうございます。
    そうですよね、失念していました。
    違うものに変えておきます。
    ありがとうございます。

    キャンセル

回答 2

checkベストアンサー

+1

この話の場合,「縦線」と「横線」は直交していると見なせそうな題材に思えますので,
「横線」群の検出結果(と,必要なら「縦線」群の検出結果も)を用いて,
それぞれの線の方向を示すベクトルを決めてしまうと楽なのではないでしょうか.

すなわち,この「楽譜の上での縦横」を2軸とする"楽譜座標系"を定めて,
諸々の画像ピクセル座標系の値をその"楽譜座標系"での値に読み替えて
"楽譜座標系"の上で処理を行うと楽なのでは?と.

「座標軸に平行な縦線と横線」の交点なら,考えやすいでしょう.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/13 06:30

    回答ありがとうございます。自分の理解力の問題で申し訳ないのですが縦線横線のうちから二本選んでそれをx、y軸にするということであっていますか?
    また、横線群は
    Imgproc.HoughLinesP(bin, linesMat, 1d, Math.PI / 360d, 200, 200d, 23);
    で取得したもので https://qiita.com/Anadreline/items/4cf6e88c743a65b7da2c こちらを参考にしており、つながっていない多くの線のつながりなのですがどのようにベクトルを決めればよいのでしょうか。linesMatがベクトルなのはわかるのですがノイズもありうまくやる方法が分かりません。

    キャンセル

  • 2020/07/13 10:10

    提示画像を見る感じ,それほどノイズがどうとか,向きにバラつきがあるとかいう雰囲気にも見えないですし,また,パースが付いているとかそういう絵でもなさそうです.
    赤色で示された横線群は相応に「五線に沿う,互いに平行な」形で得られているのだろうと思います.

    なので,横向き(五線に沿った)方向のベクトルというのは…
    例えば,検出した横線群の中で「長いやつ」上位数本を選んでそれらの向きの平均とかで出してしまっても良いように思います.

    縦方向のベクトルは…
    画像の縦線の像を使わずとも,簡単に,「上記で求めた横方向ベクトルに垂直なベクトル」としてもOKかもしれません.

    キャンセル

  • 2020/08/23 15:53 編集

    返信が遅れてしまい申し訳ございません。色々試していたところ別のエラーが出てしまい解決に手こずってしまいました。

    分かりやすく説明していただきありがとうございます。
    何とかうまくできそうです!ありがとうございます!

    キャンセル

0

(既存回答とは別の方向性の話なので,別回答として分けます)

横線群 と 縦線群 が検出されているとき…

元画像と同じサイズの画像バッファを2つ用意し,(どちらのバッファも全画素の画素値を0で初期化されているとして)

  • バッファ1には,横線群だけを(非0な画素値で)描画する
  • バッファ2には,縦線群だけを(↑と同じ画素値で)描画する

で,両者のANDを取れば,(精度は[pixel]レベルですが)交点だけが残ったマスクが作れます.

#線を描くときの幅は,少し太くしないと交点が取れない場合がある
#特定の線だけを描画して行えば,特定の線群の間の交点だけを見つけることも可能

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/23 15:54

    }新しい画像バッファをつくるために
    BufferedImage img = new BufferedImage(120, 40, BufferedImage.TYPE_3BYTE_BGR);
    をしたのですが BufferedImageがエラーになってしまいインポートもできませんでした。今は使えないのでしょうか?
    またMatの初期化を http://ya-yuki.hatenablog.com/entry/2015/06/04/190000 を参考に書こうと思ったのですがinit.data[y * init.cols + x] = 0; のjavaでのMat操作が分かりませんでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る