OpenCV在图像上画线、矩形、椭圆、多边形、填充的多边形、圆、显示文字

本文通过示例代码展示了如何使用OpenCV库在图像上绘制随机的直线、矩形、椭圆、多边形、圆及显示随机文本,并最终呈现特定标语。通过不同形状和文本的随机生成,展现了OpenCV强大的绘图功能。

OpenCV在图像上随机画直线、椭圆、多边形、圆、显示文字

代码如下:

/**
 * @file Drawing_2.cpp
 * @brief Simple sample code
 */

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace cv;

/// Global Variables
const int NUMBER = 100;
const int DELAY = 5;

const int window_width = 900;
const int window_height = 600;
int x_1 = -window_width/2;
int x_2 = window_width*3/2;
int y_1 = -window_width/2;
int y_2 = window_width*3/2;

/// Function headers
static Scalar randomColor( RNG& rng );
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng );
int Drawing_Random_Rectangles( Mat image, char* window_name, RNG rng );
int Drawing_Random_Ellipses( Mat image, char* window_name, RNG rng );
int Drawing_Random_Polylines( Mat image, char* window_name, RNG rng );
int Drawing_Random_Filled_Polygons( Mat image, char* window_name, RNG rng );
int Drawing_Random_Circles( Mat image, char* window_name, RNG rng );
int Displaying_Random_Text( Mat image, char* window_name, RNG rng );
int Displaying_Big_End( Mat image, char* window_name, RNG rng );


/**
 * @function main
 */
int main( void )
{
  int c;

  /// Start creating a window
  char window_name[] = "Drawing_2 Tutorial";

  /// Also create a random object (RNG)
  RNG rng( 0xFFFFFFFF );

  /// Initialize a matrix filled with zeros
  Mat image = Mat::zeros( window_height, window_width, CV_8UC3 );
  /// Show it in a window during DELAY ms
  imshow( window_name, image );
  waitKey( DELAY );

  /// 画线
  c = Drawing_Random_Lines(image, window_name, rng);
  if( c != 0 ) return 0;

  /// 矩形
  c = Drawing_Random_Rectangles(image, window_name, rng);
  if( c != 0 ) return 0;

  /// 椭圆
  c = Drawing_Random_Ellipses( image, window_name, rng );
  if( c != 0 ) return 0;

  /// 多边形
  c = Drawing_Random_Polylines( image, window_name, rng );
  if( c != 0 ) return 0;

  /// 填充的多边形
  c = Drawing_Random_Filled_Polygons( image, window_name, rng );
  if( c != 0 ) return 0;

  /// 圆
  c = Drawing_Random_Circles( image, window_name, rng );
  if( c != 0 ) return 0;

  /// 随机位置显示文本
  c = Displaying_Random_Text( image, window_name, rng );
  if( c != 0 ) return 0;

  /// 显示文字
  c = Displaying_Big_End( image, window_name, rng );
  if( c != 0 ) return 0;

  waitKey(0);
  return 0;
}

/// Function definitions

/**
 * @function randomColor
 * @brief Produces a random color given a random object
 */
static Scalar randomColor( RNG& rng )
{
  int icolor = (unsigned) rng;
  return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
}


/**
 * @function 随机画线
 */
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng )
{
  Point pt1, pt2;

  for( int i = 0; i < NUMBER; i++ )
  {
    pt1.x = rng.uniform( x_1, x_2 );
    pt1.y = rng.uniform( y_1, y_2 );
    pt2.x = rng.uniform( x_1, x_2 );
    pt2.y = rng.uniform( y_1, y_2 );

    line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 );
    imshow( window_name, image );
    if( waitKey( DELAY ) >= 0 )
      { return -1; }
  }

  return 0;
}

/**
 * @function 画矩形
 */
int Drawing_Random_Rectangles( Mat image, char* window_name, RNG rng )
{
  Point pt1, pt2;
  int lineType = 8;
  int thickness = rng.uniform( -3, 10 );

  for( int i = 0; i < NUMBER; i++ )
  {
    pt1.x = rng.uniform( x_1, x_2 );
    pt1.y = rng.uniform( y_1, y_2 );
    pt2.x = rng.uniform( x_1, x_2 );
    pt2.y = rng.uniform( y_1, y_2 );

    rectangle( image, pt1, pt2, randomColor(rng), MAX( thickness, -1 ), lineType );

    imshow( window_name, image );
    if( waitKey( DELAY ) >= 0 )
      { return -1; }
  }

  return 0;
}

/**
 * @function 随机椭圆
 */
int Drawing_Random_Ellipses( Mat image, char* window_name, RNG rng )
{
  int lineType = 8;

  for ( int i = 0; i < NUMBER; i++ )
  {
    Point center;
    center.x = rng.uniform(x_1, x_2);
    center.y = rng.uniform(y_1, y_2);

    Size axes;
    axes.width = rng.uniform(0, 200);
    axes.height = rng.uniform(0, 200);

    double angle = rng.uniform(0, 180);

    ellipse( image, center, axes, angle, angle - 100, angle + 200,
             randomColor(rng), rng.uniform(-1,9), lineType );

    imshow( window_name, image );

    if( waitKey(DELAY) >= 0 )
      { return -1; }
  }

  return 0;
}

