OpenCV基础(6)使用OpenCV注释图像

注释图像和视频有多种用途,OpenCV使这个过程简单明了。看看如何使用它:

  • 向演示添加信息
  • 在物体周围绘制边框,以便检测物体
  • 用不同颜色高亮像素进行图像分割

一旦你学会了注释图像,注释视频帧看起来也很简单。这是因为视频中的每一帧都表示为一幅图像。我们将在这里演示如何用几何形状和文本注释图像。

这是我们将在所有例子中用到的图像。
在这里插入图片描述

1.简单实现画线

首先,快速查看一下注释图像的代码。我们将详细讨论代码中的每一行,以便您能够完全理解它。
(1)Python

# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 在图像上画线
imageLine = img.copy()
# 在图像上绘制从A点到B点
pointA = (200,80)
pointB = (450,80)
cv2.line(imageLine, pointA, pointB, (255, 255, 0), thickness=3, lineType=cv2.LINE_AA)
cv2.imshow('Image Line', imageLine)
cv2.waitKey(0)

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 在图像上画线
    Mat imageLine = img.clone();
    Point pointA(200,80);
    Point pointB(450,80);
    line(imageLine, pointA, pointB, Scalar(255, 255, 0), 3, 8, 0);
    imshow("Lined Image", imageLine);
    waitKey();
}

在这里插入图片描述

2.代码解析

在第一个例子中,让我们使用OpenCV中的line()函数为图像添加一条彩色线。在调用line()函数之前,通过以下方法创建原始图像的副本:

  • Python中copy()函数
  • C++中clone()函数

副本将确保您对图像所做的任何更改不会影响原始图像。在c++中,首先为原始图像的副本创建一个矩阵。

下面是line()函数的语法:line(image, start_point, end_point, color, thickness)

  • 第一个参数是图像
  • 接下来的两个参数是线段的起点和终点。

从点A (x1, y1)到点B(x2, y2)画一条直线,其中AB代表图像中的任意两点。看图像的左上角,你会发现这里是xy坐标系的原点。

  • x轴表示图像的水平方向或列。
  • y轴表示图像的垂直方向或行。

如代码所示:

  • 指定起始点和结束点,以便在图像上水平绘制一条250像素长的直线。
  • 指定它的颜色为蓝色和绿色的混合物,线宽指定为3。

3.画圆

接下来,让我们使用OpenCV中的circle()函数为图像添加一个圆圈注释。看看它的语法:circle(image, center_coordinates, radius, color, thickness)

  • 与OpenCV中的所有绘图函数一样,第一个参数是图像。
  • 接下来的两个参数定义圆心的坐标及其半径。
  • 最后两个参数指定线条的颜色和粗细。

在这个例子中,您用一个红色的圆圈围绕着狗的脸来注释图像。然后使用imshow()函数显示带注释的图像。
(1)Python

# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 复制图像
imageCircle = img.copy()
# 定义圆心
circle_center = (415,190)
# 定义圆的半径
radius =100
#  使用circle()函数绘制一个圆
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA) 
# 显示结果
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 复制图像
	imageCircle = img.copy()
	// 定义圆的中心
	circle_center = (415,190)
	// 定义圆的半径
	radius =100
	//  使用circle()函数绘制一个圆
	cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA) 
	// 显示结果
	cv2.imshow("Image Circle",imageCircle)
	cv2.waitKey(0)
}

在这里插入图片描述

4.画填充的圆

您刚刚完成了用红色圆圈对图像的注释。如果你想用纯色填充这个圆呢?这很简单。只需将线宽参数更改为-1,如下面的代码所示。
(1)Python

# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 复制图像
imageCircle = img.copy()
# 定义圆心
circle_center = (415,190)
# 定义圆的半径
radius =100
#  使用circle()函数绘制一个圆
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=-1, lineType=cv2.LINE_AA) 
# 显示结果
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 复制图像
	imageCircle = img.copy()
	// 定义圆的中心
	circle_center = (415,190)
	// 定义圆的半径
	radius =100
	//  使用circle()函数绘制一个圆
	cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=-1, lineType=cv2.LINE_AA) 
	// 显示结果
	cv2.imshow("Image Circle",imageCircle)
	cv2.waitKey(0)
}

在这里插入图片描述

