首页 > 解决方案 > Android:如何使用 openCv 将对象放在屏幕的特定位置?

问题描述

编辑:

如果有人可以建议任何链接或帖子,我将非常感激。我试图从两天内找到解决方案,但我找不到任何解决方案。提前谢谢你。


我正在尝试将一个对象(图像)放在屏幕的特定位置在 android 中使用 openCv。

我确实有像“{680.0, 488.0}”这样的点,它具有(x,y)坐标,

那么如何在我的屏幕上找到放置对象的特定位置?

下面是我得到点的代码:

     public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();

        iThreshold = minTresholdSeekbar.getProgress();

        //Imgproc.blur(mRgba, mRgba, new Size(5,5));
        Imgproc.GaussianBlur(mRgba, mRgba, new org.opencv.core.Size(3, 3), 1, 1);
        //Imgproc.medianBlur(mRgba, mRgba, 3);

        if (!mIsColorSelected) return mRgba;

        List<MatOfPoint> contours = mDetector.getContours();
        mDetector.process(mRgba);

        Log.d(TAG, "Contours count: " + contours.size());

        if (contours.size() <= 0) {
            return mRgba;
        }

        RotatedRect rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(0).toArray()));

        double boundWidth = rect.size.width;
        double boundHeight = rect.size.height;
        int boundPos = 0;

        for (int i = 1; i < contours.size(); i++) {
            rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
            if (rect.size.width * rect.size.height > boundWidth * boundHeight) {
                boundWidth = rect.size.width;
                boundHeight = rect.size.height;
                boundPos = i;
            }
        }

        Rect boundRect = Imgproc.boundingRect(new MatOfPoint(contours.get(boundPos).toArray()));
        //Core/Imgproc.rectangle( mRgba, boundRect.tl(), boundRect.br(), CONTOUR_COLOR_WHITE, 2, 8, 0 );

        Log.d(TAG,
                " Row start [" +
                        (int) boundRect.tl().y + "] row end [" +
                        (int) boundRect.br().y + "] Col start [" +
                        (int) boundRect.tl().x + "] Col end [" +
                        (int) boundRect.br().x + "]");

        int rectHeightThresh = 0;
        double a = boundRect.br().y - boundRect.tl().y;
        a = a * 0.7;
        a = boundRect.tl().y + a;

        Log.d(TAG,
                " A [" + a + "] br y - tl y = [" + (boundRect.br().y - boundRect.tl().y) + "]");

        //Core.rectangle( mRgba, boundRect.tl(), boundRect.br(), CONTOUR_COLOR, 2, 8, 0 );
        //Core/Imgproc.rectangle( mRgba, boundRect.tl(), new Point(boundRect.br().x, a), CONTOUR_COLOR, 2, 8, 0 );

        MatOfPoint2f pointMat = new MatOfPoint2f();
        Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(boundPos).toArray()), pointMat, 3, true);
        contours.set(boundPos, new MatOfPoint(pointMat.toArray()));

        MatOfInt hull = new MatOfInt();
        MatOfInt4 convexDefect = new MatOfInt4();
        Imgproc.convexHull(new MatOfPoint(contours.get(boundPos).toArray()), hull);

        if (hull.toArray().length < 3) return mRgba;

        Imgproc.convexityDefects(new MatOfPoint(contours.get(boundPos).toArray()), hull, convexDefect);

        List<MatOfPoint> hullPoints = new LinkedList<MatOfPoint>();
        List<Point> listPo = new LinkedList<Point>();
        for (int j = 0; j < hull.toList().size(); j++) {
            listPo.add(contours.get(boundPos).toList().get(hull.toList().get(j)));
        }

        MatOfPoint e = new MatOfPoint();
        e.fromList(listPo);
        hullPoints.add(e);

        List<MatOfPoint> defectPoints = new LinkedList<MatOfPoint>();
        List<Point> listPoDefect = new LinkedList<Point>();
        for (int j = 0; j < convexDefect.toList().size(); j = j + 4) {
            Point farPoint = contours.get(boundPos).toList().get(convexDefect.toList().get(j + 2));
            Integer depth = convexDefect.toList().get(j + 3);
            if (depth > iThreshold && farPoint.y < a) {
                listPoDefect.add(contours.get(boundPos).toList().get(convexDefect.toList().get(j + 2)));
            }
            Log.d(TAG, "defects [" + j + "] " + convexDefect.toList().get(j + 3));
        }

        MatOfPoint e2 = new MatOfPoint();
        e2.fromList(listPo);
        defectPoints.add(e2);

        Log.d(TAG, "hull: " + hull.toList());
        Log.d(TAG, "defects: " + convexDefect.toList());

        Imgproc.drawContours(mRgba, hullPoints, -1, CONTOUR_COLOR, 3);

        int defectsTotal = (int) convexDefect.total();
        Log.d(TAG, "Defect total " + defectsTotal);

        this.numberOfFingers = listPoDefect.size();
        if (this.numberOfFingers > 5) {
            this.numberOfFingers = 5;
        } /*else if (this.numberOfFingers == 1) {
            this.numberOfFingers = 0;
        }
*/

        mHandler.post(mUpdateFingerCountResults);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ring.setVisibility(View.VISIBLE);
                /*LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(10,10);
                ring.setLayoutParams(parms);*/
            }
        });

        for (Point p : listPoDefect) {

            Log.e("Points", p.toString());
            // Imgproc.circle(mRgba, p, 6, new Scalar(255,0,255));
        }

        return mRgba;
    }

