如何使用Android Opencv检测目标上的弹孔 [英] How to detect bullet holes on the target using Android Opencv

查看:103
本文介绍了如何使用Android Opencv检测目标上的弹孔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个项目中工作,我必须扫描目标并识别目标中的孔,并且必须根据镜头得分.我不知道确切的代码如何识别目标中的漏洞.我导入了opencv库,并通过了一个程序,如果我触摸它,它将识别出相应的颜色.现在,我被困在编码部分.这是给我的目标表的屏幕截图.

I am working in a project where I have to scan the target and recognize the holes in the target and have to score according to the shots. I am not aware of the exact code how to recognize the holes in the target. I imported the opencv library and gone through a program where if I touch it will recognize the corresponding color. Now I am stuck in the coding part. Here is the screenshot of the target sheet that is given to me.

任何人都可以帮助我进一步进行操作.预先感谢.

Could anyone please help me how to proceed further. Thanks in advance.

推荐答案

要做自己想做的事

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.

,并且还要考虑一些特殊情况,例如图像中的双孔".

and also take into account some special cases, like "twin" holes in your image.

要在Android上实现该步骤最简单的方法是使用 OpenCV .如何在此处中对其进行详细说明(您应该做一些工作:从此处并正确添加).然后,您应该看一些有关在Android中使用OpenCV的教程,例如,

To implement that steps on Android easiest way is to use OpenCV. How to add it to your project well described here (You should do some work to do to it: download SDK from here and add it correctly). Then You should take a look at some tutorial about using OpenCV in Android, for example, official. And than, You can use code like this (your image added to drawable folder of demo project as 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 HOLES Button,您会得到如下结果

And if You press FIND HOLES Button You get result like this

对于其他图像,您应该在

中调整245, 255

For other images You should adjust 245, 255 values in

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>

这篇关于如何使用Android Opencv检测目标上的弹孔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