OpenCV之图像处理(八) 绘制形状与文字

画线 cv::line (LINE_4\LINE_8\LINE_AA)
画椭圆cv::ellipse
画矩形cv::rectangle
画圆cv::circle
画填充cv::fillPoly
画文字cv::putText

vs代码

    #include "../common/common.hpp"

    static Mat bgImage;
    static void drawLines();
    static void drawRectangle();
    static void drawEllipse();
    static void drawCircle();
    static void drawPolygon();
    static void drawRandomLine();

    void main1_8(int argc, char** argv)
    {
        bgImage = imread(getCVImagesPath("images/test1.png"), IMREAD_COLOR);
        drawLines();
        drawRectangle();
        drawEllipse();
        drawCircle();
        drawPolygon();
        //参数:Mat,文字(不识别中文?),文字的位置(锚点?),字体,缩放,颜色,线宽,线类型
        putText(bgImage, "Hello OpenCV", Point(0, 200), CV_FONT_HERSHEY_COMPLEX, 1.0, Scalar(0), 3, LINE_8);//绘制文字
        imshow("src", bgImage);

        drawRandomLine();

        waitKey(0);
    }

    void drawLines()//绘制线条
    {
        Point p1 = Point(20, 30);//Point表示平面上的点,OpenCV中的这些坐标值都是相对于图像本身像素值的
        Point p2;
        p2.x = 400;
        p2.y = 400;
        Scalar color = Scalar(0, 0, 255);
        line(bgImage, p1, p2, color, 10, LINE_AA);//绘制线条到Mat,10是线宽、LINE_4或LINE_8是带锯齿的,LINE_AA是抗锯齿的
    }

    void drawRectangle()//绘制矩形
    {
        //OpenCV的坐标系,原点在屏幕左上角,x朝右正,y朝下正
        Rect rect = Rect(200, 100, 300, 300);//起始位置x、y,宽,高
        Scalar color = Scalar(255, 0, 0);
        rectangle(bgImage, rect, color, LINE_8);//绘制矩形到Mat,自带圆角。。
    }

    void drawEllipse()//绘制椭圆
    {
        int width = bgImage.cols;
        int height = bgImage.rows;
        Scalar color = Scalar(0, 255, 0);
        //绘制椭圆,参数:Mat,中心点,椭圆的长短轴半径,椭圆的朝向(0表示水平),起始角度,终点角度
        ellipse(bgImage, Point(width / 2, height / 2), Size(width / 4, height / 8), 0, 0, 270, color, 2, LINE_8);
    }

    void drawCircle()//绘制圆
    {
        Scalar color = Scalar(0, 255, 255);
        circle(bgImage, Point(bgImage.cols / 2, bgImage.rows / 2), 150, color, 2, LINE_8);
    }

    void drawPolygon()//绘制多边形,绘制的多边形是填充的
    {
        Point pts[1][5];
        pts[0][0] = Point(100, 100);
        pts[0][1] = Point(100, 200);
        pts[0][2] = Point(200, 200);
        pts[0][3] = Point(200, 100);
        pts[0][4] = Point(100, 100);

        const Point * ppts[] = { pts[0] };
        int npt[] = { 5 };
        Scalar color = Scalar(255, 0, 255);
        //参数:Mat,顶点数据指针,顶点个数,1表示只绘制一个contour(轮廓)
        fillPoly(bgImage, ppts, npt, 1, color, LINE_8);
    }

    void drawRandomLine()//循环绘制随机位置随机颜色的线段
    {
        Mat randomLineMat = Mat::zeros(bgImage.size(), bgImage.type());
        RNG rng(12345);//生成高斯随机数,参数种子
        Point p1, p2;
        for (int i = 0; i < 100000; i++)
        {
            p1.x = rng.uniform(0, randomLineMat.cols);//生成正态分布 0-bgImage.cols 范围内的随机数
            p1.y = rng.uniform(0, randomLineMat.rows);
            p2.x = rng.uniform(0, randomLineMat.cols);
            p2.y = rng.uniform(0, randomLineMat.rows);
            Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
            if (waitKey(50) > 0)//参数delay如果传0表示阻塞等待键盘事件,传大于0表示只阻塞等待delay毫秒,键盘无响应返回-1
            {
                break;
            }
            line(randomLineMat, p1, p2, color, 1, LINE_8);
            imshow("randomLine", randomLineMat);
        }
    }

效果图

这里写图片描述

android代码