以下是我用来保存图像和显示的方法。现在我需要将戒指戴在捕获的手指上。

   private void saveImage() {

    if (MainActivity.listPoDefect.size() >= 5) {
        mIsColorSelected = false;


        if (listPoDefect.size() != 0) {
            for (Point p :listPoDefect) {

                Log.d(TAG, "before sorting X =" + String.valueOf(p.x) + " Y = " + String.valueOf(p.y));

            }
            Collections.sort(listPoDefect, new Comparator<Point>() {

                public int compare(Point o1, Point o2) {
                    return Double.compare(o1.x, o2.x);
                }
            });


            Log.d(TAG, "After Sorting ");

            for (Point p : listPoDefect) {

                Log.d(TAG, "after sorting X =" + String.valueOf(p.x) + " Y = " + String.valueOf(p.y));

            }

        }


        mIsColorSelected = false;


        Bitmap bitmap5 = Bitmap.createBitmap(mRgbaWithoutLine.cols(), mRgbaWithoutLine.rows(), Bitmap.Config.ARGB_8888);

        Utils.matToBitmap(mRgbaWithoutLine, bitmap5);


        bitmap = bitmap5;


        //Create a new image bitmap and attach a brand new canvas to it
        Bitmap tempBitmap = Bitmap.createBitmap(bitmap5.getWidth(), bitmap5.getHeight(), Bitmap.Config.RGB_565);
        Canvas tempCanvas = new Canvas(tempBitmap);

        //Draw the image bitmap into the cavas
        tempCanvas.drawBitmap(bitmap5, 0, 0, null);


        double scaledWidth = bitmap5.getWidth();
        double scaledHeight = bitmap5.getHeight();

        double xScaleFactor = scaledWidth / bitmap5.getWidth();
        double yScaleFactor = scaledHeight / bitmap5.getHeight();


        Paint myRectPaint = new Paint();
        myRectPaint.setStyle(Paint.Style.STROKE);
        myRectPaint.setColor(Color.RED);
        myRectPaint.setStrokeWidth(5);
        myRectPaint.setAntiAlias(true);


       //this is zeroth position manipulation

        double differenceX= listPoDefect.get(2).x-listPoDefect.get(1).x;
        double differenceY= listPoDefect.get(2).y-listPoDefect.get(1).y;

        double zeroPostionX=listPoDefect.get(1).x-differenceX;
        double zeroPostionY=listPoDefect.get(1).y-differenceY;

        Point pointZeroths=listPoDefect.get(0);

        Point pointNew=new Point(zeroPostionX,zeroPostionY);

        listPoDefect.remove(0);

        listPoDefect.add(0,pointNew);


        double thirdPostionX=listPoDefect.get(2).x+differenceX;
        double thirdPostionY=listPoDefect.get(2).y+differenceY;

        Point thirdpointNew=new Point(thirdPostionX,thirdPostionY);

        listPoDefect.remove(3);

        listPoDefect.add(3,thirdpointNew);


        //    Point pointNewThird=new Point(pointthird.x+differenc,pointthird.y);


        //   HomeActivity.listPoDefect.remove(3);

        //   HomeActivity.listPoDefect.add(3,pointNewThird);

        Paint paint_text = new Paint();
        paint_text.setColor(Color.WHITE);
        paint_text.setStyle(Paint.Style.FILL);
        paint_text.setTextSize(30);

        for (int row = 0; row < 4; row++) { // draw 2 rows


            Point point1 = null;
            point1 = listPoDefect.get(row);


            android.graphics.Point canvas_point1 = new android.graphics.Point((int) ((point1.x * xScaleFactor)), (int) ((point1.y * yScaleFactor)));


            Log.d(TAG, "after sorting canvas_point1 ="+"Raw ="+row +" " + String.valueOf(canvas_point1.x) + " Y = " + String.valueOf(canvas_point1.y));
            Log.d(TAG, "====================================================================================================");

            if(pointFListGraphies.size()!=4)
            {
                pointFListGraphies.add(new PointF(canvas_point1));

            }
          // tempCanvas.drawRect(canvas_point1.x, canvas_point1.y, canvas_point1.x + 130, canvas_point1.y + 50, myRectPaint);

           // tempCanvas.drawText(String.valueOf(row+"-"+canvas_point1.x), canvas_point1.x, canvas_point1.y, paint_text);

        }
        Log.d(TAG, "====================================================================================================");


        for (int row = 0; row <  pointFListGraphies.size(); row++) { // draw 2 rows


            PointF point1 = null;
            point1 = pointFListGraphies.get(row);
            Log.d(TAG, "=========pointF X="+point1.x +"poninF Y =" +point1.y);

        }
        tempbitmap = tempBitmap;
        handImage.setVisibility(View.VISIBLE);
        handImage.setImageBitmap(tempbitmap);
       /* Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.ring);
        tempCanvas.drawBitmap();*/
        onCameraViewStopped();

        //finish();
    }
    else {

    }

}