/**
 * @function 多边形
 */
int Drawing_Random_Polylines( Mat image, char* window_name, RNG rng )
{
  int lineType = 8;

  for( int i = 0; i< NUMBER; i++ )
  {
    Point pt[2][3];
    pt[0][0].x = rng.uniform(x_1, x_2);
    pt[0][0].y = rng.uniform(y_1, y_2);
    pt[0][1].x = rng.uniform(x_1, x_2);
    pt[0][1].y = rng.uniform(y_1, y_2);
    pt[0][2].x = rng.uniform(x_1, x_2);
    pt[0][2].y = rng.uniform(y_1, y_2);
    pt[1][0].x = rng.uniform(x_1, x_2);
    pt[1][0].y = rng.uniform(y_1, y_2);
    pt[1][1].x = rng.uniform(x_1, x_2);
    pt[1][1].y = rng.uniform(y_1, y_2);
    pt[1][2].x = rng.uniform(x_1, x_2);
    pt[1][2].y = rng.uniform(y_1, y_2);

    const Point* ppt[2] = {pt[0], pt[1]};
    int npt[] = {3, 3};

    polylines(image, ppt, npt, 2, true, randomColor(rng), rng.uniform(1,10), lineType);

    imshow( window_name, image );
    if( waitKey(DELAY) >= 0 )
      { return -1; }
  }
  return 0;
}

/**
 * @function 填充的多边形
 */
int Drawing_Random_Filled_Polygons( Mat image, char* window_name, RNG rng )
{
  int lineType = 8;

  for ( int i = 0; i < NUMBER; i++ )
  {
    Point pt[2][3];
    pt[0][0].x = rng.uniform(x_1, x_2);
    pt[0][0].y = rng.uniform(y_1, y_2);
    pt[0][1].x = rng.uniform(x_1, x_2);
    pt[0][1].y = rng.uniform(y_1, y_2);
    pt[0][2].x = rng.uniform(x_1, x_2);
    pt[0][2].y = rng.uniform(y_1, y_2);
    pt[1][0].x = rng.uniform(x_1, x_2);
    pt[1][0].y = rng.uniform(y_1, y_2);
    pt[1][1].x = rng.uniform(x_1, x_2);
    pt[1][1].y = rng.uniform(y_1, y_2);
    pt[1][2].x = rng.uniform(x_1, x_2);
    pt[1][2].y = rng.uniform(y_1, y_2);

    const Point* ppt[2] = {pt[0], pt[1]};
    int npt[] = {3, 3};

    fillPoly( image, ppt, npt, 2, randomColor(rng), lineType );

    imshow( window_name, image );
    if( waitKey(DELAY) >= 0 )
       { return -1; }
  }
  return 0;
}

/**
 * @function 圆
 */
int Drawing_Random_Circles( Mat image, char* window_name, RNG rng )
{
  int lineType = 8;

  for (int i = 0; i < NUMBER; i++)
  {
    Point center;
    center.x = rng.uniform(x_1, x_2);
    center.y = rng.uniform(y_1, y_2);

    circle( image, center, rng.uniform(0, 300), randomColor(rng),
            rng.uniform(-1, 9), lineType );

    imshow( window_name, image );
    if( waitKey(DELAY) >= 0 )
      { return -1; }
  }

  return 0;
}

/**
 * @function 显示文本
 */
int Displaying_Random_Text( Mat image, char* window_name, RNG rng )
{
  int lineType = 8;

  for ( int i = 1; i < NUMBER; i++ )
  {
    Point org;
    org.x = rng.uniform(x_1, x_2);
    org.y = rng.uniform(y_1, y_2);

    putText( image, "Testing text rendering", org, rng.uniform(0,8),
             rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType);

    imshow( window_name, image );
    if( waitKey(DELAY) >= 0 )
      { return -1; }
  }

  return 0;
}显示文本Displaying_Big_End
 */
int Displaying_Big_End( Mat image, char* window_name, RNG )
{
  Size textsize = getTextSize("OpenCV forever!", FONT_HERSHEY_COMPLEX, 3, 5, 0);
  Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2);
  int lineType = 8;

  Mat image2;

  for( int i = 0; i < 255; i += 2 )
  {
    image2 = image - Scalar::all(i);
    putText( image2, "OpenCV forever!", org, FONT_HERSHEY_COMPLEX, 3,
             Scalar(i, i, 255), 5, lineType );

    imshow( window_name, image2 );
    if( waitKey(DELAY) >= 0 )
       { return -1; }
  }

  return 0;
}

结果:

  1. 随机画线:

    Drawing_2_Tutorial_Result_0.jpg
  2. 矩形和椭圆
    Drawing_2_Tutorial_Result_2.jpg
  3. 多边形

    Drawing_2_Tutorial_Result_3.jpg
  4. 填充的多边形(三角形)和圆
    Drawing_2_Tutorial_Result_5.jpg
  5. 最后,"Testing Text Rendering"*将会以不同的字体,大小、颜色出现在不同的位置.最后,显示”OpenCV forever!“

   Drawing_2_Tutorial_Result_big.jpg


  
  