5.画矩形

现在,您将使用OpenCV中的rectangle()函数在图像上绘制一个矩形。看看它的语法:rectangle(image, start_point, end_point, color, thickness)

rectangle()函数中,为矩形的各个角提供起始点(左上)和结束点(右下)。
现在浏览一下这个示例代码,并在小狗的脸上用一个红色矩形注释这个图像。
(1)Python

# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 复制图像
imageRectangle = img.copy()
# 定义矩形的起点和终点
start_point =(300,115)
end_point =(475,225)
# 画矩形
cv2.rectangle(imageRectangle, start_point, end_point, (0, 0, 255), thickness= 3, lineType=cv2.LINE_8) 
# 输出显示
cv2.imshow('imageRectangle', imageRectangle)
cv2.waitKey(0)

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 复制图像
    Mat rect_image = image.clone();
    // 定义矩形的起始点和结束点
    Point start_point(300,115);
    Point end_point(475,225);
    // 使用 rectangle() 函数绘制一个矩形
    rectangle(rect_image, start_point, end_point, Scalar(0,0,255), 3, 8, 0);
    imshow("Rectangle on Image", rect_image);
    waitKey();
}

在这里插入图片描述

6.画椭圆

ellipse(image, centerCoordinates, axesLength, angle, startAngle, endAngle, color, thickness)
你可以使用OpenCV中的ellipse()函数在图像上画一个椭圆。ellipse()函数的语法与circle非常相似。除了,你需要指定的不是半径,而是:

  • 椭圆的长和短轴长度
  • 旋转角度
  • 椭圆的起始和结束角,这些角度让我们只绘制弧线的一部分

在下面的示例代码中,您可以使用:

  • 水平蓝色椭圆
  • 垂直的红色椭圆

正如您再次看到的,OpenCV中的绘图函数非常相似,因此很容易掌握。此外,它们还提供可选参数,以便您可以自由定义许多基本几何形状的位置和方向。
(1)Python

# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 复制图像
imageEllipse = img.copy()
# 定义椭圆的中心点
ellipse_center = (415,190)
# 定义椭圆的长轴和短轴
axis1 = (100,50)
axis2 = (125,50)
# 绘制椭圆
#水平
cv2.ellipse(imageEllipse, ellipse_center, axis1, 0, 0, 360, (255, 0, 0), thickness=3)
#垂直
cv2.ellipse(imageEllipse, ellipse_center, axis2, 90, 0, 360, (0, 0, 255), thickness=3)
# 显示输出
cv2.imshow('ellipse Image',imageEllipse)
cv2.waitKey(0)

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 复制图像
   Mat imageEllipse = img.clone();
   // 定义椭圆的中心点
   Point ellipse_center(415,190);
   // 定义椭圆的长轴和短轴
   Point axis1(100, 50);
   Point axis2(125, 50);
   // 使用ellipse()函数绘制一个椭圆
   // 水平
   ellipse(imageEllipse, ellipse_center, axis1, 0, 0, 360, Scalar(255, 0, 0), 3, 8, 0);
   // 垂直
   ellipse(imageEllipse, ellipse_center, axis2, 90, 0, 360, Scalar(0, 0, 255), 3, 8, 0);
   // 显示输出
   imshow("Ellipses on Image", imageEllipse);
   waitKey();
}

在这里插入图片描述

7.绘制半椭圆

在这个例子中,我们将前面的代码修改为:

  • 只画蓝色椭圆的一半
  • 将垂直的红色椭圆改为半填充的水平红色椭圆

要做到这一点,请进行以下更改:

  • 设置蓝色椭圆的结束角为180度
  • 改变红色椭圆的方向从90到0
  • 指定红色椭圆的起始角和结束角,分别为0和180
  • 将红色椭圆的厚度指定为负数
    (1)Python
# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 复制图像
halfEllipse = img.copy()
# 定义半椭圆的中心
ellipse_center = (415,190)
# 定义轴点
axis1 = (100,50)
# 画一个不完整/开放的椭圆,只是一个轮廓
cv2.ellipse(halfEllipse, ellipse_center, axis1, 0, 180, 360, (255, 0, 0), thickness=3)
# 如果您想绘制一个填充椭圆,请使用这行代码
# cv2.ellipse(halfEllipse, ellipse_center, axis1, 0, 0, 180, (0, 0, 255), thickness=-2)
# 输出显示
cv2.imshow('halfEllipse',halfEllipse)
cv2.waitKey(0)

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 复制图像
   Mat halfEllipse = image.clone();
   // 定义半椭圆的中心
   Point ellipse_center(415,190);
   // 定义轴点
   Point axis1(100, 50);
   // 画半椭圆,只画轮廓
   ellipse(halfEllipse, ellipse_center, axis1, 0, 180, 360, Scalar(255, 0, 0), 3, 8, 0);
   // 如果您想绘制一个填充椭圆,请使用这行代码
   // ellipse(halfEllipse, ellipse_center, axis1, 0, 0, 180, Scalar(0, 0, 255), -2, 8, 0);
   // 输出显示
   imshow("Half-Ellipses on Image", halfEllipse);
   waitKey();
}

在这里插入图片描述

8.添加文字

最后,让我们尝试用文本注释图像。要做到这一点,请使用OpenCV中的putText()函数。看看它的语法,后面跟着参数:putText(image, text, org, font, fontScale, color)

  • 和往常一样,第一个参数是输入图像。
  • 下一个参数是我们想要注释图像的实际文本字符串。
  • 第三个参数指定文本字符串左上角的起始位置。
  • 接下来的两个参数指定字体样式和比例。OpenCV支持来自Hershey字体集合的几种字体样式,以及斜体字体。看看这个列表:
    • FONT_HERSHEY_SIMPLEX = 0,
    • FONT_HERSHEY_PLAIN = 1,
    • FONT_HERSHEY_DUPLEX = 2,
    • FONT_HERSHEY_COMPLEX = 3,
    • FONT_HERSHEY_TRIPLEX = 4,
    • FONT_HERSHEY_COMPLEX_SMALL = 5,
    • FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
    • FONT_HERSHEY_SCRIPT_COMPLEX = 7,
    • FONT_ITALIC = 16
  • 字体比例是一个浮点值,用于向上或向下缩放字体的基本大小。根据图像的分辨率,选择合适的字体比例。
  • 最后一个必需参数是颜色,它被指定为BGR三元组。

看一下这段代码,了解如何实现这些参数来在图像上显示文本字符串。
(1)Python

# 导入依赖
import cv2
# 读取图像
img = cv2.imread('sample.jpg')
# 显示图像
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# 打印错误信息
if img is None:
    print('Could not read image')
# 复制图像
imageText = img.copy()
#让我们写下你想要放在图像上的文本
text = 'I am a Happy dog!'
#你想放文本的地方
org = (50,350)
# 将文本写在输入图像上
cv2.putText(imageText, text, org, fontFace = cv2.FONT_HERSHEY_COMPLEX, fontScale = 1.5, color = (250,225,100))
# 显示带有文本的输出图像
cv2.imshow("Image Text",imageText)
cv2.waitKey(0)
cv2.destroyAllWindows()

(2)C++

// 导入依赖
#include <opencv2/opencv.hpp>
#include <iostream>
// 命名空间
using namespace std;
using namespace cv;
int main()
{
    // 读取图像
    Mat img = imread("sample.jpg");
    // 显示图像
    imshow("Original Image", img);
    waitKey();
    // 打印错误信息
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // 复制图像
   Mat imageText = img.clone();
   // 使用 putText() 函数写入文本
   putText(imageText, "I am a Happy dog!", Point(50,350), FONT_HERSHEY_COMPLEX, 1.5, Scalar(250,225,100));
   imshow("Text on Image", imageText);
   waitKey(0);
}

在这里插入图片描述

总结

用几何形状和文本注释图像是一种强大的交流方式。它有助于放大图像上的信息。在图像经过各种计算机视觉算法处理后(例如,在物体检测模型检测到的物体周围绘制边界框),图像几乎总是被注释以覆盖结果。

您已经看到用几何形状和文本注释图像是多么容易。甚至绘图函数也有类似的输入参数。只是指定注释的位置和大小的方式可能略有不同。

你还学会了用想要的颜色填充形状。绘制特定方向和长度的椭圆和弧。

最后,您看到了如何用文本注释图像。

参考目录

https://learnopencv.com/annotating-images-using-opencv/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值