AndroidStudio opencv(二)perspective transform

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/danfengw/article/details/78782608

这里写图片描述

 public void transform(View view) {
        //最开始的图片        
        Mat sampledImage = ImageUtils.bitmapToMat(mBitmap);
        //变换后图片
        Mat correctedImage = new Mat(sampledImage.rows(), sampledImage.cols(), sampledImage.type());

        Map<Integer, PointF> points = mPolygonView.getPoints();
        //屏幕选中点的坐标转换为图片坐标
        List<Point> srccorners = getSrcPoint(mBitmap, points);

        List<Point> descorners = new ArrayList<>();
        descorners.add(new Point(0, 0));
        descorners.add(new Point(correctedImage.cols(), 0));
        descorners.add(new Point(0, correctedImage.rows()));
        descorners.add(new Point(correctedImage.cols(), correctedImage.rows()));

        Mat srcPoints = Converters.vector_Point2f_to_Mat(srccorners);
        Mat desPoints = Converters.vector_Point2f_to_Mat(descorners);
        //求出变换矩阵
        Mat transformation = Imgproc.getPerspectiveTransform(srcPoints, desPoints);
        //进行仿射变换
        Imgproc.warpPerspective(sampledImage, correctedImage, transformation, correctedImage.size());
        displayImage(correctedImage);
    }
