2016-11-15 5 views
-3

Я работаю в проекте, где я должен сканировать цель и распознавать отверстия в цели и забивать в соответствии с выстрелами. Я не знаю точно, как распознать дыры в цели. Я импортировал библиотеку opencv и прошел через программу, где, если я коснусь ее, она узнает соответствующий цвет. Теперь я застрял в кодирующей части. Вот скриншот целевого листа, который мне дал.Как обнаружить пулевые отверстия на цели с помощью Android Opencv

enter image description here

Может кто-нибудь, пожалуйста, помогите мне, как действовать дальше. Заранее спасибо.

+0

я мог бы найти такую ​​же проблему в другом вопросе, но он использует в питона. http://stackoverflow.com/questions/33321303/how-to-detect-bullet-holes-on-the-target-using-python – SomeshShuffle

ответ

0

Чтобы сделать то, что Вы хотите, Вы должны:

1) find white areas with max brightness; 
2) find bounding contours of areas with max brightness (from p.1); 
3) find bounding boxes for contours from p.2; 
4) count bounding boxes. 

, а также принимать во внимание некоторые особые случаи, как «близнецы» дырками в изображении.

Чтобы реализовать эти шаги на Android, проще всего использовать OpenCV. Как добавить его в свой проект, хорошо описанный here (вам нужно сделать некоторую работу, чтобы сделать с ним: загрузить SDK от here и добавить его правильно). Затем вы должны взглянуть на некоторый учебник об использовании OpenCV в Android, например, official. И чем, вы можете использовать код, как это (ваш образ добавлен в drawable папку демонстрационного проекта как target.png):

public class MainActivity extends AppCompatActivity { 

    public static final String TAG = MainActivity.class.getSimpleName(); 

    private ImageView mImageView; 
    private Button mProcessButton; 

    private Mat mSourceImageMat; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mImageView = (ImageView) findViewById(R.id.target_image_view); 
     mProcessButton = (Button) findViewById(R.id.process_button); 
     mProcessButton.setVisibility(View.INVISIBLE); 

     mProcessButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       processImage(); 
      } 
     }); 
    } 

    private void processImage() { 
     try { 
      mSourceImageMat = Utils.loadResource(this, R.drawable.target); 
      Bitmap bm = Bitmap.createBitmap(mSourceImageMat.cols(), mSourceImageMat.rows(),Bitmap.Config.ARGB_8888); 

      final Mat mat = new Mat(); 
      final List<Mat> channels = new ArrayList<>(3); 

      mSourceImageMat.copyTo(mat); 

      // split image channels: 0-H, 1-S, 2-V 
      Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGB2HSV); 
      Core.split(mat, channels); 
      final Mat frameV = channels.get(2); 

      // find white areas with max brightness 
      Imgproc.threshold(frameV, frameV, 245, 255, Imgproc.THRESH_BINARY); 

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

      // find average contour area for "twin" hole detection 
      double averageArea = 0; 
      int contoursCount = 0; 
      Iterator<MatOfPoint> each = contours.iterator(); 
      while (each.hasNext()) { 
       averageArea += Imgproc.contourArea(each.next()); 
       contoursCount++; 
      } 
      if (contoursCount != 0) { 
       averageArea /= contoursCount; 
      } 

      int holesCount = 0; 
      each = contours.iterator(); 
      while (each.hasNext()) { 
       MatOfPoint contour = each.next(); 

       MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray()); 
       RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints); 
       Point rect_points[] = new Point[4]; 

       boundingRect.points(rect_points); 
       for(int i=0; i<4; ++i){ 
        Imgproc.line(mSourceImageMat, rect_points[i], rect_points[(i+1)%4], new Scalar(255,0,0), 2); 
       } 
       holesCount++; 

       Imgproc.putText(mSourceImageMat, Integer.toString(holesCount), new Point(boundingRect.center.x + 20, boundingRect.center.y), 
         Core.FONT_HERSHEY_PLAIN, 1.5 ,new Scalar(255, 0, 0)); 

       // case of "twin" hole (like 9 & 10) on image 
       if (Imgproc.contourArea(contour) > 1.3f * averageArea) { 
        holesCount++; 
        Imgproc.putText(mSourceImageMat, ", " + Integer.toString(holesCount), new Point(boundingRect.center.x + 40, boundingRect.center.y), 
          Core.FONT_HERSHEY_PLAIN, 1.5 ,new Scalar(255, 0, 0)); 
       } 

      } 

      // convert to bitmap: 
      Utils.matToBitmap(mSourceImageMat, bm); 
      mImageView.setImageBitmap(bm); 

      // release 
      frameV.release(); 
      mat.release(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


    } 

    @Override 
    protected void onPostResume() { 
     super.onPostResume(); 
     OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mOpenCVLoaderCallback); 
    } 

    private BaseLoaderCallback mOpenCVLoaderCallback = new BaseLoaderCallback(this) { 
     @Override 
     public void onManagerConnected(int status) { 
      switch (status) { 
       case LoaderCallbackInterface.SUCCESS: { 
        Log.i(TAG, "OpenCV loaded successfully"); 
        mProcessButton.setVisibility(View.VISIBLE); 
       } break; 
       default: { 
        super.onManagerConnected(status); 
       } break; 
      } 
     } 
    }; 
} 

И если Вы нажмете FIND HOLESButton Вы получаете результат, как этот

result

Для других изображений Вы должны отрегулировать значения 245, 255 в

Imgproc.threshold(frameV, frameV, 245, 255, Imgproc.THRESH_BINARY); 

линия.

Обновление: MainActivity макет (activity_main.xml):

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/activity_main" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity"> 

    <ImageView 
     android:id="@+id/target_image_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scaleType="fitCenter" 
     app:srcCompat="@drawable/target" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentStart="true" 
     android:layout_above="@+id/process_button"/> 

    <Button 
     android:id="@+id/process_button" 
     android:text="Find holes" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentStart="true" 
     android:layout_alignParentEnd="true"/> 

</RelativeLayout> 
+0

Большое спасибо @ Andriy Omelchenko. Ваша программа работает как шарм. Я просто следил за твоими шагами, и он отлично работает. На самом деле ты так полезен. Я просто начинаю свою карьеру как разработчик Android. Это мой первый проект по обработке изображений. Поэтому я понятия не имею об этом. Тем не менее у меня есть много этапов. В любом случае, спасибо за ваше руководство. Вы так полезны. Хотел бы я узнать больше от вас, сэр. Спасибо, сэр. – SomeshShuffle

+0

Добро пожаловать! (а также вы можете перенести ответ;)) –

+0

Здравствуйте @Andriy Omelchenko, мне нужна другая помощь от вас. Надеюсь, ты поможешь мне в этом. Ваш пример работает для одного изображения, которое хранится в папке с возможностью переноса. Предположим, если я хочу захватить изображение и распознать отверстия, что мне делать? Не могли бы вы помочь мне с кодирующей частью. Теперь я хочу захватить изображение, и когда я нажимаю кнопку «Найти отверстия», я должен уметь распознавать отверстия. Есть ли способ сделать это? Надеюсь, вы поможете мне решить проблему. Спасибо. – SomeshShuffle