<think>嗯,用户想在OpenCV中使用IplImage格式绘制基本图形,比如形、矩形、点、线、多边形椭圆,而且他们用的是C++和VS2019环境。首先,我得确认IplImage在OpenCV中的使用方式,因为现在OpenCV主要推荐使用Mat结构,但IplImage仍然被支持。可能需要提醒用户注意兼容性,或者是否有必要升级到Mat。 接下来,绘制各个图形需要哪些函数呢?比如,可能是cvCircle,矩形是cvRectangle,直线是cvLine,点的话可能需要用cvLine来一个点,或者直接操作像素。多边形的话,可能需要用cvPolyLine或者填充多边形椭圆的话,应该是cvEllipse。 然后,需要注意每个函数的参数,比如坐标、颜色、线宽等。颜色在IplImage中是按通道顺序的,比如BGR。另外,IplImage的结构需要正确,比如是否是3通道或者单通道,不同的通道可能影响颜色参数的使用。 还有,用户提到的环境是VS2019,需要确保OpenCV的库正确配置,包含头文件和链接库。可能需要提醒用户包含必要的头文件,比如opencv2/core/core_c.h和opencv2/imgproc/imgproc_c.h,因为这些旧的C接口的函数可能在新的OpenCV版本中被移到不同的头文件中。 另外,内存管理方面,IplImage需要手动释放,使用cvReleaseImage,但用户的问题主要是绘制,可能不需要涉及创建和释放,除非他们要新建图像。如果是处理现有的图像,比如加载或从摄像头获取,需要注意不要溢出内存。 可能还需要注意绘制函数是否需要图像是8位深度,颜色范围是否正确。比如,cvCircle的参数中的thickness如果是负数的话,可能表示填充图形,比如填充或者矩形。 还要考虑到多边形的绘制,可能需要定义点的数组,比如CvPoint*数组,并且正确传递顶点数和是否闭合。 最后,示例代码的结构应该包括创建图像、绘制各个图形、显示和保存,以及释放资源。需要确保代码在VS2019中能够编译通过,可能需要配置项目属性,添加OpenCV的包含目录、库目录和链接库。 可能还需要提醒用户关于OpenCV的C接口和C++接口的区别,比如IplImage是C的结构,而Mat是C++的类。如果用户混合使用,可能会有问题,但在这个问题中,用户明确要求使用IplImage,所以应该没问题。 总之,步骤应该是:包含头文件,创建或加载图像,使用对应的cv函数绘制各个图形,显示或保存图像,最后释放资源。每个图形对应的函数和参数需要准确无误,颜色格式和坐标系统正确。同时,注意编译环境和OpenCV版本的兼容性,确保使用的函数未被弃用。</think>在OpenCV中使用$IplImage$格式进行图形绘制需要调用C接口函数,以下是基于C++环境的具体实现方法: ### 一、基础配置 1. 包含头文件: ```cpp #include <opencv2/core/core_c.h> #include <opencv2/imgproc/imgproc_c.h> ``` 2. 创建图像: ```cpp IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); // 创建3通道彩色图像[^1] ``` ### 二、图形绘制方法 #### 1. 绘制点 ```cpp cvSet2D(img, y, x, CvScalar(B, G, R)); // 直接设置像素值 // 或使用线宽为1的线段模拟点 cvLine(img, cvPoint(x,y), cvPoint(x,y), CV_RGB(R,G,B), 1); ``` #### 2. 绘制直线 ```cpp cvLine(img, cvPoint(x1, y1), // 起点 cvPoint(x2, y2), // 终点 CV_RGB(255,0,0), // BGR颜色 2); // 线宽 ``` #### 3. 绘制矩形 ```cpp cvRectangle(img, cvPoint(x1,y1), // 左上角 cvPoint(x2,y2), // 右下角 CV_RGB(0,255,0), 1, // 线宽(负数表示填充) CV_AA); // 抗锯齿模式 ``` #### 4. 绘制 ```cpp cvCircle(img, cvPoint(center_x, center_y), // 心 radius, // 半径 CV_RGB(0,0,255), 2, CV_AA); ``` #### 5. 绘制椭圆 ```cpp cvEllipse(img, cvPoint(center_x, center_y), // 中心点 cvSize(ax, by), // 长/短轴 angle, // 旋转角度 0, 360, // 起始/结束角度 CV_RGB(255,255,0), 2); ``` #### 6. 绘制多边形 ```cpp CvPoint points[] = {{x1,y1}, {x2,y2}, {x3,y3}}; int npts = sizeof(points)/sizeof(CvPoint); cvPolyLine(img, &points, // 顶点数组 &npts, // 顶点数量 1, // 是否闭合 true, // 是否逐个连接 CV_RGB(128,0,128), 2); ``` ### 三、显示与保存 ```cpp cvShowImage("Result", img); cvSaveImage("output.jpg", img); cvReleaseImage(&img); // 释放内存[^2] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值