谁能帮我?提前致谢。

标签: androidopencv4androidopencv3.1

解决方案


OpenCV 有许多用于在图像上书写的功能,这通常是您在屏幕上显示的内容。

例如,在特定位置写入文本的功能是

void cv::putText    (   InputOutputArray    img,
        const String &  text,
        Point   org,
        int     fontFace,
        double  fontScale,
        Scalar  color,
        int     thickness = 1,
        int     lineType = LINE_8,
        bool    bottomLeftOrigin = false 
)   

参数是:

Parameters
  img   Image.
  text  Text string to be drawn.
  org   Bottom-left corner of the text string in the image.
  fontFace  Font type, see cv::HersheyFonts.
  fontScale Font scale factor that is multiplied by the font-specific base      size.
  color Text color.
  thickness Thickness of the lines used to draw a text.
  lineType  Line type. See the line for details.
  bottomLeftOrigin  When true, the image data origin is at the bottom-left        corner. Otherwise, it is at the top-left corner.

您可以在此处找到绘图功能的概述:https ://docs.opencv.org/3.1.0/dc/da5/tutorial_py_drawing_functions.html

在您的情况下,只要您的图像覆盖整个屏幕,就可以准确地绘制您想要文本、对象或任何您想要绘制的内容的位置。


推荐阅读