//ImageUtil的bitmapToMat()方法
  public static Mat bitmapToMat(Bitmap bitmap) {
        Mat mat = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8U, new Scalar(4));
        Bitmap bitmap32 = bitmap.copy(Bitmap.Config.ARGB_8888, true);
        Utils.bitmapToMat(bitmap32, mat);
        return mat;
    }
    //ImageUtil的matToBitmap()方法
    public static Bitmap matToBitmap(Mat mat) {
        Bitmap bitmap = Bitmap.createBitmap(mat.cols(), mat.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(mat, bitmap);
        return bitmap;
    }
 //屏幕坐标与图片坐标转换
    private List<Point> getSrcPoint(Bitmap original, Map<Integer, PointF> points) {
        List<Point> srccorners = new ArrayList<>();

        float xRatio = (float) original.getWidth() / mImageView.getWidth();
        float yRatio = (float) original.getHeight() / mImageView.getHeight();

        float x1 = (points.get(0).x) * xRatio;
        float x2 = (points.get(1).x) * xRatio;
        float x3 = (points.get(2).x) * xRatio;
        float x4 = (points.get(3).x) * xRatio;
        float y1 = (points.get(0).y) * yRatio;
        float y2 = (points.get(1).y) * yRatio;
        float y3 = (points.get(2).y) * yRatio;
        float y4 = (points.get(3).y) * yRatio;
        srccorners.add(new Point(x1, y1));
        srccorners.add(new Point(x2, y2));
        srccorners.add(new Point(x3, y3));
        srccorners.add(new Point(x4, y4));

        return srccorners;
    }

PolygonView

public class PolygonView extends FrameLayout {
    private Context mContext;
    private Paint mPaint;
    private ImageView mPointer1;
    private ImageView mPointer2;
    private ImageView mPointer3;
    private ImageView mPointer4;
    private PolygonView mPolygonView;

    public PolygonView(@NonNull Context context) {
        this(context, null);

    }

    public PolygonView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPolygonView = this;
        mPointer1 = getImageView(0, 0);
        mPointer2 = getImageView(getWidth(), 0);
        mPointer3 = getImageView(0, getHeight());
        mPointer4 = getImageView(getWidth(), getHeight());
        addView(mPointer1);
        addView(mPointer2);
        addView(mPointer3);
        addView(mPointer4);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(getResources().getColor(R.color.blue));
        mPaint.setStrokeWidth(2);
    }

    private ImageView getImageView(int x, int y) {
        ImageView imageview = new ImageView(mContext);
        LayoutParams layoutparams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        imageview.setLayoutParams(layoutparams);
        imageview.setImageResource(R.drawable.circle);
        imageview.setX(x);
        imageview.setY(y);
        imageview.setOnTouchListener(new TouchListaner());
        return imageview;
    }

    private class TouchListaner implements OnTouchListener {

        PointF downPoint = new PointF();
        PointF startPoint = new PointF();

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downPoint.x = event.getX();
                    downPoint.y = event.getY();
                    startPoint = new PointF(v.getX(), v.getY());
                    break;
                case MotionEvent.ACTION_MOVE:
                    PointF mv = new PointF(event.getX() - downPoint.x, event.getY() - downPoint.y);
                    if ((startPoint.x + mv.x + v.getWidth()) < mPolygonView.getWidth() &&
                            (startPoint.y + mv.y + v.getHeight()) < mPolygonView.getHeight() &&
                            (startPoint.x + mv.x) > 0 && (startPoint.y + mv.y) > 0
                            ) {
                        v.setX(startPoint.x + mv.x);
                        v.setY(startPoint.y + mv.y);
                        startPoint = new PointF(v.getX(), v.getY());
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    int color = 0;
                    if (isValidShape(getPoints())) {
                        color = getResources().getColor(R.color.blue);
                    } else {
                        color = getResources().getColor(R.color.orange);
                    }
                    mPaint.setColor(color);
                    break;
            }
            mPolygonView.invalidate();
            return true;
        }

    }

    public Map<Integer, PointF> getPoints() {
        List<PointF> points = new ArrayList<>();
        points.add(new PointF(mPointer1.getX(), mPointer1.getY()));
        points.add(new PointF(mPointer2.getX(), mPointer2.getY()));
        points.add(new PointF(mPointer3.getX(), mPointer3.getY()));
        points.add(new PointF(mPointer4.getX(), mPointer4.getY()));
        return getOrderedPoints(points);
    }

    /**
     * 为各个点重新排序
     * @param points
     * @return
     */
    public Map<Integer,PointF> getOrderedPoints(List<PointF> points){
        PointF centerPoint=new PointF();
        int size=points.size();
        for(PointF point:points){
            centerPoint.x+=point.x/size;
            centerPoint.y+=point.y/size;
        }
        Map<Integer,PointF> orderedPoints=new HashMap<>();
        for (PointF point:points){
            int index=-1;
            if (point.x<centerPoint.x&&point.y<centerPoint.y){
                index=0;
            }else if (point.x>centerPoint.x&&point.y<centerPoint.y){
                index=1;
            }else if (point.x<centerPoint.x&& point.y>centerPoint.y){
                index=2;
            }else if (point.x>centerPoint.x&&point.y>centerPoint.y){
                index=3;
            }
            orderedPoints.put(index,point);
        }

        return orderedPoints;
    }
    public boolean isValidShape(Map<Integer, PointF> pointFMap) {
        return pointFMap.size() == 4;
    }
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        canvas.drawLine(mPointer1.getX() + (mPointer1.getWidth() / 2), mPointer1.getY() + (mPointer1.getHeight() / 2), mPointer3.getX() + (mPointer3.getWidth() / 2), mPointer3.getY() + (mPointer3.getHeight() / 2), mPaint);
        canvas.drawLine(mPointer1.getX() + (mPointer1.getWidth() / 2), mPointer1.getY() + (mPointer1.getHeight() / 2), mPointer2.getX() + (mPointer2.getWidth() / 2), mPointer2.getY() + (mPointer2.getHeight() / 2), mPaint);
        canvas.drawLine(mPointer2.getX() + (mPointer2.getWidth() / 2), mPointer2.getY() + (mPointer2.getHeight() / 2), mPointer4.getX() + (mPointer4.getWidth() / 2), mPointer4.getY() + (mPointer4.getHeight() / 2), mPaint);
        canvas.drawLine(mPointer3.getX() + (mPointer3.getWidth() / 2), mPointer3.getY() + (mPointer3.getHeight() / 2), mPointer4.getX() + (mPointer4.getWidth() / 2), mPointer4.getY() + (mPointer4.getHeight() / 2), mPaint);

    }
    public void setPoints(Map<Integer, PointF> pointFMap) {
        if (pointFMap.size() == 4) {
            setPointsCoordinates(pointFMap);
        }
    }

    private void setPointsCoordinates(Map<Integer, PointF> pointFMap) {
        mPointer1.setX(pointFMap.get(0).x);
        mPointer1.setY(pointFMap.get(0).y);

        mPointer2.setX(pointFMap.get(1).x);
        mPointer2.setY(pointFMap.get(1).y);

        mPointer3.setX(pointFMap.get(2).x);
        mPointer3.setY(pointFMap.get(2).y);

        mPointer4.setX(pointFMap.get(3).x);
        mPointer4.setY(pointFMap.get(3).y);
    }

}
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页