@BindView(R.id.iv_cv1_8_input) ImageView mSrcIv;
@BindView(R.id.iv_cv1_8_output1) ImageView mRandomLineIv;
private Bitmap mSrcBmp;
private Bitmap mRandomLineBmp;
private Mat mSrcMat = new Mat();
private Mat mRandomLineMat;
private volatile boolean isStop;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cv1_8);
    mUnbinder = ButterKnife.bind(this);

    //src
    mSrcBmp = CV310Utils.getBitmapFromAssets(this, "opencv/test1.png");
    Utils.bitmapToMat(mSrcBmp, mSrcMat);
    drawLine();
    drawRectangle();
    drawEllipse();
    drawCircle();
    drawPolygon();
    //参数:Mat,文字(不识别中文?),文字的位置(锚点?),字体,缩放,颜色,线宽,线类型,固定false
    Imgproc.putText(mSrcMat, "Hello OpenCV", new Point(0, 100), Core.FONT_HERSHEY_COMPLEX, 1.0, new Scalar(0), 3, Imgproc.LINE_8, false);//绘制文字
    Imgproc.putText(mSrcMat, "中文", new Point(0, 200), Core.FONT_HERSHEY_COMPLEX, 1.0, new Scalar(0), 3, Imgproc.LINE_8, false);
    CV310Utils.mat2bitmapAndShowInIv(mSrcMat, mSrcBmp, mSrcIv);

    //random line
    mRandomLineIv.post(new Runnable() {
        @Override
        public void run() {
            new Thread(){
                @Override
                public void run() {
                    drawRandomLine(mRandomLineIv.getWidth(), mRandomLineIv.getHeight());
                }
            }.start();
        }
    });
}

/*画线*/
private void drawLine() {
    Point p1 = new Point(20, 30);//Point表示平面上的点,OpenCV中的这些坐标值都是相对于图像本身像素值的
    Point p2 = new Point(400, 400);
    Scalar color = new Scalar(255, 0, 0, 255);//因为bitmap是ARGB_8888的,所以Scalar要传alpha
    Imgproc.line(mSrcMat, p1, p2, color, 10, Imgproc.LINE_AA, 0);//绘制线条到Mat,10是线宽、LINE_4或LINE_8是带锯齿的,LINE_AA是抗锯齿的,参数shift固定传0
}

/*画矩形*/
private void drawRectangle() {
    //Rect rect = new Rect(200, 100, 300, 300);//起始位置x、y,宽,高
    Scalar color = new Scalar(0, 0, 255, 255);
    //OpenCV的坐标系,原点在屏幕左上角,x朝右正,y朝下正,参数:Mat,矩形坐上点 右下点
    Imgproc.rectangle(mSrcMat, new Point(200, 100), new Point(500, 400), color, Imgproc.LINE_8);//绘制矩形到Mat,自带圆角。。
}

/*绘制椭圆*/
private void drawEllipse() {
    int width = mSrcMat.cols();
    int height = mSrcMat.rows();
    Scalar color = new Scalar(0, 255, 0, 255);
    //绘制椭圆,参数:Mat,中心点,椭圆的长短轴半径,椭圆的朝向(0表示水平),起始角度,终点角度
    Imgproc.ellipse(mSrcMat, new Point(width / 2, height / 2), new Size(width / 4, height / 8), 0, 0, 270, color, 2, Imgproc.LINE_8, 0);
}

/*绘制圆*/
private void drawCircle() {
    Scalar color = new Scalar(255, 255, 0, 255);
    Imgproc.circle(mSrcMat, new Point(mSrcMat.cols()/2, mSrcMat.rows()/2), 150, color, 2, Imgproc.LINE_8, 0);
}

/*绘制多边形,绘制的多边形是填充的*/
private void drawPolygon() {
    List<MatOfPoint> pts = new ArrayList<>();
    //需要这样组织顶点数据,否则绘制不出来
    pts.add(new MatOfPoint(new Point(100, 100), new Point(100, 200), new Point(200, 200), new Point(200, 100), new Point(100, 100)));
    //同样的顶点,与c++绘制出来的地方偏差了100。。
    pts.add(new MatOfPoint(new Point(100, 300), new Point(100, 400), new Point(200, 400), new Point(200, 300), new Point(100, 300)));
    Scalar color = new Scalar(255, 0, 255, 255);
    Imgproc.fillPoly(mSrcMat, pts, color, Imgproc.LINE_8, 0, new Point(100, 100));//pts.size()多少就绘制几个多边形
}

/*循环绘制随机位置随机颜色的线段*/
private void drawRandomLine(int width, int height) {
    mRandomLineBmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    mRandomLineMat = Mat.zeros(new Size(width, height), mSrcMat.type());
    Random random = new Random();
    Point p1 = new Point();
    Point p2 = new Point();
    for (int i = 0; i < 100000; i++) {
        p1.x = random.nextInt(width);
        p1.y = random.nextInt(height);
        p2.x = random.nextInt(width);
        p2.y = random.nextInt(height);
        Scalar color = new Scalar(random.nextInt(255), random.nextInt(255), random.nextInt(255), 255);//线段与颜色都随机
        if (isStop) {
            break;
        } else {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Imgproc.line(mRandomLineMat, p1, p2, color, 1, Imgproc.LINE_8, 0);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                CV310Utils.mat2bitmapAndShowInIv(mRandomLineMat, mRandomLineBmp, mRandomLineIv);
            }
        });
    }
}

@OnClick({R.id.btn_cv1_8_stop})
void click(View view) {
    switch (view.getId()) {
        case R.id.btn_cv1_8_stop:
            isStop = true;
            break;
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    isStop = true;
}

效果图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/80896543
今日推荐