circle()
是 OpenCV 中用于在图像上绘制圆形的基本函数。它的原型如下所示:
void circle(
InputOutputArray img,
Point center,
int radius,
const Scalar& color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
);
其中,img表示图像,center表示圆心坐标(x,y),radius表示圆的半径(int型),Scalar表示圆的颜色(BGR格式),thickness表示线条的粗细(默认为1),如果thickness=-1表示填充整个圆,lineType表示线条类型(默认LINE_8),shift表示圆心和半径的小数位数(默认为0)。
下面利用该函数绘制奥运五环图标。
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat image(300, 450, CV_8UC3, Scalar(255, 255, 255));
int x = 100;
int y = 125;
Point center(x, y);//圆心
int radius = 50;//半径
Scalar color(200, 130, 0); //蓝色
circle(image, center, radius, color, 5);//1号圆
center.x += 120;
color = Scalar(0,0,0);//黑色
circle(image, center, radius, color, 5);//2号圆
center.x += 120;
color = Scalar(78, 52, 238);//红色
circle(image, center, radius, color, 5);//3号圆
center.x = x + 60;
center.y = y + 50;
color = Scalar(50, 177, 252);//黄色
circle(image, center, radius, color, 5);//4号圆
center.x += 120;
color = Scalar(81, 167, 0);//绿色
circle(image, center, radius, color, 5);//5号圆
radius = 5;
color = Scalar(0, 0, 255);//纯红色
center.x = image.cols / 2 - radius;
center.y = image.rows / 2 - radius;
circle(image, center, radius, color, -1,LINE_AA);//实心圆
imshow("image", image);//显示图像
imwrite("output.jpg", image);
waitKey(0);//等待按键
return 0;
}
先看一下这段代码的最终效果图。

在图中一共有6个圆,从代码的注释中可得知,前5个圆都是空心圆,最后一个圆是实心圆,因为它的thickness参数等于-1。
第二个关键点,实心圆比较圆滑(抗锯齿),而5个空心圆有很明显的锯齿感。这是因为实心圆的lineType参数采用了LINE_AA枚举值。对于高分辨率的图像,使用LINE_AA
可以获得更好的视觉效果。
如果需要绘制大量的圆,可以考虑使用UMat
代替Mat
,利用GPU加速;另外批量绘制时,先准备所有参数,再一次性绘制。
UMat类介绍
UMat可自动利用CPU/GPU异构计算资源(通过OpenCL加速),适合大规模图像处理。针对本例,可以将图像创建成UMat。
UMat image(300, 450, CV_8UC3, Scalar(255, 255, 255));
Mat和UMat转换
两者可以实现互相转换,实现方式也比较简单。如下面的代码所示。
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
// 1. 创建UMat(默认使用OpenCL加速)
UMat uimage1(480, 640, CV_8UC3, Scalar(0, 0, 255)); // 红色背景
// 2. 从Mat转换到UMat
Mat matImage = imread("input.jpg");
UMat uimage2;
matImage.copyTo(uimage2); // 显式转换
// 3. UMat转回Mat
Mat outputMat;
uimage2.copyTo(outputMat);
imshow("UMat Demo", outputMat);
waitKey(0);
return 0;
}
那什么时候用Mat,什么时候用UMat呢?
如果需要处理1MP(即1000*1000=百万像素)以上的图像,且有独立GPU,可以使用UMat+OpenCL。
为什么用1MP作为性能分界?这是因为,对于CPU来说,超过1MP的图像,CPU单线程处理可能开始出现明显延迟(如高斯模糊>10ms)。对于内存来说,1MP的RGB图像约占用3MB内存(1000×1000×3字节),超过L3缓存容量,内存带宽成为瓶颈。
——重庆教主 2025年5月16日
若文章对您有帮助,可以激励一下我哦,祝您平安幸福!
微信 | 支付宝 |
---|---|
![]() |
![]() |