2017-05-10 12 views
-2

画像内の同様のオブジェクトを検出しようとしています。コードの目的は、金を検出してそれをクリックすることです。 enter image description here画像内の類似するオブジェクトを検出する

ピクセル単位でスキャンしようとしましたが効率的ではなく、結果が満足できませんでした。 ゲームがWindowsモードで実行されていて、ロボットのようなクラスが正常に動作していると付け加えます。また、金は毎回異なる場所にあるかもしれません。

+0

各ステップごとに5ピクセルのようにスキップすることができるサイズに応じて。もしあなたがボットを書こうとするならば、Javaは最良の解決策ではないかもしれません。 – XtremeBaumer

+1

広すぎます。あなたの質問は、次のようなものです。そして、事は:その本について全書籍が書かれています。 – GhostCat

+1

これはOpenCV用のタスクです。ここで述べるようにjavaで使用できます:http://stackoverflow.com/questions/29182521/opencv-with-javacv-or-only-opencv-to-use-java-apiバイナリイメージを作成したり、スポットを検出したり、大きすぎるもの(つまりあなたのロボット)を棄却してゴールデンスポットを残してください – pandaadb

答えて

1

は非常に簡単な例として、私はあなたのイメージを使用してこれを書いた:

public class OpenCVTest { 

    public static void main(String[] args) { 
     OpenCV.loadLibrary(); 

     Mat m = Highgui.imread("/home/artur/Pictures/test.png", Highgui.CV_LOAD_IMAGE_GRAYSCALE); 
     LoadImage(m); 
     Mat res = Mat.zeros(m.size(), m.type()); 
     Imgproc.adaptiveThreshold(m, res, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 15, 20); 
     LoadImage(res); 
     Mat cannyRes = Mat.zeros(m.size(), m.type()); 
     Imgproc.Canny(res, cannyRes, 55, 5.2); 
     LoadImage(cannyRes); 

     Imgproc.dilate(cannyRes, cannyRes, new Mat(), new Point(-1, -1), 2); 
     Imgproc.erode(cannyRes, cannyRes, new Mat(), new Point(-1, -1), 2); 

     LoadImage(cannyRes); 

     List<MatOfPoint> contours = new ArrayList<>(); 
     Imgproc.findContours(cannyRes, contours, new Mat(), Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_SIMPLE); 

     System.err.println(contours.size()); 

     contours = contours.stream().filter(s -> s.size().area() > 50 && s.size().area() <= 100).collect(Collectors.toList()); 

     for(MatOfPoint p : contours) { 
      Size size = p.size(); 
      System.err.println("-- -- --"); 
      System.err.println(size.area()); 
     } 

     Imgproc.drawContours(cannyRes, contours, 20, new Scalar(233, 223,212)); 
     LoadImage(cannyRes); 
    } 

    public static void LoadImage(Mat m) { 
     Path path = Paths.get("/tmp/", UUID.randomUUID().toString() + ".png"); 
     Highgui.imwrite(path.toString(), m); 
     JFrame frame = new JFrame("My GUI"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.setResizable(true); 
     frame.setLocationRelativeTo(null); 

     // Inserts the image icon 
     ImageIcon image = new ImageIcon(path.toString()); 
     frame.setSize(image.getIconWidth() + 10, image.getIconHeight() + 35); 
     // Draw the Image data into the BufferedImage 
     JLabel label1 = new JLabel(" ", image, JLabel.CENTER); 
     frame.getContentPane().add(label1); 

     frame.validate(); 
     frame.setVisible(true); 
    } 

} 
  1. 私は、バイナリイメージ

  2. を作成するために適応このアクションによって使用画像に

  3. を読みます私はイメージ内のエッジを検出するためにキャニーを使用します。

  4. 私は任意のサイズ

得られた輪郭を有する任意の輪郭を閉じ、私は私の画像

  • 内のオブジェクトを検索するために輪郭ファインダーを使用し、バックグラウンドノイズを

  • を除去するために、浸食/拡張使用しますおおよそあなたの黄色い斑点です。これは非常に正確ではありません。なぜなら、私は異なるパラメータで遊ぶ時間を費やさなかったのですが、それを微調整することができます。

    希望するものは、

    楽しく遊ぼう!ここでOpenCVを設定する方法を見ることができます:Java OpenCV from Maven

  • +0

    ありがとうございますが、画像を作成して1秒ごとに解析すると効率的だと思いますか?なぜなら、オブジェクト(ゴールド)をクリックするたびに、プレイヤーが別の場所にいるため、画面をスキャンしてイメージを生成する必要があるからです。 –

    +1

    あなたはキャンバスにオブジェクトを置くのはあなたですか?オブジェクトがどこにあるかを既に知っておく必要があるので、それらを検出する必要はありません。また、1秒に1回ではなく、1秒に少なくとも30回(これはあなたに比較的流暢な画像を与えるでしょう)、毎秒60フレームすることさえあります。しかし、CVでは、いったんオブジェクトを取得すると、それらがピクチャと共に移動することがわかります。毎回それらを再発見するのではなく、異なるテクニックを使用してそれらを追跡することができます。しかし、ゲームがあなたのコントロール下にある場合は、オブジェクトがどこに置かれているかを知るべきです – pandaadb

    関連する問題